diff --git a/src/ssl.c b/src/ssl.c index b4cac31053..ff88531f86 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1582,6 +1582,18 @@ static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl) XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion)); XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion)); +#ifdef HAVE_ONE_TIME_AUTH +#ifdef HAVE_POLY1305 + if (ssl->auth.setup && ssl->auth.poly1305 != NULL) { + dup->auth.poly1305 = + (Poly1305*)XMALLOC(sizeof(Poly1305), dup->heap, DYNAMIC_TYPE_CIPHER); + if (dup->auth.poly1305 == NULL) + return MEMORY_E; + dup->auth.setup = 1; + } +#endif +#endif + /* dup side now owns encrypt/write ciphers */ XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers)); diff --git a/tests/api.c b/tests/api.c index d9c75f6752..8f7280d7ea 100644 --- a/tests/api.c +++ b/tests/api.c @@ -69273,6 +69273,146 @@ static int test_tls_multi_handshakes_one_record(void) return EXPECT_RESULT(); } + +static int test_write_dup(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_WRITE_DUP) + size_t i, j; + char hiWorld[] = "dup message"; + char readData[sizeof(hiWorld) + 5]; + struct { + method_provider client_meth; + method_provider server_meth; + const char* version_name; + int version; + } methods[] = { +#ifndef WOLFSSL_NO_TLS12 + {wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2", WOLFSSL_TLSV1_2}, +#endif +#ifdef WOLFSSL_TLS13 + {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3", WOLFSSL_TLSV1_3}, +#endif + }; + struct { + const char* cipher; + int version; + } ciphers[] = { +/* For simplicity the macros are copied from internal.h */ +/* TLS 1.2 */ +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + #ifndef NO_RSA + {"ECDHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2}, + #endif + #endif + #if !defined(NO_DH) && !defined(NO_RSA) && !defined(NO_TLS_DH) + {"DHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2}, + #endif +#endif +#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \ + !defined(NO_RSA) && defined(HAVE_AESGCM) && !defined(NO_TLS_DH) + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + {"DHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2}, + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + {"DHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2}, + #endif +#endif +#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) \ + && !defined(NO_TLS) && !defined(NO_AES) + #ifdef HAVE_AESGCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + #ifndef NO_RSA + {"ECDHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2}, + #endif + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + #ifndef NO_RSA + {"ECDHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2}, + #endif + #endif + #endif +#endif +/* TLS 1.3 */ +#ifdef WOLFSSL_TLS13 + #ifdef HAVE_AESGCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + {"TLS13-AES128-GCM-SHA256", WOLFSSL_TLSV1_3}, + #endif + #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) + {"TLS13-AES256-GCM-SHA384", WOLFSSL_TLSV1_3}, + #endif + #endif + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + #ifndef NO_SHA256 + {"TLS13-CHACHA20-POLY1305-SHA256", WOLFSSL_TLSV1_3}, + #endif + #endif + #ifdef HAVE_AESCCM + #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) + {"TLS13-AES128-CCM-SHA256", WOLFSSL_TLSV1_3}, + #endif + #endif +#endif + }; + + for (i = 0; i < XELEM_CNT(methods); i++) { + for (j = 0; j < XELEM_CNT(ciphers) && !EXPECT_FAIL(); j++) { + struct test_memio_ctx test_ctx; + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + WOLFSSL *ssl_c2 = NULL; + + if (methods[i].version != ciphers[j].version) + continue; + + if (i == 0 && j == 0) + printf("\n"); + + printf("Testing %s with %s... ", methods[i].version_name, + ciphers[j].cipher); + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + test_ctx.c_ciphers = test_ctx.s_ciphers = ciphers[j].cipher; + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + methods[i].client_meth, methods[i].server_meth), 0); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + ExpectNotNull(ssl_c2 = wolfSSL_write_dup(ssl_c)); + ExpectIntEQ(wolfSSL_write(ssl_c, hiWorld, sizeof(hiWorld)), + WRITE_DUP_WRITE_E); + ExpectIntEQ(wolfSSL_write(ssl_c2, hiWorld, sizeof(hiWorld)), + sizeof(hiWorld)); + + ExpectIntEQ(wolfSSL_read(ssl_s, readData, sizeof(readData)), + sizeof(hiWorld)); + ExpectIntEQ(wolfSSL_write(ssl_s, hiWorld, sizeof(hiWorld)), + sizeof(hiWorld)); + + ExpectIntEQ(wolfSSL_read(ssl_c2, readData, sizeof(readData)), + WRITE_DUP_READ_E); + ExpectIntEQ(wolfSSL_read(ssl_c, readData, sizeof(readData)), + sizeof(hiWorld)); + + if (EXPECT_SUCCESS()) + printf("ok\n"); + else + printf("failed\n"); + + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_c2); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); + } + } +#endif + return EXPECT_RESULT(); +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -70577,6 +70717,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_tls13_pq_groups), TEST_DECL(test_tls13_early_data), TEST_DECL(test_tls_multi_handshakes_one_record), + TEST_DECL(test_write_dup), /* This test needs to stay at the end to clean up any caches allocated. */ TEST_DECL(test_wolfSSL_Cleanup) };