diff --git a/src/internal.c b/src/internal.c index da01dac15..9349f48c9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4388,24 +4388,28 @@ static void SetDigest(WOLFSSL* ssl, int hashAlgo) switch (hashAlgo) { #ifndef NO_SHA case sha_mac: + ssl->options.dontFreeDigest = 1; ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; ssl->buffers.digest.length = WC_SHA_DIGEST_SIZE; break; #endif /* !NO_SHA */ #ifndef NO_SHA256 case sha256_mac: + ssl->options.dontFreeDigest = 1; ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256; ssl->buffers.digest.length = WC_SHA256_DIGEST_SIZE; break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA384 case sha384_mac: + ssl->options.dontFreeDigest = 1; ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384; ssl->buffers.digest.length = WC_SHA384_DIGEST_SIZE; break; #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 case sha512_mac: + ssl->options.dontFreeDigest = 1; ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512; ssl->buffers.digest.length = WC_SHA512_DIGEST_SIZE; break; @@ -7544,9 +7548,13 @@ void FreeKeyExchange(WOLFSSL* ssl) /* Cleanup digest buffer */ if (ssl->buffers.digest.buffer) { - XFREE(ssl->buffers.digest.buffer, ssl->heap, DYNAMIC_TYPE_DIGEST); + /* Only free if digest buffer was not set using SetDigest */ + if (!ssl->options.dontFreeDigest) { + XFREE(ssl->buffers.digest.buffer, ssl->heap, DYNAMIC_TYPE_DIGEST); + } ssl->buffers.digest.buffer = NULL; ssl->buffers.digest.length = 0; + ssl->options.dontFreeDigest = 0; } /* Free handshake key */ @@ -26225,6 +26233,14 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, ssl->buffers.digest.length = (unsigned int)digest_sz; /* buffer for hash */ + if (!ssl->buffers.digest.buffer) { + if (!ssl->options.dontFreeDigest) { + XFREE(ssl->buffers.digest.buffer, ssl->heap, + DYNAMIC_TYPE_DIGEST); + } + } + ssl->options.dontFreeDigest = 0; + ssl->buffers.digest.buffer = (byte*)XMALLOC(ssl->buffers.digest.length, ssl->heap, DYNAMIC_TYPE_DIGEST); if (ssl->buffers.digest.buffer == NULL) { @@ -30476,8 +30492,16 @@ exit_scv: #endif /* WOLFSSL_ASYNC_IO */ /* Digest is not allocated, so do this to prevent free */ + if(ssl->buffers.digest.buffer) { + if (!ssl->options.dontFreeDigest) { + /*This should not happen*/ + XFREE(ssl->buffers.digest.buffer, + ssl->heap, DYNAMIC_TYPE_DIGEST); + } + } ssl->buffers.digest.buffer = NULL; ssl->buffers.digest.length = 0; + ssl->options.dontFreeDigest = 0; /* Final cleanup */ #ifdef WOLFSSL_ASYNC_IO @@ -31960,8 +31984,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, TypeHash(ssl->options.hashAlgo)); /* Replace sig buffer with new one */ - XFREE(ssl->buffers.digest.buffer, ssl->heap, - DYNAMIC_TYPE_DIGEST); + if (!ssl->options.dontFreeDigest) { + XFREE(ssl->buffers.digest.buffer, + ssl->heap, DYNAMIC_TYPE_DIGEST); + } + ssl->options.dontFreeDigest = 0; ssl->buffers.digest.buffer = encodedSig; } @@ -32178,8 +32205,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, TypeHash(ssl->options.hashAlgo)); /* Replace sig buffer with new one */ - XFREE(ssl->buffers.digest.buffer, ssl->heap, - DYNAMIC_TYPE_DIGEST); + if (!ssl->options.dontFreeDigest) { + XFREE(ssl->buffers.digest.buffer, + ssl->heap, DYNAMIC_TYPE_DIGEST); + } + ssl->options.dontFreeDigest = 0; ssl->buffers.digest.buffer = encodedSig; } break; @@ -34268,8 +34298,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, SendAlert(ssl, alert_fatal, bad_certificate); #endif /* Digest is not allocated, so do this to prevent free */ + if(ssl->buffers.digest.buffer) { + if (!ssl->options.dontFreeDigest) { + /*This should not happen*/ + XFREE(ssl->buffers.digest.buffer, + ssl->heap, DYNAMIC_TYPE_DIGEST); + } + } ssl->buffers.digest.buffer = NULL; ssl->buffers.digest.length = 0; + ssl->options.dontFreeDigest = 0; #ifdef WOLFSSL_ASYNC_CRYPT /* Cleanup async */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 442588712..cb45d54f9 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4414,6 +4414,7 @@ struct Options { word16 saveArrays:1; /* save array Memory for user get keys or psk */ word16 weOwnRng:1; /* will be true unless CTX owns */ + word16 dontFreeDigest:1; /* when true, we used SetDigest */ word16 haveEMS:1; /* using extended master secret */ #ifdef HAVE_POLY1305 word16 oldPoly:1; /* set when to use old rfc way of poly*/