diff --git a/CMakeLists.txt b/CMakeLists.txt index f3006fe0a..cc15dbe00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,38 +275,6 @@ if("${FIPS_VERSION}" STREQUAL "v1") override_cache(WOLFSSL_TLS13 "no") endif() -# DTLS v1.3 -add_option("WOLFSSL_DTLS13" - "Enable wolfSSL DTLS v1.3 (default: disabled)" - "no" "yes;no") - -if(WOLFSSL_DTLS13) - if (NOT WOLFSSL_DTLS) - message(FATAL_ERROR "DTLS13 requires DTLS") - endif() - if (NOT WOLFSSL_TLS13) - message(FATAL_ERROR "DTLS13 requires TLS13") - endif() - list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS13") - list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_W64_WRAPPER") - - if (WOLFSSL_AES) - list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_DIRECT") - endif() -endif() - -# DTLS ConnectionID support -add_option("WOLFSSL_DTLS_CID" - "Enables wolfSSL DTLS CID (default: disabled)" - "no" "yes;no") - -if(WOLFSSL_DTLS_CID) - if(NOT WOLFSSL_DTLS13) - message(FATAL_ERROR "CID are supported only for DTLSv1.3") - endif() - list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS_CID") -endif() - # Post-handshake authentication add_option("WOLFSSL_POSTAUTH" "Enable wolfSSL Post-handshake Authentication (default: disabled)" @@ -325,9 +293,9 @@ endif() # Hello Retry Request Cookie add_option("WOLFSSL_HRR_COOKIE" "Enable the server to send Cookie Extension in HRR with state (default: disabled)" - "no" "yes;no") + "undefined" "yes;no;undefined") -if(WOLFSSL_HRR_COOKIE) +if("${WOLFSSL_HRR_COOKIE}" STREQUAL "yes") if(NOT WOLFSSL_TLS13) message(WARNING "TLS 1.3 is disabled - disabling HRR Cookie") override_cache(WOLFSSL_HRR_COOKIE "no") @@ -337,6 +305,42 @@ if(WOLFSSL_HRR_COOKIE) endif() endif() +# DTLS v1.3 +add_option("WOLFSSL_DTLS13" + "Enable wolfSSL DTLS v1.3 (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_DTLS13) + if (NOT WOLFSSL_DTLS) + message(FATAL_ERROR "DTLS13 requires DTLS") + endif() + if (NOT WOLFSSL_TLS13) + message(FATAL_ERROR "DTLS13 requires TLS13") + endif() + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS13") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_W64_WRAPPER") + if ("${WOLFSSL_HRR_COOKIE}" STREQUAL "undefined") + message(WARNING "DTLS1.3 is enabled - enabling HRR Cookie") + override_cache(WOLFSSL_HRR_COOKIE "yes") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SEND_HRR_COOKIE") + endif() + if (WOLFSSL_AES) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_DIRECT") + endif() +endif() + +# DTLS ConnectionID support +add_option("WOLFSSL_DTLS_CID" + "Enables wolfSSL DTLS CID (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_DTLS_CID) + if(NOT WOLFSSL_DTLS13) + message(FATAL_ERROR "CID are supported only for DTLSv1.3") + endif() + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS_CID") +endif() + # RNG add_option("WOLFSSL_RNG" "Enable compiling and using RNG (default: enabled)" diff --git a/configure.ac b/configure.ac index b798a5eb1..169548347 100644 --- a/configure.ac +++ b/configure.ac @@ -1078,7 +1078,7 @@ fi AC_ARG_ENABLE([hrrcookie], [AS_HELP_STRING([--enable-hrrcookie],[Enable the server to send Cookie Extension in HRR with state (default: disabled)])], [ ENABLED_SEND_HRR_COOKIE=$enableval ], - [ ENABLED_SEND_HRR_COOKIE=no ] + [ ENABLED_SEND_HRR_COOKIE=undefined ] ) if test "$ENABLED_SEND_HRR_COOKIE" = "yes" then @@ -3753,6 +3753,12 @@ then then AC_MSG_ERROR([You need to enable both DTLS and TLSv1.3 to use DTLSv1.3]) fi + if test "x$ENABLED_SEND_HRR_COOKIE" == "xundefined" + then + AC_MSG_NOTICE([DTLSv1.3 is enabled, enabling HRR cookie]) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SEND_HRR_COOKIE" + ENABLED_SEND_HRR_COOKIE="yes" + fi AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DTLS13 -DWOLFSSL_W64_WRAPPER" if test "x$ENABLED_AES" = "xyes" then diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 1cba16f15..f5d9532a0 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -13052,10 +13052,13 @@ int wolfSSL_connect(WOLFSSL* ssl); \ingroup Setup \brief This function is called on the server side to indicate that a - HelloRetryRequest message must contain a Cookie. - The Cookie holds a hash of the current transcript so that another server - process can handle the ClientHello in reply. - The secret is used when generting the integrity check on the Cookie data. + HelloRetryRequest message must contain a Cookie and, in case of using + protocol DTLS v1.3, that the handshake will always include a cookie + exchange. Please note that when using protocol DTLS v1.3, the cookie + exchange is enabled by default. The Cookie holds a hash of the current + transcript so that another server process can handle the ClientHello in + reply. The secret is used when generting the integrity check on the Cookie + data. \param [in,out] ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). \param [in] secret a pointer to a buffer holding the secret. @@ -13082,10 +13085,31 @@ int wolfSSL_connect(WOLFSSL* ssl); \endcode \sa wolfSSL_new + \sa wolfSSL_disable_hrr_cookie */ int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret, unsigned int secretSz); +/*! + + \ingroup Setup + + \brief This function is called on the server side to indicate that a + HelloRetryRequest message must NOT contain a Cookie and that, if using + protocol DTLS v1.3, a cookie exchange will not be included in the + handshake. Please note that not doing a cookie exchange when using protocol + DTLS v1.3 can make the server susceptible to DoS/Amplification attacks. + + \param [in,out] ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). + + \return WOLFSSL_SUCCESS if successful + \return BAD_FUNC_ARG if ssl is NULL or not using TLS v1.3 + \return SIDE_ERROR if invoked on client + + \sa wolfSSL_send_hrr_cookie +*/ +int wolfSSL_disable_hrr_cookie(WOLFSSL* ssl); + /*! \ingroup Setup diff --git a/examples/server/server.c b/examples/server/server.c index 504d013eb..1b9d06ca6 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -936,7 +936,8 @@ static const char* server_usage_msg[][65] = { "-Q Request certificate from client post-handshake\n", /* 49 */ #endif #ifdef WOLFSSL_SEND_HRR_COOKIE - "-J Server sends Cookie Extension containing state\n", /* 50 */ + "-J [n] Server sends Cookie Extension containing state (n to " + "disable)\n", /* 50 */ #endif #endif /* WOLFSSL_TLS13 */ #ifdef WOLFSSL_EARLY_DATA @@ -1702,7 +1703,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) /* 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:" + "A:B:C:D:E:FGH:IJ;KL:MNO:PQR:S:T;UVYZ:" "01:23:4:567:89" "@#", long_options, 0)) != -1) { switch (ch) { @@ -2085,6 +2086,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) case 'J' : #ifdef WOLFSSL_SEND_HRR_COOKIE hrrCookie = 1; + if (XSTRCMP(myoptarg, "n") == 0) + hrrCookie = -1; #endif break; @@ -2959,10 +2962,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif /* !NO_CERTS */ #ifdef WOLFSSL_SEND_HRR_COOKIE - if (hrrCookie && wolfSSL_send_hrr_cookie(ssl, NULL, 0) + if (hrrCookie == 1 && wolfSSL_send_hrr_cookie(ssl, NULL, 0) != WOLFSSL_SUCCESS) { err_sys("unable to set use of cookie with HRR msg"); } + else if (hrrCookie == -1) { + wolfSSL_disable_hrr_cookie(ssl); + } #endif #if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) diff --git a/src/internal.c b/src/internal.c index 25653ee89..f3adef06d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6934,11 +6934,22 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER) if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) { - ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0); - if (ret != 0) { - WOLFSSL_MSG("DTLS Cookie Secret error"); - return ret; + if (!IsAtLeastTLSv1_3(ssl->version)) { + ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0); + if (ret != 0) { + WOLFSSL_MSG("DTLS Cookie Secret error"); + return ret; + } } +#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE) + else { + ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("DTLS1.3 Cookie secret error"); + return ret; + } + } +#endif /* WOLFSSL_DTLS13 && WOLFSSL_SEND_HRR_COOKIE */ } #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */ diff --git a/src/tls13.c b/src/tls13.c index c78c5e150..2506f45c3 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -10628,7 +10628,33 @@ int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret, return ret; } -#endif + +int wolfSSL_disable_hrr_cookie(WOLFSSL* ssl) +{ + if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version)) + return BAD_FUNC_ARG; + +#ifdef NO_WOLFSSL_SERVER + return SIDE_ERROR +#else + if (ssl->options.side == WOLFSSL_CLIENT_END) + return SIDE_ERROR; + + if (ssl->buffers.tls13CookieSecret.buffer != NULL) { + ForceZero(ssl->buffers.tls13CookieSecret.buffer, + ssl->buffers.tls13CookieSecret.length); + XFREE(ssl->buffers.tls13CookieSecret.buffer, ssl->heap, + DYNAMIC_TYPE_COOKIE_PWD); + ssl->buffers.tls13CookieSecret.buffer = NULL; + ssl->buffers.tls13CookieSecret.length = 0; + } + + ssl->options.sendCookie = 0; + return WOLFSSL_SUCCESS; +#endif /* NO_WOLFSSL_SERVER */ +} + +#endif /* defined(WOLFSSL_SEND_HRR_COOKIE) */ #ifdef HAVE_SUPPORTED_CURVES /* Create a key share entry from group. diff --git a/tests/test-dtls13.conf b/tests/test-dtls13.conf index 516a61796..0186b9a7f 100644 --- a/tests/test-dtls13.conf +++ b/tests/test-dtls13.conf @@ -129,17 +129,16 @@ -l TLS13-AES128-GCM-SHA256 -J -# server DTLSv1.3 +# server DTLSv1.3 HelloRetryRequest with cookie -v 4 -u -l TLS13-AES128-GCM-SHA256 -J -# client DTLSv1.3 HelloRetryRequest with cookie +# client DTLSv1.3 -v 4 -u -l TLS13-AES128-GCM-SHA256 --J # server DTLSv1.3 -v 4 @@ -260,3 +259,14 @@ -u -l TLS13-AES128-GCM-SHA256 -f + +# server DTLSv1.3 no HelloRetryRequest cookie +-u +-v 4 +-l TLS_AES_128_GCM_SHA256 +-J n + +# client DTLSv1.3 defaults +-u +-v 4 +-l TLS_AES_128_GCM_SHA256 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2601feb86..92271de8c 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1144,6 +1144,7 @@ WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req); #ifdef WOLFSSL_TLS13 WOLFSSL_API int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret, unsigned int secretSz); +WOLFSSL_API int wolfSSL_disable_hrr_cookie(WOLFSSL * ssl); WOLFSSL_API int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx);