diff --git a/examples/client/client.c b/examples/client/client.c index bfd152c1c..7dd11403a 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -142,6 +142,10 @@ static int lng_index = 0; #endif #ifdef HAVE_SESSION_TICKET + +#ifndef SESSION_TICKET_LEN +#define SESSION_TICKET_LEN 256 +#endif static int sessionTicketCB(WOLFSSL* ssl, const unsigned char* ticket, int ticketSz, void* ctx) @@ -1868,6 +1872,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_SRTP { "srtp", 2, 260 }, /* optional argument */ #endif +#ifdef WOLFSSL_DTLS13 + /* allow waitTicket option even when HAVE_SESSION_TICKET is 0. Otherwise + * tests that use this option will ignore the options following + * --waitTicket in the command line and fail */ + {"waitTicket", 0, 261}, +#endif /* WOLFSSL_DTLS13 */ { 0, 0, 0 } }; #endif @@ -1994,6 +2004,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) const char* dtlsSrtpProfiles = NULL; #endif +#ifdef HAVE_SESSION_TICKET + int waitTicket = 0; +#endif /* HAVE_SESSION_TICKET */ + char buffer[WOLFSSL_MAX_ERROR_SZ]; int argc = ((func_args*)args)->argc; @@ -2141,6 +2155,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) break; #endif +#ifdef WOLFSSL_DTLS13 + case 261: +#ifdef HAVE_SESSION_TICKET + waitTicket = 1; +#endif /* HAVE_SESSION_TICKET */ + break; +#endif /* WOLFSSL_DTLS13 */ + case 'G' : #ifdef WOLFSSL_SCTP doDTLS = 1; @@ -2749,12 +2771,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } else { if (doDTLS) { - if (version == 3) + if (version == 3) { version = -2; + } #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) - else if (version == EITHER_DOWNGRADE_VERSION) + else if (version == EITHER_DOWNGRADE_VERSION) { version = -3; + } #endif + else if (version == 4) { +#ifdef WOLFSSL_DTLS13 + version = -4; +#else + err_sys("Bad DTLS version"); +#endif /* WOLFSSL_DTLS13 */ + } else version = -1; } @@ -2833,6 +2864,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) method = wolfDTLSv1_2_client_method_ex; break; #endif +#ifdef WOLFSSL_DTLS13 + case -4: + method = wolfDTLSv1_3_client_method_ex; + break; +#endif /* WOLFSSL_DTLS13 */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) case -3: method = wolfDTLSv1_2_method_ex; @@ -3450,7 +3486,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) - if (!helloRetry && version >= 4) { + if (!helloRetry && (version >= 4 || version <= -4)) { SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, usePqc, pqcAlg, 0); } @@ -4029,6 +4065,29 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)ClientWrite(ssl, msg, msgSz, "", 0); #endif +#if defined(HAVE_SESSION_TICKET) + while (waitTicket == 1) { + unsigned char ticketBuf[SESSION_TICKET_LEN]; + int zeroReturn = 0; + word32 size; + + (void)zeroReturn; + size = sizeof(ticketBuf); + err = wolfSSL_get_SessionTicket(ssl, ticketBuf, &size); + if (err < 0) + err_sys("wolfSSL_get_SessionTicket failed"); + + if (size == 0) { + err = process_handshake_messages(ssl, !nonBlocking, &zeroReturn); + if (err < 0) + err_sys("error waiting for session ticket "); + } + else { + waitTicket = 0; + } + } +#endif + #ifndef NO_SESSION_CACHE if (resumeSession) { session = wolfSSL_get1_session(ssl); diff --git a/examples/server/server.c b/examples/server/server.c index 9c7bcd155..23973ee38 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -546,6 +546,11 @@ static void ServerRead(WOLFSSL* ssl, char* input, int inputLen) } else if (SSL_get_error(ssl, 0) == 0 && tcp_select(SSL_get_fd(ssl), 0) == TEST_RECV_READY) { + err = wolfSSL_peek(ssl, buffer, 0); + if(err < 0) { + err_sys_ex(runWithErrors, "wolfSSL_peek failed"); + } + if (wolfSSL_pending(ssl)) err = WOLFSSL_ERROR_WANT_READ; } } while (err == WC_PENDING_E || err == WOLFSSL_ERROR_WANT_READ); @@ -2160,13 +2165,22 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } else { if (doDTLS) { - if (version == 3) + if (version == 3) { version = -2; + } + else if (version == 4) { +#ifdef WOLFSSL_DTLS13 + version = -4; +#else + err_sys_ex(runWithErrors, "Bad DTLS version"); +#endif /* WOLFSSL_DTLS13 */ + } #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) - else if (version == EITHER_DOWNGRADE_VERSION) + else if (version == EITHER_DOWNGRADE_VERSION) { version = -3; + } #endif - else + else if (version == 2) version = -1; } } @@ -2225,7 +2239,16 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif case SERVER_DOWNGRADE_VERSION: - method = wolfSSLv23_server_method_ex; + if (!doDTLS) { + method = wolfSSLv23_server_method_ex; + } + else { +#ifdef WOLFSSL_DTLS13 + method = wolfDTLS_server_method_ex; +#else + err_sys_ex(runWithErrors, "version not supported"); +#endif /* WOLFSSL_DTLS13 */ + } break; #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) case EITHER_DOWNGRADE_VERSION: @@ -2246,6 +2269,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) method = wolfDTLSv1_2_server_method_ex; break; #endif +#ifdef WOLFSSL_DTLS13 + case -4: + method = wolfDTLSv1_3_server_method_ex; + break; +#endif #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) case -3: method = wolfDTLSv1_2_method_ex; @@ -2291,6 +2319,19 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) err_sys_ex(catastrophic, "unable to get ctx"); if (minVersion != SERVER_INVALID_VERSION) { +#ifdef WOLFSSL_DTLS13 + switch (minVersion) { + case 4: + minVersion = WOLFSSL_DTLSV1_3; + break; + case 3: + minVersion = WOLFSSL_DTLSV1_2; + break; + case 2: + minVersion = WOLFSSL_DTLSV1; + break; + } +#endif /* WOLFSSL_DTLS13 */ wolfSSL_CTX_SetMinVersion(ctx, minVersion); } @@ -3343,6 +3384,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT), 0); wolfSSL_request_certificate(ssl); + } #endif @@ -3395,6 +3437,23 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) Task_yield(); #endif +#if defined(WOLFSSL_DTLS13) + if (wolfSSL_dtls(ssl) && version == -4) { + int zero_return = 0; + while (wolfSSL_dtls13_has_pending_msg(ssl)) { + err = + process_handshake_messages(ssl, !nonBlocking, &zero_return); + if (err < 0) { + /* other peer closes the connection, non fatal */ + if (zero_return) + break; + + err_sys("Error while processing pending DTLSv1.3 messages"); + } + } + } +#endif /* WOLFSSL_DTLS13 */ + ret = SSL_shutdown(ssl); if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { while (tcp_select(wolfSSL_get_fd(ssl), DEFAULT_TIMEOUT_SEC) == diff --git a/wolfssl/test.h b/wolfssl/test.h index f5db32209..7ce3bb8cc 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -350,6 +350,10 @@ #endif #endif +#ifndef DEFAULT_TIMEOUT_SEC +#define DEFAULT_TIMEOUT_SEC 2 +#endif + /* all certs relative to wolfSSL home directory now */ #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL) #define caCertFile "certs/ca-cert.pem" @@ -5299,6 +5303,67 @@ static WC_INLINE void EarlyDataStatus(WOLFSSL* ssl) } #endif /* WOLFSSL_EARLY_DATA */ +#if defined(HAVE_SESSION_TICKET) || defined (WOLFSSL_DTLS13) +static WC_INLINE int process_handshake_messages(WOLFSSL* ssl, int blocking, + int* zero_return) +{ + int timeout = DEFAULT_TIMEOUT_SEC; + char foo[1]; + int ret = 0; + int dtls; + + (void)dtls; + + if (zero_return == NULL || ssl == NULL) + return -1; + + dtls = wolfSSL_dtls(ssl); + *zero_return = 0; + + if (!blocking) { +#ifdef WOLFSSL_DTLS + if (dtls) { + timeout = wolfSSL_dtls_get_current_timeout(ssl); + +#ifdef WOLFSSL_DTLS13 + if (timeout > 4 && wolfSSL_dtls13_use_quick_timeout(ssl)) + timeout /= 4; +#endif /* WOLFSSL_DTLS13 */ + } +#endif /* WOLFSSL_DTLS */ + + ret = tcp_select(wolfSSL_get_fd(ssl), timeout); + if (ret == TEST_ERROR_READY) { + err_sys("tcp_select error"); + return -1; + } + + if (ret == TEST_TIMEOUT) { +#ifdef WOLFSSL_DTLS + if (dtls) { + ret = wolfSSL_dtls_got_timeout(ssl); + if (ret != WOLFSSL_SUCCESS && !wolfSSL_want_write(ssl) && + !wolfSSL_want_read(ssl)) { + err_sys("got timeout error"); + return -1; + } + } +#endif /* WOLFSSL_DTLS */ + /* do the peek to detect if the peer closed the connection*/ + } + } + + ret = wolfSSL_peek(ssl, foo, 0); + if (ret < 0 && !wolfSSL_want_read(ssl) && !wolfSSL_want_write(ssl)) { + ret = wolfSSL_get_error(ssl, ret); + if (ret == WOLFSSL_ERROR_ZERO_RETURN) + *zero_return = 1; + return -1; + } + + return 0; +} +#endif /* HAVE_SESSION_TICKET || WOLFSSL_DTLS13 */ #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \ defined(DEBUG_UNIT_TEST_CERTS)