From a4f94366a42b42f7a94cb727764d38ca7580913c Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 20 Oct 2017 14:56:29 -0700 Subject: [PATCH 1/6] Added static memory code to client example. --- examples/client/client.c | 95 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index b5279250c..b57cc7734 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -762,12 +762,22 @@ static void Usage(void) #endif } +#ifdef WOLFSSL_STATIC_MEMORY + #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ + || defined(SESSION_CERTS) + /* big enough to handle most cases including session certs */ + byte memory[204000]; + #else + byte memory[80000]; + #endif + byte memoryIO[34500]; /* max of 17k for IO buffer (TLS packet can be 16k) */ +#endif THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; - WOLFSSL_METHOD* method = 0; + wolfSSL_method_func method = NULL; WOLFSSL_CTX* ctx = 0; WOLFSSL* ssl = 0; @@ -1372,17 +1382,17 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef NO_OLD_TLS #ifdef WOLFSSL_ALLOW_SSLV3 case 0: - method = wolfSSLv3_client_method(); + method = wolfSSLv3_client_method_ex; break; #endif #ifndef NO_TLS case 1: - method = wolfTLSv1_client_method(); + method = wolfTLSv1_client_method_ex; break; case 2: - method = wolfTLSv1_1_client_method(); + method = wolfTLSv1_1_client_method_ex; break; #endif /* NO_TLS */ @@ -1390,11 +1400,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef NO_TLS case 3: - method = wolfTLSv1_2_client_method(); + method = wolfTLSv1_2_client_method_ex; break; #ifdef WOLFSSL_TLS13 case 4: - method = wolfTLSv1_3_client_method(); + method = wolfTLSv1_3_client_method_ex; break; #endif #endif @@ -1402,12 +1412,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_DTLS #ifndef NO_OLD_TLS case -1: - method = wolfDTLSv1_client_method(); + method = wolfDTLSv1_client_method_ex; break; #endif case -2: - method = wolfDTLSv1_2_client_method(); + method = wolfDTLSv1_2_client_method_ex; break; #endif @@ -1419,7 +1429,32 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (method == NULL) err_sys("unable to get method"); - ctx = wolfSSL_CTX_new(method); + +#ifdef WOLFSSL_STATIC_MEMORY + #ifdef DEBUG_WOLFSSL + /* print off helper buffer sizes for use with static memory + * printing to stderr incase of debug mode turned on */ + fprintf(stderr, "static memory management size = %d\n", + wolfSSL_MemoryPaddingSz()); + fprintf(stderr, "calculated optimum general buffer size = %d\n", + wolfSSL_StaticBufferSz(memory, sizeof(memory), 0)); + fprintf(stderr, "calculated optimum IO buffer size = %d\n", + wolfSSL_StaticBufferSz(memoryIO, sizeof(memoryIO), + WOLFMEM_IO_POOL_FIXED)); + #endif /* DEBUG_WOLFSSL */ + + if (wolfSSL_CTX_load_static_memory(&ctx, method, memory, sizeof(memory), + 0, 1) != WOLFSSL_SUCCESS) { + err_sys("unable to load static memory"); + } + + if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO), + WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1) != WOLFSSL_SUCCESS) { + err_sys("unable to load static memory"); + } +#else + ctx = wolfSSL_CTX_new(method(NULL)); +#endif if (ctx == NULL) err_sys("unable to get ctx"); @@ -1708,6 +1743,17 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_CTX_allow_post_handshake_auth(ctx); #endif +#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) + { + WOLFSSL_MEM_STATS mem_stats; + fprintf(stderr, "Before creating SSL\n"); + if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) + err_sys("ctx not using static memory"); + if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ + err_sys("error printing out memory stats"); + } +#endif + if (doMcast) { #ifdef WOLFSSL_MULTICAST wolfSSL_CTX_mcast_set_member_id(ctx, mcastID); @@ -1729,6 +1775,17 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_KeepArrays(ssl); #endif +#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) + { + WOLFSSL_MEM_STATS mem_stats; + fprintf(stderr, "After creating SSL\n"); + if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) + err_sys("ctx not using static memory"); + if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ + err_sys("error printing out memory stats"); + } +#endif + #ifdef WOLFSSL_TLS13 if (!helloRetry) { if (onlyKeyShare == 0 || onlyKeyShare == 2) { @@ -2088,6 +2145,26 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (atomicUser) FreeAtomicUser(ssl); #endif + + + /* display collected statistics */ +#ifdef WOLFSSL_STATIC_MEMORY + { + WOLFSSL_MEM_CONN_STATS ssl_stats; + if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1) + err_sys("static memory was not used with ssl"); + + fprintf(stderr, "\nprint off SSL memory stats\n"); + fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n"); + fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem); + fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem); + fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc); + fprintf(stderr, "current connection allocs = %d\n", ssl_stats.curAlloc); + fprintf(stderr, "total connection allocs = %d\n", ssl_stats.totalAlloc); + fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr); + } +#endif + wolfSSL_free(ssl); CloseSocket(sockfd); From 6369794b6f9ea49f9042668fcfff12c2200034da Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 23 Oct 2017 10:50:19 -0700 Subject: [PATCH 2/6] Fixes for static memory with `-r` session resumption option on client. Fix for possible failed InitSSL cleanup using NULL ssl->ctx for static memory. --- examples/client/client.c | 64 +++++++++++++++++++++++----------------- examples/server/server.c | 11 +++---- scripts/resume.test | 2 +- src/internal.c | 4 +-- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index b57cc7734..13eaaf1e9 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -762,17 +762,6 @@ static void Usage(void) #endif } -#ifdef WOLFSSL_STATIC_MEMORY - #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ - || defined(SESSION_CERTS) - /* big enough to handle most cases including session certs */ - byte memory[204000]; - #else - byte memory[80000]; - #endif - byte memoryIO[34500]; /* max of 17k for IO buffer (TLS packet can be 16k) */ -#endif - THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; @@ -895,6 +884,22 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; + +#ifdef WOLFSSL_STATIC_MEMORY + #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ + || defined(SESSION_CERTS) + /* big enough to handle most cases including session certs */ + byte memory[204000]; + #else + byte memory[80000]; + #endif + byte memoryIO[34500]; /* max for IO buffer (TLS packet can be 16k) */ + WOLFSSL_MEM_CONN_STATS ssl_stats; + #ifdef DEBUG_WOLFSSL + WOLFSSL_MEM_STATS mem_stats; + #endif +#endif + ((func_args*)args)->return_code = -1; /* error state */ #ifdef NO_RSA @@ -1744,14 +1749,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) - { - WOLFSSL_MEM_STATS mem_stats; fprintf(stderr, "Before creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) err_sys("ctx not using static memory"); if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ err_sys("error printing out memory stats"); - } #endif if (doMcast) { @@ -1776,14 +1778,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) - { - WOLFSSL_MEM_STATS mem_stats; fprintf(stderr, "After creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) err_sys("ctx not using static memory"); if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ err_sys("error printing out memory stats"); - } #endif #ifdef WOLFSSL_TLS13 @@ -2127,12 +2126,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef NO_SESSION_CACHE if (resumeSession) { session = wolfSSL_get_session(ssl); - sslResume = wolfSSL_new(ctx); - if (sslResume == NULL) { - wolfSSL_free(ssl); - wolfSSL_CTX_free(ctx); - err_sys("unable to get SSL object"); - } } #endif @@ -2146,11 +2139,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) FreeAtomicUser(ssl); #endif - /* display collected statistics */ #ifdef WOLFSSL_STATIC_MEMORY - { - WOLFSSL_MEM_CONN_STATS ssl_stats; if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1) err_sys("static memory was not used with ssl"); @@ -2162,7 +2152,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) fprintf(stderr, "current connection allocs = %d\n", ssl_stats.curAlloc); fprintf(stderr, "total connection allocs = %d\n", ssl_stats.totalAlloc); fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr); - } #endif wolfSSL_free(ssl); @@ -2170,6 +2159,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifndef NO_SESSION_CACHE if (resumeSession) { + sslResume = wolfSSL_new(ctx); + if (sslResume == NULL) { + wolfSSL_CTX_free(ctx); + err_sys("unable to get SSL object"); + } + if (dtlsUDP) { #ifdef USE_WINDOWS_API Sleep(500); @@ -2459,6 +2454,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) wolfSSL_shutdown(sslResume); /* bidirectional shutdown */ + /* display collected statistics */ + #ifdef WOLFSSL_STATIC_MEMORY + if (wolfSSL_is_static_memory(sslResume, &ssl_stats) != 1) + err_sys("static memory was not used with ssl"); + + fprintf(stderr, "\nprint off SSLresume memory stats\n"); + fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n"); + fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem); + fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem); + fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc); + fprintf(stderr, "current connection allocs = %d\n", ssl_stats.curAlloc); + fprintf(stderr, "total connection allocs = %d\n", ssl_stats.totalAlloc); + fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr); + #endif + wolfSSL_free(sslResume); CloseSocket(sockfd); } diff --git a/examples/server/server.c b/examples/server/server.c index eb976fc59..08c0cf000 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -534,8 +534,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #else byte memory[80000]; #endif - byte memoryIO[34500]; /* max of 17k for IO buffer (TLS packet can be 16k) */ + byte memoryIO[34500]; /* max for IO buffer (TLS packet can be 16k) */ WOLFSSL_MEM_CONN_STATS ssl_stats; + #ifdef DEBUG_WOLFSSL + WOLFSSL_MEM_STATS mem_stats; + #endif #endif ((func_args*)args)->return_code = -1; /* error state */ @@ -1153,14 +1156,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } } #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) - { - WOLFSSL_MEM_STATS mem_stats; fprintf(stderr, "Before creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) err_sys_ex(runWithErrors, "ctx not using static memory"); if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ err_sys_ex(runWithErrors, "error printing out memory stats"); - } #endif if (doMcast) { @@ -1185,14 +1185,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) - { - WOLFSSL_MEM_STATS mem_stats; fprintf(stderr, "After creating SSL\n"); if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) err_sys_ex(runWithErrors, "ctx not using static memory"); if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ err_sys_ex(runWithErrors, "error printing out memory stats"); - } #endif if (doMcast) { diff --git a/scripts/resume.test b/scripts/resume.test index 6b6ad488e..5badb4838 100755 --- a/scripts/resume.test +++ b/scripts/resume.test @@ -71,7 +71,7 @@ do_test() { if [ $client_result != 0 ] then - echo -e "client failed!" + echo -e "client failed!\ncapture_out=$capture_out\nclient_result=$client_result" do_cleanup exit 1 fi diff --git a/src/internal.c b/src/internal.c index d2599d5bb..26fc0fa86 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4864,9 +4864,9 @@ void SSL_ResourceFree(WOLFSSL* ssl) /* check if tracking stats */ if (ctx_heap->flag & WOLFMEM_TRACK_STATS) { - XFREE(ssl_hint->stats, ssl->ctx->heap, DYNAMIC_TYPE_SSL); + XFREE(ssl_hint->stats, ssl->heap, DYNAMIC_TYPE_SSL); } - XFREE(ssl->heap, ssl->ctx->heap, DYNAMIC_TYPE_SSL); + XFREE(ssl->heap, ssl->heap, DYNAMIC_TYPE_SSL); #ifdef WOLFSSL_HEAP_TEST } #endif From 0e34f35c08afcb8ccfb00ae7c63ea9d61803a982 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 26 Oct 2017 08:06:08 -0700 Subject: [PATCH 3/6] Increase the static memory pool in client to better support ECC or session certs. --- examples/client/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/client/client.c b/examples/client/client.c index 13eaaf1e9..e6a32d45a 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -889,7 +889,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ || defined(SESSION_CERTS) /* big enough to handle most cases including session certs */ - byte memory[204000]; + byte memory[320000]; #else byte memory[80000]; #endif From 72f44aba87b7e98eb418f4813b3f6f1b92a6a96e Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 26 Oct 2017 15:52:51 -0700 Subject: [PATCH 4/6] Fix for X509 FreeAltNames with static memory enabled. --- src/internal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 26fc0fa86..a67810fc3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2833,7 +2833,7 @@ void FreeX509(WOLFSSL_X509* x509) } #endif /* OPENSSL_EXTRA */ if (x509->altNames) - FreeAltNames(x509->altNames, NULL); + FreeAltNames(x509->altNames, x509->heap); } #endif /* !NO_DH || HAVE_ECC */ From 229cecfb610c93934a51fc65c6bb4a5a2aad5444 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 30 Oct 2017 09:49:08 -0700 Subject: [PATCH 5/6] Fix static memory failure case (insuficient mem) in InitSSL case where `ssl->ctx` isn't set yet and `SSL_ResourceFree` is called NULL dereferece happens. --- src/internal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index a67810fc3..22067077a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4864,9 +4864,10 @@ void SSL_ResourceFree(WOLFSSL* ssl) /* check if tracking stats */ if (ctx_heap->flag & WOLFMEM_TRACK_STATS) { - XFREE(ssl_hint->stats, ssl->heap, DYNAMIC_TYPE_SSL); + XFREE(ssl_hint->stats, ssl->ctx ? ssl->ctx->heap : NULL, + DYNAMIC_TYPE_SSL); } - XFREE(ssl->heap, ssl->heap, DYNAMIC_TYPE_SSL); + XFREE(ssl->heap, ssl->ctx ? ssl->ctx->heap : NULL, DYNAMIC_TYPE_SSL); #ifdef WOLFSSL_HEAP_TEST } #endif From 4084255fd5dba8778f8a235a2278f577193975ff Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 2 Nov 2017 09:48:12 -0700 Subject: [PATCH 6/6] Improve SSL failure cleanup case where ssl->ctx isn't set yet. --- src/internal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index 22067077a..ae569af45 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4845,6 +4845,7 @@ void SSL_ResourceFree(WOLFSSL* ssl) #endif WOLFSSL_HEAP_HINT* ssl_hint = (WOLFSSL_HEAP_HINT*)ssl->heap; WOLFSSL_HEAP* ctx_heap; + void* heap = ssl->ctx ? ssl->ctx->heap : ssl->heap; ctx_heap = ssl_hint->memory; if (wc_LockMutex(&(ctx_heap->memory_mutex)) != 0) { @@ -4864,10 +4865,9 @@ void SSL_ResourceFree(WOLFSSL* ssl) /* check if tracking stats */ if (ctx_heap->flag & WOLFMEM_TRACK_STATS) { - XFREE(ssl_hint->stats, ssl->ctx ? ssl->ctx->heap : NULL, - DYNAMIC_TYPE_SSL); + XFREE(ssl_hint->stats, heap, DYNAMIC_TYPE_SSL); } - XFREE(ssl->heap, ssl->ctx ? ssl->ctx->heap : NULL, DYNAMIC_TYPE_SSL); + XFREE(ssl->heap, heap, DYNAMIC_TYPE_SSL); #ifdef WOLFSSL_HEAP_TEST } #endif