diff --git a/examples/client/client.c b/examples/client/client.c index d0fc9fc88..7e492e9ba 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3904,12 +3904,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) 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); + wolfSSL_PrintStatsConn(&ssl_stats); #endif wolfSSL_free(ssl); ssl = NULL; @@ -4123,12 +4118,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) 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); + wolfSSL_PrintStatsConn(&ssl_stats); #endif wolfSSL_free(sslResume); sslResume = NULL; diff --git a/examples/server/server.c b/examples/server/server.c index 0b6ae2afc..a846a36f5 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -1411,10 +1411,20 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif #ifdef WOLFSSL_STATIC_MEMORY + /* Note: Actual memory used is much less, this is the entire buffer buckets, + * which is partitioned into pools of common sizes. To adjust the buckets + * sizes see WOLFMEM_BUCKETS in memory.h */ #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ || defined(SESSION_CERTS) /* big enough to handle most cases including session certs */ - byte memory[239936]; + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) + /* increase is due to EdDSA_Update */ + byte memory[440000]; + #else + byte memory[320000]; + #endif #else byte memory[80000]; #endif @@ -1512,11 +1522,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) /* Reinitialize the global myVerifyAction. */ myVerifyAction = VERIFY_OVERRIDE_ERROR; - /* Not Used: h, z, W, X, 7 */ + /* Not Used: h, z, W, X */ while ((ch = mygetopt_long(argc, argv, "?:" "abc:defgijk:l:mop:q:rstu;v:wxy" "A:B:C:D:E:FGH:IJKL:MNO:PQR:S:T;UVYZ:" - "01:23:4:5689" + "01:23:4:567:89" "@#", long_options, 0)) != -1) { switch (ch) { case '?' : @@ -3203,14 +3213,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) 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); + wolfSSL_PrintStatsConn(&ssl_stats); #endif SSL_free(ssl); ssl = NULL; diff --git a/src/internal.c b/src/internal.c index 6cebc367e..2ff7db3da 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2171,13 +2171,16 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { WOLFSSL_MSG("ctx-x509_store.lookup.dir memory allocation error"); XFREE(ctx->param, heap, DYNAMIC_TYPE_OPENSSL); + ctx->param = NULL; return MEMORY_E; } XMEMSET(ctx->x509_store.lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); if (wc_InitMutex(&ctx->x509_store.lookup.dirs->lock) != 0) { WOLFSSL_MSG("Bad mutex init"); XFREE(ctx->param, heap, DYNAMIC_TYPE_OPENSSL); + ctx->param = NULL; XFREE(ctx->x509_store.lookup.dirs, heap, DYNAMIC_TYPE_OPENSSL); + ctx->x509_store.lookup.dirs = NULL; return BAD_MUTEX_E; } #endif @@ -2249,13 +2252,25 @@ void wolfSSL_CRYPTO_cleanup_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data) } #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */ -/* In case contexts are held in array and don't want to free actual ctx */ +/* In case contexts are held in array and don't want to free actual ctx. */ + +/* The allocations done in InitSSL_Ctx must be free'd with ctx->onHeapHint + * logic. A WOLFSSL_CTX can be assigned a static memory heap hint using + * wolfSSL_CTX_load_static_memory after CTX creation, which means variables + * allocated in InitSSL_Ctx were allocated from heap and should be free'd with + * a NULL heap hint. */ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) { #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && \ defined(HAVE_TLS_EXTENSIONS) && !defined(NO_WOLFSSL_SERVER) int i; #endif + void* heapAtCTXInit = ctx->heap; +#ifdef WOLFSSL_STATIC_MEMORY + if (ctx->onHeapHint == 0) { + heapAtCTXInit = NULL; + } +#endif #ifdef HAVE_EX_DATA_CLEANUP_HOOKS wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data); @@ -2265,17 +2280,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) wolfEventQueue_Free(&ctx->event_queue); #endif /* HAVE_WOLF_EVENT */ -#ifdef WOLFSSL_STATIC_MEMORY - if (ctx->onHeap == 1) { - XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD); - } - else { - XFREE(ctx->method, NULL, DYNAMIC_TYPE_METHOD); - } -#else - XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD); -#endif + XFREE(ctx->method, heapAtCTXInit, DYNAMIC_TYPE_METHOD); ctx->method = NULL; + if (ctx->suites) { XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES); ctx->suites = NULL; @@ -2358,12 +2365,13 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #endif /* HAVE_TLS_EXTENSIONS */ #ifdef OPENSSL_EXTRA - if(ctx->alpn_cli_protos) { - XFREE((void *)ctx->alpn_cli_protos, NULL, DYNAMIC_TYPE_OPENSSL); + if (ctx->alpn_cli_protos) { + XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL); ctx->alpn_cli_protos = NULL; } if (ctx->param) { - XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); + XFREE(ctx->param, heapAtCTXInit, DYNAMIC_TYPE_OPENSSL); + ctx->param = NULL; } if (ctx->x509_store.lookup.dirs) { @@ -2374,7 +2382,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #endif wc_FreeMutex(&ctx->x509_store.lookup.dirs->lock); - XFREE(ctx->x509_store.lookup.dirs, ctx->heap, DYNAMIC_TYPE_OPENSSL); + XFREE(ctx->x509_store.lookup.dirs, heapAtCTXInit, DYNAMIC_TYPE_OPENSSL); } #endif #ifdef WOLFSSL_STATIC_EPHEMERAL @@ -2391,6 +2399,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) FreeDer(&ctx->staticKE.x25519Key); #endif #endif + (void)heapAtCTXInit; } #ifdef WOLFSSL_STATIC_MEMORY @@ -2414,7 +2423,7 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx) int refCount; void* heap = ctx->heap; #ifdef WOLFSSL_STATIC_MEMORY - if (ctx->onHeap == 0) { + if (ctx->onHeapHint == 0) { heap = NULL; } #endif diff --git a/src/ssl.c b/src/ssl.c index 59a6e16e9..d2295cb31 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -471,14 +471,14 @@ WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap) if (method == NULL) return ctx; - ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX); + ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX); if (ctx) { int ret; ret = InitSSL_Ctx(ctx, method, heap); #ifdef WOLFSSL_STATIC_MEMORY if (heap != NULL) { - ctx->onHeap = 1; /* free the memory back to heap when done */ + ctx->onHeapHint = 1; /* free the memory back to heap when done */ } #endif if (ret < 0) { @@ -23325,6 +23325,14 @@ int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509) #if defined(OPENSSL_EXTRA_X509_SMALL) +int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name) +{ + WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz"); + if (!name) + return -1; + return name->sz; +} + /* Searches for the first ENTRY of type NID * idx is the location to start searching from, the value at when the entry was * found is stored into idx @@ -26766,8 +26774,8 @@ int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam, sz = (unsigned int)XSTRLEN(name); - /* If name is NUL-terminated, namelen can be set to zero. */ - if(nameSz == 0 || nameSz > sz) + /* If name is NULL-terminated, namelen can be set to zero. */ + if (nameSz == 0 || nameSz > sz) nameSz = sz; if (nameSz > 0 && name[nameSz - 1] == '\0') @@ -47436,15 +47444,6 @@ int wolfSSL_version(WOLFSSL* ssl) return WOLFSSL_FAILURE; } - -int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name) -{ - WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz"); - if(!name) - return -1; - return name->sz; -} - #ifdef HAVE_SNI int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name) { @@ -50353,12 +50352,14 @@ int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p, unsigned int p_len) { WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos"); - if(ctx == NULL) + if (ctx == NULL) return BAD_FUNC_ARG; - if((void *)ctx->alpn_cli_protos != NULL) - wolfSSL_OPENSSL_free((void *)ctx->alpn_cli_protos); - ctx->alpn_cli_protos = - (const unsigned char *)wolfSSL_OPENSSL_memdup(p, p_len, NULL, 0); + if (ctx->alpn_cli_protos != NULL) { + XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL); + } + + ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len, + ctx->heap, DYNAMIC_TYPE_OPENSSL); if (ctx->alpn_cli_protos == NULL) { #if defined(WOLFSSL_ERROR_CODE_OPENSSL) /* 0 on success in OpenSSL, non-0 on failure in OpenSSL @@ -50366,9 +50367,10 @@ int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p, */ return 1; #else - return SSL_FAILURE; + return WOLFSSL_FAILURE; #endif } + XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len); ctx->alpn_cli_protos_len = p_len; #if defined(WOLFSSL_ERROR_CODE_OPENSSL) @@ -59539,7 +59541,7 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, if (ctx->param == NULL) { ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( sizeof(WOLFSSL_X509_VERIFY_PARAM), - NULL,DYNAMIC_TYPE_OPENSSL); + NULL, DYNAMIC_TYPE_OPENSSL); if (ctx->param == NULL){ WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed"); return WOLFSSL_FAILURE; @@ -59561,8 +59563,8 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data); #endif #ifdef OPENSSL_EXTRA - if (ctx->param != NULL){ - XFREE(ctx->param,NULL,DYNAMIC_TYPE_OPENSSL); + if (ctx->param != NULL) { + XFREE(ctx->param, NULL, DYNAMIC_TYPE_OPENSSL); ctx->param = NULL; } #endif @@ -59575,8 +59577,8 @@ void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx) { if (ctx != NULL) { #ifdef OPENSSL_EXTRA - if (ctx->param != NULL){ - XFREE(ctx->param,NULL,DYNAMIC_TYPE_OPENSSL); + if (ctx->param != NULL) { + XFREE(ctx->param, NULL, DYNAMIC_TYPE_OPENSSL); ctx->param = NULL; } #endif diff --git a/tests/api.c b/tests/api.c index 40f887a20..727cf4948 100644 --- a/tests/api.c +++ b/tests/api.c @@ -518,7 +518,7 @@ static int test_wolfCrypt_Init(void) AssertTrue((buff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL) ; AssertTrue(XFREAD(buff, 1, sz, f) == sz); XMEMCMP(server_cert_der_2048, buff, sz); - printf(resultFmt, passed); + printf(resultFmt, passed); #endif return WOLFSSL_SUCCESS; } @@ -5418,7 +5418,7 @@ done: * Used by SNI / ALPN / crypto callback helper functions */ #if defined(HAVE_IO_TESTS_DEPENDENCIES) && \ (defined(HAVE_SNI) || defined(HAVE_ALPN) || defined(WOLF_CRYPTO_CB) || \ - defined(HAVE_ALPN_PROTOS_SUPPORT)) + defined(HAVE_ALPN_PROTOS_SUPPORT)) || defined(WOLFSSL_STATIC_MEMORY) #define ENABLE_TLS_CALLBACK_TEST #endif @@ -5429,7 +5429,7 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) { callback_functions* callbacks = ((func_args*)args)->callbacks; - WOLFSSL_CTX* ctx; + WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; SOCKET_T sfd = 0; SOCKET_T cfd = 0; @@ -5443,7 +5443,20 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) ((func_args*)args)->return_code = TEST_FAIL; - ctx = wolfSSL_CTX_new(callbacks->method()); +#ifdef WOLFSSL_STATIC_MEMORY + if (callbacks->method_ex != NULL && callbacks->mem != NULL && + callbacks->memSz > 0) { + ret = wolfSSL_CTX_load_static_memory(&ctx, callbacks->method_ex, + callbacks->mem, callbacks->memSz, 0, 1); + if (ret != WOLFSSL_SUCCESS) { + printf("CTX static new failed %d\n", ret); + return 0; + } + } +#endif + if (ctx == NULL) { + ctx = wolfSSL_CTX_new(callbacks->method()); + } if (ctx == NULL) { printf("CTX new failed\n"); return 0; @@ -5622,7 +5635,7 @@ static void run_wolfssl_client(void* args) { callback_functions* callbacks = ((func_args*)args)->callbacks; - WOLFSSL_CTX* ctx; + WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; SOCKET_T sfd = 0; @@ -5642,7 +5655,20 @@ static void run_wolfssl_client(void* args) if (callbacks->keyPemFile == NULL) callbacks->keyPemFile = cliKeyFile; - ctx = wolfSSL_CTX_new(callbacks->method()); +#ifdef WOLFSSL_STATIC_MEMORY + if (callbacks->method_ex != NULL && callbacks->mem != NULL && + callbacks->memSz > 0) { + ret = wolfSSL_CTX_load_static_memory(&ctx, callbacks->method_ex, + callbacks->mem, callbacks->memSz, 0, 1); + if (ret != WOLFSSL_SUCCESS) { + printf("CTX static new failed %d\n", ret); + return; + } + } +#endif + if (ctx == NULL) { + ctx = wolfSSL_CTX_new(callbacks->method()); + } if (ctx == NULL) { printf("CTX new failed\n"); return; @@ -35806,7 +35832,8 @@ static void test_wolfSSL_X509_sign(void) #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA) int ret; - char *caSubject; + char *cn; + word32 cnSz; X509_NAME *name; X509 *x509, *ca; DecodedCert dCert; @@ -35918,11 +35945,13 @@ static void test_wolfSSL_X509_sign(void) InitDecodedCert(&dCert, certIssuer, (word32)certIssuerSz, 0); AssertIntEQ(ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL), 0); - AssertNotNull(ca = wolfSSL_d2i_X509(NULL, &certIssuer, (int)certIssuerSz)); - AssertNotNull(caSubject = wolfSSL_X509_NAME_oneline( - X509_get_subject_name(ca), 0, 0)); - AssertIntEQ(0, XSTRNCMP(caSubject, dCert.subject, XSTRLEN(caSubject))); - XFREE(caSubject, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); + AssertNotNull(ca = d2i_X509(NULL, &certIssuer, (int)certIssuerSz)); + AssertNotNull(name = X509_get_subject_name(ca)); + cnSz = X509_NAME_get_sz(name); + AssertNotNull(cn = (char*)XMALLOC(cnSz, HEAP_HINT, DYNAMIC_TYPE_OPENSSL)); + AssertNotNull(cn = X509_NAME_oneline(name, cn, cnSz)); + AssertIntEQ(0, XSTRNCMP(cn, dCert.subject, XSTRLEN(cn))); + XFREE(cn, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); #ifdef WOLFSSL_MULTI_ATTRIB /* test adding multiple OU's to the signer */ @@ -35938,9 +35967,13 @@ static void test_wolfSSL_X509_sign(void) AssertIntEQ(X509_set_issuer_name(x509, name), SSL_SUCCESS); AssertIntGT(X509_sign(x509, priv, EVP_sha256()), 0); - AssertNotNull(caSubject = wolfSSL_X509_NAME_oneline( - X509_get_issuer_name(x509), 0, 0)); - XFREE(caSubject, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); + AssertNotNull(name = X509_get_issuer_name(x509)); + cnSz = X509_NAME_get_sz(name); + AssertNotNull(cn = (char*)XMALLOC(cnSz, HEAP_HINT, DYNAMIC_TYPE_OPENSSL)); + AssertNotNull(cn = X509_NAME_oneline(name, cn, cnSz)); + /* compare and don't include the multi-attrib "/OU=OU1/OU=OU2" above */ + AssertIntEQ(0, XSTRNCMP(cn, dCert.issuer, XSTRLEN(dCert.issuer))); + XFREE(cn, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); FreeDecodedCert(&dCert); @@ -50748,6 +50781,38 @@ static void test_wc_CryptoCb_TLS(int tlsVer, client_cbf.method = wolfTLSv1_2_client_method; #endif } + else if (tlsVer == WOLFSSL_TLSV1_1) { + #ifndef NO_OLD_TLS + server_cbf.method = wolfTLSv1_1_server_method; + client_cbf.method = wolfTLSv1_1_client_method; + #endif + } + else if (tlsVer == WOLFSSL_TLSV1) { + #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10) + server_cbf.method = wolfTLSv1_server_method; + client_cbf.method = wolfTLSv1_client_method; + #endif + } + else if (tlsVer == WOLFSSL_SSLV3) { + #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) && \ + defined(WOLFSSL_STATIC_RSA) + server_cbf.method = wolfSSLv3_server_method; + client_cbf.method = wolfSSLv3_client_method; + #endif + } + else if (tlsVer == WOLFSSL_DTLSV1_2) { + #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) + server_cbf.method = wolfDTLSv1_2_server_method; + client_cbf.method = wolfDTLSv1_2_client_method; + #endif + } + else if (tlsVer == WOLFSSL_DTLSV1) { + #if defined(WOLFSSL_DTLS) && !defined(NO_OLD_TLS) + server_cbf.method = wolfDTLSv1_server_method; + client_cbf.method = wolfDTLSv1_client_method; + #endif + } + if (server_cbf.method == NULL) { /* not enabled */ return; @@ -50799,39 +50864,267 @@ static void test_wc_CryptoCb(void) /* TODO: Add crypto callback API tests */ #ifdef HAVE_IO_TESTS_DEPENDENCIES + #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) + int tlsVer; + #endif + #ifndef NO_RSA - /* RSA */ - test_wc_CryptoCb_TLS(WOLFSSL_TLSV1_3, - svrCertFile, cliCertFile, cliKeyFile, cliKeyPubFile, - cliCertFile, svrCertFile, svrKeyFile, svrKeyPubFile); - test_wc_CryptoCb_TLS(WOLFSSL_TLSV1_2, - svrCertFile, cliCertFile, cliKeyFile, cliKeyPubFile, - cliCertFile, svrCertFile, svrKeyFile, svrKeyPubFile); + for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) { + test_wc_CryptoCb_TLS(tlsVer, + svrCertFile, cliCertFile, cliKeyFile, cliKeyPubFile, + cliCertFile, svrCertFile, svrKeyFile, svrKeyPubFile); + } #endif - #ifdef HAVE_ECC - /* ECC */ - test_wc_CryptoCb_TLS(WOLFSSL_TLSV1_3, - caEccCertFile, cliEccCertFile, cliEccKeyFile, cliEccKeyPubFile, - cliEccCertFile, eccCertFile, eccKeyFile, eccKeyPubFile); - test_wc_CryptoCb_TLS(WOLFSSL_TLSV1_2, - caEccCertFile, cliEccCertFile, cliEccKeyFile, cliEccKeyPubFile, - cliEccCertFile, eccCertFile, eccKeyFile, eccKeyPubFile); + for (tlsVer = WOLFSSL_TLSV1; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) { + test_wc_CryptoCb_TLS(tlsVer, + caEccCertFile, cliEccCertFile, cliEccKeyFile, cliEccKeyPubFile, + cliEccCertFile, eccCertFile, eccKeyFile, eccKeyPubFile); + } #endif - #ifdef HAVE_ED25519 - /* ED25519 */ - test_wc_CryptoCb_TLS(WOLFSSL_TLSV1_3, - caEdCertFile, cliEdCertFile, cliEdKeyFile, cliEdKeyPubFile, - cliEdCertFile, edCertFile, edKeyFile, edKeyPubFile); - test_wc_CryptoCb_TLS(WOLFSSL_TLSV1_2, - caEdCertFile, cliEdCertFile, cliEdKeyFile, cliEdKeyPubFile, - cliEdCertFile, edCertFile, edKeyFile, edKeyPubFile); + for (tlsVer = WOLFSSL_TLSV1_2; tlsVer <= WOLFSSL_DTLSV1_2; tlsVer++) { + if (tlsVer == WOLFSSL_DTLSV1) continue; + test_wc_CryptoCb_TLS(tlsVer, + caEdCertFile, cliEdCertFile, cliEdKeyFile, cliEdKeyPubFile, + cliEdCertFile, edCertFile, edKeyFile, edKeyPubFile); + } #endif #endif /* HAVE_IO_TESTS_DEPENDENCIES */ #endif /* WOLF_CRYPTO_CB */ } +#if defined(WOLFSSL_STATIC_MEMORY) && defined(HAVE_IO_TESTS_DEPENDENCIES) + +/* tlsVer: Example: WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */ +static void test_wolfSSL_CTX_StaticMemory_TLS(int tlsVer, + const char* cliCaPemFile, const char* cliCertPemFile, + const char* cliPrivKeyPemFile, + const char* svrCaPemFile, const char* svrCertPemFile, + const char* svrPrivKeyPemFile, + byte* cliMem, word32 cliMemSz, byte* svrMem, word32 svrMemSz) +{ + callback_functions client_cbf; + callback_functions server_cbf; + + XMEMSET(&client_cbf, 0, sizeof(client_cbf)); + XMEMSET(&server_cbf, 0, sizeof(server_cbf)); + + if (tlsVer == WOLFSSL_TLSV1_3) { + #ifdef WOLFSSL_TLS13 + server_cbf.method_ex = wolfTLSv1_3_server_method_ex; + client_cbf.method_ex = wolfTLSv1_3_client_method_ex; + #endif + } + else if (tlsVer == WOLFSSL_TLSV1_2) { + #ifndef WOLFSSL_NO_TLS12 + server_cbf.method_ex = wolfTLSv1_2_server_method_ex; + client_cbf.method_ex = wolfTLSv1_2_client_method_ex; + #endif + } + else if (tlsVer == WOLFSSL_TLSV1_1) { + #ifndef NO_OLD_TLS + server_cbf.method_ex = wolfTLSv1_1_server_method_ex; + client_cbf.method_ex = wolfTLSv1_1_client_method_ex; + #endif + } + else if (tlsVer == WOLFSSL_TLSV1) { + #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10) + server_cbf.method_ex = wolfTLSv1_server_method_ex; + client_cbf.method_ex = wolfTLSv1_client_method_ex; + #endif + } + else if (tlsVer == WOLFSSL_SSLV3) { + #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) && \ + defined(WOLFSSL_STATIC_RSA) + server_cbf.method_ex = wolfSSLv3_server_method_ex; + client_cbf.method_ex = wolfSSLv3_client_method_ex; + #endif + } + else if (tlsVer == WOLFSSL_DTLSV1_2) { + #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) + server_cbf.method_ex = wolfDTLSv1_2_server_method_ex; + client_cbf.method_ex = wolfDTLSv1_2_client_method_ex; + #endif + } + else if (tlsVer == WOLFSSL_DTLSV1) { + #if defined(WOLFSSL_DTLS) && !defined(NO_OLD_TLS) + server_cbf.method_ex = wolfDTLSv1_server_method_ex; + client_cbf.method_ex = wolfDTLSv1_client_method_ex; + #endif + } + + if (server_cbf.method_ex == NULL) { + /* not enabled */ + return; + } + + /* Setup the keys for the TLS test */ + client_cbf.certPemFile = cliCertPemFile; + client_cbf.keyPemFile = cliPrivKeyPemFile; + client_cbf.caPemFile = cliCaPemFile; + + server_cbf.certPemFile = svrCertPemFile; + server_cbf.keyPemFile = svrPrivKeyPemFile; + server_cbf.caPemFile = svrCaPemFile; + + client_cbf.mem = cliMem; + client_cbf.memSz = cliMemSz; + server_cbf.mem = svrMem; + server_cbf.memSz = svrMemSz; + + client_cbf.devId = INVALID_DEVID; + server_cbf.devId = INVALID_DEVID; + + /* Perform TLS server and client test */ + /* First test is at WOLFSSL_CTX level */ + test_wolfSSL_client_server(&client_cbf, &server_cbf); + /* Check for success */ + AssertIntEQ(server_cbf.return_code, TEST_SUCCESS); + AssertIntEQ(client_cbf.return_code, TEST_SUCCESS); + + /* Second test is a WOLFSSL object level */ + client_cbf.loadToSSL = 1; server_cbf.loadToSSL = 1; + test_wolfSSL_client_server(&client_cbf, &server_cbf); + + /* Check for success */ + AssertIntEQ(server_cbf.return_code, TEST_SUCCESS); + AssertIntEQ(client_cbf.return_code, TEST_SUCCESS); +} +#endif /* WOLFSSL_STATIC_MEMORY && HAVE_IO_TESTS_DEPENDENCIES */ + +#ifdef WOLFSSL_STATIC_MEMORY +#if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || \ + defined(SESSION_CERTS) + #ifdef OPENSSL_EXTRA + #define TEST_TLS_STATIC_MEMSZ (400000) + #else + #define TEST_TLS_STATIC_MEMSZ (320000) + #endif +#else + #define TEST_TLS_STATIC_MEMSZ (80000) +#endif + +static void test_wolfSSL_CTX_StaticMemory_SSL(WOLFSSL_CTX* ctx) +{ + WOLFSSL *ssl1 = NULL, *ssl2 = NULL, *ssl3 = NULL; + WOLFSSL_MEM_STATS mem_stats; + WOLFSSL_MEM_CONN_STATS ssl_stats; + +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) + AssertIntEQ(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, + WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, + WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); +#endif + + AssertNotNull((ssl1 = wolfSSL_new(ctx))); + AssertNotNull((ssl2 = wolfSSL_new(ctx))); + /* this should fail because kMaxCtxClients == 2 */ + AssertNull((ssl3 = wolfSSL_new(ctx))); + + if (wolfSSL_is_static_memory(ssl1, &ssl_stats) == 1) { + #ifdef DEBUG_WOLFSSL + wolfSSL_PrintStatsConn(&ssl_stats); + #endif + (void)ssl_stats; + } + + /* display collected statistics */ + if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) == 1) { + #ifdef DEBUG_WOLFSSL + wolfSSL_PrintStats(&mem_stats); + #endif + (void)mem_stats; + } + + wolfSSL_free(ssl1); + wolfSSL_free(ssl2); +} +#endif /* WOLFSSL_STATIC_MEMORY */ + +static void test_wolfSSL_CTX_StaticMemory(void) +{ +#ifdef WOLFSSL_STATIC_MEMORY + wolfSSL_method_func method_func; + WOLFSSL_CTX* ctx; + const int kMaxCtxClients = 2; + #ifdef HAVE_IO_TESTS_DEPENDENCIES + #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) + int tlsVer; + byte cliMem[TEST_TLS_STATIC_MEMSZ]; + #endif + #endif + byte svrMem[TEST_TLS_STATIC_MEMSZ]; + + printf(testingFmt, "test_wolfSSL_CTX_StaticMemory()"); + +#ifndef NO_WOLFSSL_SERVER + #ifndef WOLFSSL_NO_TLS12 + method_func = wolfTLSv1_2_server_method_ex; + #else + method_func = wolfTLSv1_3_server_method_ex; + #endif +#else + #ifndef WOLFSSL_NO_TLS12 + method_func = wolfTLSv1_2_client_method_ex; + #else + method_func = wolfTLSv1_3_client_method_ex; + #endif +#endif + + /* Test creating CTX directly from static memory pool */ + ctx = NULL; + AssertIntEQ(wolfSSL_CTX_load_static_memory( + &ctx, method_func, svrMem, sizeof(svrMem), + 0, kMaxCtxClients), WOLFSSL_SUCCESS); + test_wolfSSL_CTX_StaticMemory_SSL(ctx); + wolfSSL_CTX_free(ctx); + ctx = NULL; + + /* Test for heap allocated CTX, then assigning static pool to it */ + AssertNotNull(ctx = wolfSSL_CTX_new(method_func(NULL))); + AssertIntEQ(wolfSSL_CTX_load_static_memory(&ctx, + NULL, svrMem, sizeof(svrMem), + 0, kMaxCtxClients), WOLFSSL_SUCCESS); + test_wolfSSL_CTX_StaticMemory_SSL(ctx); + wolfSSL_CTX_free(ctx); + + /* TLS Level Tests using static memory */ +#ifdef HAVE_IO_TESTS_DEPENDENCIES + #ifndef NO_RSA + for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) { + test_wolfSSL_CTX_StaticMemory_TLS(tlsVer, + svrCertFile, cliCertFile, cliKeyFile, + cliCertFile, svrCertFile, svrKeyFile, + cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)); + } + #endif + #ifdef HAVE_ECC + for (tlsVer = WOLFSSL_TLSV1; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) { + test_wolfSSL_CTX_StaticMemory_TLS(tlsVer, + caEccCertFile, cliEccCertFile, cliEccKeyFile, + cliEccCertFile, eccCertFile, eccKeyFile, + cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)); + } + #endif + #ifdef HAVE_ED25519 + for (tlsVer = WOLFSSL_TLSV1_2; tlsVer <= WOLFSSL_DTLSV1_2; tlsVer++) { + if (tlsVer == WOLFSSL_DTLSV1) continue; + test_wolfSSL_CTX_StaticMemory_TLS(tlsVer, + caEdCertFile, cliEdCertFile, cliEdKeyFile, + cliEdCertFile, edCertFile, edKeyFile, + cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)); + } + #endif +#endif /* HAVE_IO_TESTS_DEPENDENCIES */ + + printf(resultFmt, passed); +#endif +} + + + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -51684,6 +51977,7 @@ void ApiTest(void) test_wolfSSL_CTX_LoadCRL(); test_wc_CryptoCb(); + test_wolfSSL_CTX_StaticMemory(); AssertIntEQ(test_ForceZero(), 0); diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index a5ebeaf40..49b4fb78b 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -628,6 +628,10 @@ void* wolfSSL_Malloc(size_t size, void* heap, int type) #else res = malloc(size); #endif + + #ifdef WOLFSSL_DEBUG_MEMORY + printf("Alloc: %p -> %u at %s:%d\n", res, (word32)size, func, line); + #endif #else WOLFSSL_MSG("No heap hint found to use and no malloc"); #ifdef WOLFSSL_DEBUG_MEMORY @@ -751,6 +755,9 @@ void wolfSSL_Free(void *ptr, void* heap, int type) /* check for testing heap hint was set */ #ifdef WOLFSSL_HEAP_TEST if (heap == (void*)WOLFSSL_HEAP_TEST) { + #ifdef WOLFSSL_DEBUG_MEMORY + printf("Free: %p at %s:%d\n", pt, func, line); + #endif return free(ptr); } #endif diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 01570b0ed..da235049f 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -446,6 +446,8 @@ int wc_FileExists(const char* fname) { struct ReadDirCtx ctx; + XMEMSET(&ctx, 0, sizeof(ctx)); + if (fname == NULL) return 0; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 05687c2a7..14ca12d32 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2811,7 +2811,7 @@ struct WOLFSSL_CTX { byte disallowEncThenMac:1; /* Don't do Encrypt-Then-MAC */ #endif #ifdef WOLFSSL_STATIC_MEMORY - byte onHeap:1; /* whether the ctx/method is put on heap hint */ + byte onHeapHint:1; /* whether the ctx/method is put on heap hint */ #endif #ifdef WOLFSSL_MULTICAST byte haveMcast; /* multicast requested */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 920a62d71..9abe7fa19 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -550,6 +550,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_NAME_new wolfSSL_X509_NAME_new #define X509_NAME_free wolfSSL_X509_NAME_free #define X509_NAME_dup wolfSSL_X509_NAME_dup +#define X509_NAME_get_sz wolfSSL_X509_NAME_get_sz #define X509_NAME_get_text_by_NID wolfSSL_X509_NAME_get_text_by_NID #define X509_NAME_get_index_by_OBJ wolfSSL_X509_NAME_get_index_by_OBJ #define X509_NAME_cmp wolfSSL_X509_NAME_cmp diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index fffd89214..60094ad10 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1693,6 +1693,7 @@ WOLFSSL_API int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ct WOLFSSL_API int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME*); +WOLFSSL_API int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME*); WOLFSSL_API int wolfSSL_X509_NAME_get_text_by_NID( WOLFSSL_X509_NAME*, int, char*, int); WOLFSSL_API int wolfSSL_X509_NAME_get_index_by_NID( @@ -2863,6 +2864,9 @@ enum { WOLFSSL_TLSV1_1 = 2, WOLFSSL_TLSV1_2 = 3, WOLFSSL_TLSV1_3 = 4, + WOLFSSL_DTLSV1 = 5, + WOLFSSL_DTLSV1_2 = 6, + WOLFSSL_USER_CA = 1, /* user added as trusted */ WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */ }; @@ -4326,8 +4330,6 @@ WOLFSSL_API int wolfSSL_SESSION_set_ex_data_with_cleanup( WOLFSSL_API int wolfSSL_SESSION_get_ex_new_index(long,void*,void*,void*, CRYPTO_free_func*); -WOLFSSL_API int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME*); - WOLFSSL_API const unsigned char* wolfSSL_SESSION_get_id(WOLFSSL_SESSION*, unsigned int*); diff --git a/wolfssl/test.h b/wolfssl/test.h index 6e1c802c4..8302ddb84 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -509,6 +509,11 @@ typedef struct callback_functions { const char* caPemFile; const char* certPemFile; const char* keyPemFile; +#ifdef WOLFSSL_STATIC_MEMORY + byte* mem; + word32 memSz; + wolfSSL_method_func method_ex; +#endif int devId; int return_code; unsigned char isSharedCtx:1; @@ -3608,6 +3613,22 @@ static WC_INLINE int wolfSSL_PrintStats(WOLFSSL_MEM_STATS* stats) return 1; } + +static WC_INLINE int wolfSSL_PrintStatsConn(WOLFSSL_MEM_CONN_STATS* stats) +{ + if (stats == NULL) { + return 0; + } + + fprintf(stderr, "peak connection memory = %d\n", stats->peakMem); + fprintf(stderr, "current memory in use = %d\n", stats->curMem); + fprintf(stderr, "peak connection allocs = %d\n", stats->peakAlloc); + fprintf(stderr, "current connection allocs = %d\n",stats->curAlloc); + fprintf(stderr, "total connection allocs = %d\n", stats->totalAlloc); + fprintf(stderr, "total connection frees = %d\n\n", stats->totalFr); + + return 1; +} #endif /* WOLFSSL_STATIC_MEMORY */ #ifdef HAVE_PK_CALLBACKS diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 751711130..544e25464 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1526,8 +1526,13 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #endif #ifndef FILE_BUFFER_SIZE - #define FILE_BUFFER_SIZE 1024 /* default static file buffer size for input, \ - will use dynamic buffer if not big enough */ + /* default static file buffer size for input, will use dynamic buffer if + * not big enough */ + #ifdef WOLFSSL_CERT_EXT + #define FILE_BUFFER_SIZE (3*1024) + #else + #define FILE_BUFFER_SIZE (1*1024) + #endif #endif #ifdef HAVE_CAVIUM_OCTEON_SYNC