From e6d9151f47aa25cd517cfe4192d490f529dfd3f4 Mon Sep 17 00:00:00 2001 From: toddouska Date: Fri, 20 Jun 2014 10:49:21 -0700 Subject: [PATCH] add user cert chain functionality at SSL level instead of just CTX --- cyassl/internal.h | 3 ++- src/internal.c | 10 ++++++---- src/ssl.c | 47 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/cyassl/internal.h b/cyassl/internal.h index 59329a75e..7a00be9e5 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1631,7 +1631,7 @@ typedef struct Buffers { #ifndef NO_CERTS buffer certificate; /* CYASSL_CTX owns, unless we own */ buffer key; /* CYASSL_CTX owns, unless we own */ - buffer certChain; /* CYASSL_CTX owns */ + buffer certChain; /* CYASSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ buffer serverDH_P; /* CYASSL_CTX owns, unless we own */ buffer serverDH_G; /* CYASSL_CTX owns, unless we own */ @@ -1647,6 +1647,7 @@ typedef struct Buffers { int plainSz; /* plain text bytes in buffer to send when got WANT_WRITE */ byte weOwnCert; /* SSL own cert flag */ + byte weOwnCertChain; /* SSL own cert chain flag */ byte weOwnKey; /* SSL own key flag */ byte weOwnDH; /* SSL own dh (p,g) flag */ #ifdef CYASSL_DTLS diff --git a/src/internal.c b/src/internal.c index f2565bdb2..dbd57133a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1647,9 +1647,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->buffers.serverDH_G = ctx->serverDH_G; } #endif - ssl->buffers.weOwnCert = 0; - ssl->buffers.weOwnKey = 0; - ssl->buffers.weOwnDH = 0; + ssl->buffers.weOwnCert = 0; + ssl->buffers.weOwnCertChain = 0; + ssl->buffers.weOwnKey = 0; + ssl->buffers.weOwnDH = 0; #ifdef CYASSL_DTLS ssl->buffers.dtlsCtx.fd = -1; @@ -1874,9 +1875,10 @@ void SSL_ResourceFree(CYASSL* ssl) XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH); } - /* CYASSL_CTX always owns certChain */ if (ssl->buffers.weOwnCert) XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT); + if (ssl->buffers.weOwnCertChain) + XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT); if (ssl->buffers.weOwnKey) XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY); #endif diff --git a/src/ssl.c b/src/ssl.c index 494f8c5ac..2ac78e979 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1905,6 +1905,9 @@ int CyaSSL_Init(void) && format != SSL_FILETYPE_RAW) return SSL_BAD_FILETYPE; + if (ctx == NULL && ssl == NULL) + return BAD_FUNC_ARG; + if (type == CA_TYPE) dynamicType = DYNAMIC_TYPE_CA; else if (type == CERT_TYPE) @@ -1924,6 +1927,8 @@ int CyaSSL_Init(void) if (userChain && type == CERT_TYPE && info.consumed < sz) { byte staticBuffer[FILE_BUFFER_SIZE]; /* tmp chain buffer */ byte* chainBuffer = staticBuffer; + byte* shrinked = NULL; /* shrinked to size chainBuffer + * or staticBuffer */ int dynamicBuffer = 0; word32 bufferSz = sizeof(staticBuffer); long consumed = info.consumed; @@ -1986,22 +1991,30 @@ int CyaSSL_Init(void) } CYASSL_MSG("Finished Processing Cert Chain"); - if (ctx == NULL) { - CYASSL_MSG("certChain needs context"); - if (dynamicBuffer) - XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE); - XFREE(der.buffer, heap, dynamicType); - return BAD_FUNC_ARG; - } - ctx->certChain.buffer = (byte*)XMALLOC(idx, heap, - dynamicType); - if (ctx->certChain.buffer) { - ctx->certChain.length = idx; - XMEMCPY(ctx->certChain.buffer, chainBuffer, idx); + /* only retain actual size used */ + shrinked = (byte*)XMALLOC(idx, heap, dynamicType); + if (shrinked) { + if (ssl) { + if (ssl->buffers.certChain.buffer && + ssl->buffers.weOwnCertChain) { + XFREE(ssl->buffers.certChain.buffer, heap, + dynamicType); + } + ssl->buffers.certChain.buffer = shrinked; + ssl->buffers.certChain.length = idx; + XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer,idx); + ssl->buffers.weOwnCertChain = 1; + } else if (ctx) { + if (ctx->certChain.buffer) + XFREE(ctx->certChain.buffer, heap, dynamicType); + ctx->certChain.buffer = shrinked; + ctx->certChain.length = idx; + XMEMCPY(ctx->certChain.buffer, chainBuffer, idx); + } } if (dynamicBuffer) XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE); - if (ctx->certChain.buffer == NULL) { + if (shrinked == NULL) { XFREE(der.buffer, heap, dynamicType); return MEMORY_E; } @@ -5866,6 +5879,14 @@ int CyaSSL_set_compression(CYASSL* ssl) ssl->buffers.certificate.buffer = NULL; } + if (ssl->buffers.weOwnCertChain) { + CYASSL_MSG("Unloading cert chain"); + XFREE(ssl->buffers.certChain.buffer, ssl->heap,DYNAMIC_TYPE_CERT); + ssl->buffers.weOwnCertChain = 0; + ssl->buffers.certChain.length = 0; + ssl->buffers.certChain.buffer = NULL; + } + if (ssl->buffers.weOwnKey) { CYASSL_MSG("Unloading key"); XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);