From 8fb48464e3202034453008fbaa258651ebd151a3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 22 Jun 2022 20:11:08 +0200 Subject: [PATCH 01/11] Add callback when we parse a verified ClientHello --- src/ssl.c | 34 ++++++++++++++++++++++++++++++++++ src/tls13.c | 11 +++++++++++ wolfssl/internal.h | 5 +++++ wolfssl/ssl.h | 4 ++++ 4 files changed, 54 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 3f19647b9..82d7c9162 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1183,6 +1183,14 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) if (ssl == NULL) return WOLFSSL_FAILURE; + if (peer == NULL || peerSz == 0) { + if (ssl->buffers.dtlsCtx.peer.sa != NULL) + XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR); + ssl->buffers.dtlsCtx.peer.sa = NULL; + ssl->buffers.dtlsCtx.peer.sz = 0; + return WOLFSSL_SUCCESS; + } + sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR); if (sa != NULL) { if (ssl->buffers.dtlsCtx.peer.sa != NULL) { @@ -12527,6 +12535,18 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return wolfSSL_accept_TLSv13(ssl); } #endif + +#ifdef WOLFSSL_DTLS + if (ssl->chGoodCb != NULL && !IsSCR(ssl)) { + int cbret = ssl->chGoodCb(ssl, ssl->chGoodCtx); + if (cbret < 0) { + ssl->error = cbret; + WOLFSSL_MSG("ClientHello Good Cb don't continue error"); + return WOLFSSL_FATAL_ERROR; + } + } +#endif + ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE; WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE"); FALL_THROUGH; @@ -12748,6 +12768,20 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #endif /* NO_WOLFSSL_SERVER */ +#ifdef WOLFSSL_DTLS +int wolfSSL_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx) +{ + WOLFSSL_ENTER("wolfSSL_SetChGoodCb"); + + if (ssl == NULL) + return BAD_FUNC_ARG; + + ssl->chGoodCb = cb; + ssl->chGoodCtx = user_ctx; + + return WOLFSSL_SUCCESS; +} +#endif #ifndef NO_HANDSHAKE_DONE_CB diff --git a/src/tls13.c b/src/tls13.c index 431c2e666..ae3e32c5b 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -10798,6 +10798,17 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) } } +#ifdef WOLFSSL_DTLS + if (ssl->chGoodCb != NULL) { + int cbret = ssl->chGoodCb(ssl, ssl->chGoodCtx); + if (cbret < 0) { + ssl->error = cbret; + WOLFSSL_MSG("ClientHello Good Cb don't continue error"); + return WOLFSSL_FATAL_ERROR; + } + } +#endif + ssl->options.acceptState = TLS13_ACCEPT_SECOND_REPLY_DONE; WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE"); FALL_THROUGH; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 66d8b1041..efaccc767 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4478,6 +4478,11 @@ struct WOLFSSL { #ifdef WOLFSSL_STATIC_MEMORY WOLFSSL_HEAP_HINT heap_hint; #endif +#ifdef WOLFSSL_DTLS + ClientHelloGoodCb chGoodCb; /* notify user we parsed a verified + * ClientHello */ + void* chGoodCtx; /* user ClientHello cb context */ +#endif #ifndef NO_HANDSHAKE_DONE_CB HandShakeDoneCb hsDoneCb; /* notify user handshake done */ void* hsDoneCtx; /* user handshake cb context */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 829fc4745..56be14ad0 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3940,6 +3940,10 @@ WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx); #define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */ +/* notify user we parsed a verified ClientHello is done. This only has an effect + * on the server end. */ +typedef int (*ClientHelloGoodCb)(WOLFSSL* ssl, void*); +WOLFSSL_API int wolfSSL_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx); /* notify user the handshake is done */ typedef int (*HandShakeDoneCb)(WOLFSSL* ssl, void*); WOLFSSL_API int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx); From c6aa4fc52696f961c45f31959f4d074f58f06515 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 24 Jun 2022 10:42:57 +0200 Subject: [PATCH 02/11] DTLS 1.3: allow the server to operate without maintaining state --- src/dtls13.c | 12 +++++ src/internal.c | 23 +++++++++ src/tls.c | 12 ++++- src/tls13.c | 113 +++++++++++++++++++++++++++++++++++--------- wolfcrypt/src/kdf.c | 1 + 5 files changed, 136 insertions(+), 25 deletions(-) diff --git a/src/dtls13.c b/src/dtls13.c index 2f30c98db..0954f6f8a 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -1388,6 +1388,18 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size, if (frag_off + frag_length > message_length) return BUFFER_ERROR; + if (handshake_type == client_hello && + /* Only when receiving an unverified ClientHello */ + ssl->options.serverState < SERVER_HELLO_COMPLETE) { + /* To be able to operate in stateless mode, we assume the ClientHello + * is in order and we use its Handshake Message number and Sequence + * Number for our Tx. */ + ssl->keys.dtls_expected_peer_handshake_number = + ssl->keys.dtls_handshake_number = + ssl->keys.dtls_peer_handshake_number; + ssl->dtls13Epochs[0].nextSeqNumber = ssl->keys.curSeq; + } + ret = Dtls13RtxMsgRecvd(ssl, (enum HandShakeType)handshake_type, frag_off); if (ret != 0) return ret; diff --git a/src/internal.c b/src/internal.c index 98286ba8c..f0b3f696d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8788,6 +8788,14 @@ static int EdDSA_Update(WOLFSSL* ssl, const byte* data, int sz) int HashRaw(WOLFSSL* ssl, const byte* data, int sz) { int ret = 0; +#ifdef WOLFSSL_DEBUG_TLS + byte digest[WC_MAX_DIGEST_SIZE]; + + WOLFSSL_MSG("HashRaw:"); + WOLFSSL_MSG("Data:"); + WOLFSSL_BUFFER(data, sz); + WOLFSSL_MSG("Hashes:"); +#endif (void)data; (void)sz; @@ -8817,16 +8825,31 @@ int HashRaw(WOLFSSL* ssl, const byte* data, int sz) ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, data, sz); if (ret != 0) return ret; + #ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Sha256"); + wc_Sha256GetHash(&ssl->hsHashes->hashSha256, digest); + WOLFSSL_BUFFER(digest, WC_SHA224_DIGEST_SIZE); + #endif #endif #ifdef WOLFSSL_SHA384 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, data, sz); if (ret != 0) return ret; + #ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Sha384"); + wc_Sha384GetHash(&ssl->hsHashes->hashSha384, digest); + WOLFSSL_BUFFER(digest, WC_SHA384_DIGEST_SIZE); + #endif #endif #ifdef WOLFSSL_SHA512 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, data, sz); if (ret != 0) return ret; + #ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Sha512"); + wc_Sha512GetHash(&ssl->hsHashes->hashSha512, digest); + WOLFSSL_BUFFER(digest, WC_SHA512_DIGEST_SIZE); + #endif #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ diff --git a/src/tls.c b/src/tls.c index 8a6617bd6..af3f197db 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6167,8 +6167,16 @@ static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length, /* client_hello */ extension = TLSX_Find(ssl->extensions, TLSX_COOKIE); - if (extension == NULL) - return HRR_COOKIE_ERROR; + if (extension == NULL) { +#ifdef WOLFSSL_DTLS13 + if (ssl->options.dtls) + /* TODO: Should we allow a ClientHello with a valid cookie even if + * the cookie wasn't sent by this WOLFSSL object? */ + return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0); + else +#endif + return HRR_COOKIE_ERROR; + } cookie = (Cookie*)extension->data; if (cookie->len != len || XMEMCMP(&cookie->data, input + idx, len) != 0) diff --git a/src/tls13.c b/src/tls13.c index ae3e32c5b..b8ec8a130 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2889,7 +2889,7 @@ int RestartHandshakeHash(WOLFSSL* ssl) #endif #if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER) - if (ssl->options.sendCookie) { + if (ssl->options.sendCookie && ssl->options.side == WOLFSSL_SERVER_END) { byte cookie[OPAQUE8_LEN + WC_MAX_DIGEST_SIZE + OPAQUE16_LEN * 2]; TLSX* ext; word32 idx = 0; @@ -4833,6 +4833,10 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie) return ret; if ((ret = HashRaw(ssl, header, sizeof(header))) != 0) return ret; +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Restart Hash from Cookie"); + WOLFSSL_BUFFER(cookieData + idx, hashSz); +#endif if ((ret = HashRaw(ssl, cookieData + idx, hashSz)) != 0) return ret; @@ -5282,20 +5286,45 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #if defined(WOLFSSL_SEND_HRR_COOKIE) if (ssl->options.sendCookie && - ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) { - TLSX* ext; + (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE +#ifdef WOLFSSL_DTLS13 + /* Always check for a valid cookie since we may have already + * sent a HRR but we reset the state. */ + || ssl->options.dtls +#endif + )) { + TLSX* ext = TLSX_Find(ssl->extensions, TLSX_COOKIE); - if ((ext = TLSX_Find(ssl->extensions, TLSX_COOKIE)) == NULL) - ERROR_OUT(HRR_COOKIE_ERROR, exit_dch); - - /* Ensure the cookie came from client and isn't the one in the - * response - HelloRetryRequest. - */ - if (ext->resp == 1) - ERROR_OUT(HRR_COOKIE_ERROR, exit_dch); - ret = RestartHandshakeHashWithCookie(ssl, (Cookie*)ext->data); - if (ret != 0) - goto exit_dch; + if (ext != NULL) { + /* Ensure the cookie came from client and isn't the one in the + * response - HelloRetryRequest. + */ + if (ext->resp == 0) { + ret = RestartHandshakeHashWithCookie(ssl, (Cookie*)ext->data); +#ifdef WOLFSSL_DTLS13 + /* Send a new cookie request */ + if (ret == HRR_COOKIE_ERROR && ssl->options.dtls) + ssl->options.serverState = NULL_STATE; + else +#endif + if (ret != 0) + goto exit_dch; + ssl->options.serverState = SERVER_HELLO_COMPLETE; + } + else { +#ifdef WOLFSSL_DTLS13 + if (ssl->options.dtls) + ssl->options.serverState = NULL_STATE; + else +#endif + ERROR_OUT(HRR_COOKIE_ERROR, exit_dch); + } + } + else +#ifdef WOLFSSL_DTLS13 + if (!ssl->options.dtls) +#endif + ERROR_OUT(HRR_COOKIE_ERROR, exit_dch); } #endif @@ -5424,9 +5453,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* We are using DTLSv13 and set the HRR cookie secret, use the cookie to perform a return-routability check. */ if (ret == 0 && ssl->options.dtls && ssl->options.sendCookie && - ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE) { + ssl->options.serverState < SERVER_HELLO_RETRY_REQUEST_COMPLETE) { - /* ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE + /* ssl->options.serverState < SERVER_HELLO_RETRY_REQUEST_COMPLETE so the client already provided a good KeyShareEntry. In this case we don't add the KEY_SHARE extension to the HelloRetryRequest or in the Cookie. The RFC8446 forbids to select a supported group @@ -5556,18 +5585,27 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) if (ret != 0) return ret; - -#ifdef WOLFSSL_DTLS13 - if (ssl->options.dtls) { - ret = Dtls13HashHandshake(ssl, - output + Dtls13GetRlHeaderLength(0) , - sendSz - Dtls13GetRlHeaderLength(0)); +#ifdef WOLFSSL_SEND_HRR_COOKIE + if (ssl->options.sendCookie && extMsgType == hello_retry_request) { + /* Reset the hashes from here. We will be able to restart the hashes + * from the cookie in RestartHandshakeHashWithCookie */ + ret = InitHandshakeHashes(ssl); } else +#endif + { +#ifdef WOLFSSL_DTLS13 + if (ssl->options.dtls) { + ret = Dtls13HashHandshake(ssl, + output + Dtls13GetRlHeaderLength(0) , + sendSz - Dtls13GetRlHeaderLength(0)); + } + else #endif /* WOLFSSL_DTLS13 */ { ret = HashOutput(ssl, output, sendSz, 0); } + } if (ret != 0) return ret; @@ -5598,7 +5636,6 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) ssl->buffers.outputBuffer.length += sendSz; if (!ssl->options.groupMessages || extMsgType != server_hello) - ret = SendBuffered(ssl); WOLFSSL_LEAVE("SendTls13ServerHello", ret); @@ -10754,6 +10791,36 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) WOLFSSL_ERROR(ssl->error); return WOLFSSL_FATAL_ERROR; } +#ifdef WOLFSSL_DTLS13 + if (ssl->options.dtls && wolfSSL_dtls_get_using_nonblock(ssl)) { + /* Reset the state so that we can statelessly await the + * ClientHello that contains the cookie. Return a WANT_READ + * to the user so that we don't drop UDP messages in the + * network callbacks. */ + + /* Reset DTLS window */ + w64Zero(&ssl->dtls13Epochs[0].nextSeqNumber); + w64Zero(&ssl->dtls13Epochs[0].nextPeerSeqNumber); + XMEMSET(ssl->dtls13Epochs[0].window, 0, + sizeof(ssl->dtls13Epochs[0].window)); + + ssl->keys.dtls_expected_peer_handshake_number = 0; + ssl->keys.dtls_handshake_number = 0; + + ssl->msgsReceived.got_client_hello = 0; + + /* Reset states */ + ssl->options.serverState = NULL_STATE; + ssl->options.clientState = NULL_STATE; + ssl->options.connectState = CONNECT_BEGIN; + ssl->options.acceptState = ACCEPT_BEGIN; + ssl->options.handShakeState = NULL_STATE; + + ssl->error = WANT_READ; + WOLFSSL_ERROR(ssl->error); + return WOLFSSL_FATAL_ERROR; + } +#endif /* WOLFSSL_DTLS13 */ } ssl->options.acceptState = TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE; diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 77adf8e30..2960b3acc 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -463,6 +463,7 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, WOLFSSL_BUFFER(prk, prkLen); WOLFSSL_MSG(" Info"); WOLFSSL_BUFFER(data, idx); + WOLFSSL_MSG_EX(" Digest %d", digest); #endif ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen); From d72edd03b8ad04b9e08c4940d434c718560f2ef3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jun 2022 16:58:45 +0200 Subject: [PATCH 03/11] dtls: wolfSSL_set_dtls_fd_connected wolfSSL_set_dtls_fd_connected sets the connected socket file descriptor. This descriptor should be called without addr and addr_len. --- src/ssl.c | 25 +++++++++++++++++++++++++ src/wolfio.c | 44 +++++++++++++++++++++++++++++++++++++------- wolfssl/internal.h | 3 +++ wolfssl/ssl.h | 1 + 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 82d7c9162..9782866fc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -890,6 +890,25 @@ int wolfSSL_set_fd(WOLFSSL* ssl, int fd) return ret; } +#ifdef WOLFSSL_DTLS +int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd) +{ + int ret; + + WOLFSSL_ENTER("SSL_set_dtls_fd_connected"); + + if (ssl == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_set_fd(ssl, fd); + if (ret == WOLFSSL_SUCCESS) + ssl->buffers.dtlsCtx.connected = 1; + + return ret; +} +#endif + int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd) { @@ -903,6 +922,7 @@ int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd) ssl->IOCB_ReadCtx = &ssl->rfd; #ifdef WOLFSSL_DTLS + ssl->buffers.dtlsCtx.connected = 0; if (ssl->options.dtls) { ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx; ssl->buffers.dtlsCtx.rfd = fd; @@ -926,6 +946,7 @@ int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd) ssl->IOCB_WriteCtx = &ssl->wfd; #ifdef WOLFSSL_DTLS + ssl->buffers.dtlsCtx.connected = 0; if (ssl->options.dtls) { ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx; ssl->buffers.dtlsCtx.wfd = fd; @@ -1188,6 +1209,8 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR); ssl->buffers.dtlsCtx.peer.sa = NULL; ssl->buffers.dtlsCtx.peer.sz = 0; + ssl->buffers.dtlsCtx.peer.bufSz = 0; + ssl->buffers.dtlsCtx.userSet = 0; return WOLFSSL_SUCCESS; } @@ -1200,6 +1223,8 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) XMEMCPY(sa, peer, peerSz); ssl->buffers.dtlsCtx.peer.sa = sa; ssl->buffers.dtlsCtx.peer.sz = peerSz; + ssl->buffers.dtlsCtx.peer.bufSz = peerSz; + ssl->buffers.dtlsCtx.userSet = 1; return WOLFSSL_SUCCESS; } return WOLFSSL_FAILURE; diff --git a/src/wolfio.c b/src/wolfio.c index 70c6217ca..d7c68fdb1 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -382,11 +382,35 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) int sd = dtlsCtx->rfd; int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); byte doDtlsTimeout; - SOCKADDR_S peer; - XSOCKLENT peerSz = sizeof(peer); + SOCKADDR_S lclPeer; + SOCKADDR_S* peer; + XSOCKLENT peerSz; WOLFSSL_ENTER("EmbedReceiveFrom()"); + if (dtlsCtx->connected) { + peer = NULL; + } + else if (dtlsCtx->userSet) { + peer = &lclPeer; + XMEMSET(&lclPeer, 0, sizeof(lclPeer)); + peerSz = sizeof(lclPeer); + } + else { + /* Store the peer address. It is used to calculate the DTLS cookie. */ + if (dtlsCtx->peer.sa == NULL) { + dtlsCtx->peer.sa = (void*)XMALLOC(sizeof(SOCKADDR_S), + ssl->heap, DYNAMIC_TYPE_SOCKADDR); + dtlsCtx->peer.sz = 0; + if (dtlsCtx->peer.sa != NULL) + dtlsCtx->peer.bufSz = sizeof(SOCKADDR_S); + else + dtlsCtx->peer.bufSz = 0; + } + peer = dtlsCtx->peer.sa; + peerSz = dtlsCtx->peer.bufSz; + } + /* Don't use ssl->options.handShakeDone since it is true even if * we are in the process of renegotiation */ doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE; @@ -443,10 +467,8 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) } #endif /* !NO_ASN_TIME */ - XMEMSET(&peer, 0, sizeof(peer)); - recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, - (SOCKADDR*)&peer, &peerSz); + (SOCKADDR*)peer, peer != NULL ? &peerSz : NULL); recvd = TranslateReturnCode(recvd, sd); @@ -459,15 +481,23 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) } return recvd; } - else { + else if (dtlsCtx->connected) { + /* Nothing to do */ + } + else if (dtlsCtx->userSet) { + /* Check we received the packet from the correct peer */ if (dtlsCtx->peer.sz > 0 && (peerSz != (XSOCKLENT)dtlsCtx->peer.sz || - !sockAddrEqual(&peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa, + !sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa, dtlsCtx->peer.sz))) { WOLFSSL_MSG(" Ignored packet from invalid peer"); return WOLFSSL_CBIO_ERR_WANT_READ; } } + else { + /* Store size of saved address */ + dtlsCtx->peer.sz = peerSz; + } #ifndef NO_ASN_TIME ssl->dtls_start_timeout = 0; #endif /* !NO_ASN_TIME */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index efaccc767..999f0e6a7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2219,6 +2219,7 @@ WOLFSSL_LOCAL int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, /* wolfSSL Sock Addr */ struct WOLFSSL_SOCKADDR { unsigned int sz; /* sockaddr size */ + unsigned int bufSz; /* sockaddr size */ void* sa; /* pointer to the sockaddr_in or sockaddr_in6 */ }; @@ -2226,6 +2227,8 @@ typedef struct WOLFSSL_DTLS_CTX { WOLFSSL_SOCKADDR peer; int rfd; int wfd; + byte userSet:1; + byte connected:1; /* Set when the rfd and wfd are connected sockets */ } WOLFSSL_DTLS_CTX; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 56be14ad0..2915b1ef9 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1045,6 +1045,7 @@ WOLFSSL_API int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PAR WOLFSSL_API int wolfSSL_is_server(WOLFSSL* ssl); WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_fd(WOLFSSL* ssl, int fd); +WOLFSSL_API int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd); WOLFSSL_API int wolfSSL_set_write_fd (WOLFSSL* ssl, int fd); WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL* ssl, int fd); WOLFSSL_API char* wolfSSL_get_cipher_list(int priority); From afdd5648aa13518e847fe3ba2a8654802696489e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jun 2022 16:28:56 +0200 Subject: [PATCH 04/11] Address code review --- src/ssl.c | 2 +- src/tls.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 9782866fc..53339b752 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12793,7 +12793,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #endif /* NO_WOLFSSL_SERVER */ -#ifdef WOLFSSL_DTLS +#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER) int wolfSSL_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx) { WOLFSSL_ENTER("wolfSSL_SetChGoodCb"); diff --git a/src/tls.c b/src/tls.c index af3f197db..c37e1d1a3 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6169,9 +6169,10 @@ static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length, extension = TLSX_Find(ssl->extensions, TLSX_COOKIE); if (extension == NULL) { #ifdef WOLFSSL_DTLS13 - if (ssl->options.dtls) - /* TODO: Should we allow a ClientHello with a valid cookie even if - * the cookie wasn't sent by this WOLFSSL object? */ + if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) + /* Allow a cookie extension with DTLS 1.3 because it is possible + * that a different SSL instance sent the cookie but we are now + * receiving it. */ return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0); else #endif From e605cfeccb697b9b5765f66b5786c2611c93507e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jun 2022 16:48:07 +0200 Subject: [PATCH 05/11] Add docs for new features --- doc/dox_comments/header_files/ssl.h | 45 +++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 203fd15c2..911ae3972 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -1597,6 +1597,43 @@ WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); */ int wolfSSL_set_fd (WOLFSSL* ssl, int fd); +/*! + \ingroup Setup + + \brief This function assigns a file descriptor (fd) as the + input/output facility for the SSL connection. Typically this will be + a socket file descriptor. This is a DTLS specific API because it marks that + the socket is connected. recvfrom and sendto calls on this fd will have the + addr and addr_len parameters set to NULL. + + \return SSL_SUCCESS upon success. + \return Bad_FUNC_ARG upon failure. + + \param ssl pointer to the SSL session, created with wolfSSL_new(). + \param fd file descriptor to use with SSL/TLS connection. + + _Example_ + \code + int sockfd; + WOLFSSL* ssl = 0; + ... + if (connect(sockfd, peer_addr, peer_addr_len) != 0) { + // handle connect error + } + ... + ret = wolfSSL_set_dtls_fd_connected(ssl, sockfd); + if (ret != SSL_SUCCESS) { + // failed to set SSL file descriptor + } + \endcode + + \sa wolfSSL_CTX_SetIOSend + \sa wolfSSL_CTX_SetIORecv + \sa wolfSSL_SetIOReadCtx + \sa wolfSSL_SetIOWriteCtx +*/ +int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd) + /*! \ingroup IO @@ -3521,9 +3558,11 @@ int wolfSSL_dtls(WOLFSSL* ssl); \return SSL_NOT_IMPLEMENTED will be returned if wolfSSL was not compiled with DTLS support. - \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). - \param peer pointer to peer’s sockaddr_in structure. - \param peerSz size of the sockaddr_in structure pointed to by peer. + \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). + \param peer pointer to peer’s sockaddr_in structure. If NULL then the peer + information in ssl is cleared. + \param peerSz size of the sockaddr_in structure pointed to by peer. If 0 + then the peer information in ssl is cleared. _Example_ \code From dd7073740b933fbb6e480659388ef8b0addce56d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jun 2022 16:58:41 +0200 Subject: [PATCH 06/11] DTLS 1.3: tie cookie to peer address --- src/tls13.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tls13.c b/src/tls13.c index b8ec8a130..b11515f44 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2832,6 +2832,13 @@ static int CreateCookie(WOLFSSL* ssl, byte* hash, byte hashSz) return ret; if ((ret = wc_HmacUpdate(&cookieHmac, hash, hashSz)) != 0) return ret; +#ifdef WOLFSSL_DTLS13 + /* Tie cookie to peer address */ + if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0 && + (ret = wc_HmacUpdate(&cookieHmac, ssl->buffers.dtlsCtx.peer.sa, + ssl->buffers.dtlsCtx.peer.sz)) != 0) + return ret; +#endif if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0) return ret; @@ -4775,6 +4782,13 @@ static int CheckCookie(WOLFSSL* ssl, byte* cookie, byte cookieSz) return ret; if ((ret = wc_HmacUpdate(&cookieHmac, cookie, cookieSz)) != 0) return ret; +#ifdef WOLFSSL_DTLS13 + /* Tie cookie to peer address */ + if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0 && + (ret = wc_HmacUpdate(&cookieHmac, ssl->buffers.dtlsCtx.peer.sa, + ssl->buffers.dtlsCtx.peer.sz)) != 0) + return ret; +#endif if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0) return ret; From 7ea13bf5bf4274cdab41a82705c26447593c2ffd Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 1 Jul 2022 17:52:12 +0200 Subject: [PATCH 07/11] Apply connected to sendto and address code review --- src/wolfio.c | 6 +++--- wolfssl/internal.h | 4 ++-- wolfssl/ssl.h | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wolfio.c b/src/wolfio.c index d7c68fdb1..b860f3d6f 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -407,7 +407,7 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) else dtlsCtx->peer.bufSz = 0; } - peer = dtlsCtx->peer.sa; + peer = (SOCKADDR_S*)dtlsCtx->peer.sa; peerSz = dtlsCtx->peer.bufSz; } @@ -518,8 +518,8 @@ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) WOLFSSL_ENTER("EmbedSendTo()"); sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, sz, ssl->wflags, - (const SOCKADDR*)dtlsCtx->peer.sa, - dtlsCtx->peer.sz); + !dtlsCtx->connected ? (const SOCKADDR*)dtlsCtx->peer.sa : NULL, + !dtlsCtx->connected ? dtlsCtx->peer.sz : 0); sent = TranslateReturnCode(sent, sd); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 999f0e6a7..606dc9d4b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2219,7 +2219,7 @@ WOLFSSL_LOCAL int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, /* wolfSSL Sock Addr */ struct WOLFSSL_SOCKADDR { unsigned int sz; /* sockaddr size */ - unsigned int bufSz; /* sockaddr size */ + unsigned int bufSz; /* size of allocated buffer */ void* sa; /* pointer to the sockaddr_in or sockaddr_in6 */ }; @@ -4481,7 +4481,7 @@ struct WOLFSSL { #ifdef WOLFSSL_STATIC_MEMORY WOLFSSL_HEAP_HINT heap_hint; #endif -#ifdef WOLFSSL_DTLS +#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER) ClientHelloGoodCb chGoodCb; /* notify user we parsed a verified * ClientHello */ void* chGoodCtx; /* user ClientHello cb context */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2915b1ef9..b35664d84 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1045,7 +1045,9 @@ WOLFSSL_API int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PAR WOLFSSL_API int wolfSSL_is_server(WOLFSSL* ssl); WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_fd(WOLFSSL* ssl, int fd); +#ifdef WOLFSSL_DTLS WOLFSSL_API int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd); +#endif WOLFSSL_API int wolfSSL_set_write_fd (WOLFSSL* ssl, int fd); WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL* ssl, int fd); WOLFSSL_API char* wolfSSL_get_cipher_list(int priority); From 00391a5acef83244d37b6e3b524048cbba7cecfe Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 1 Jul 2022 12:05:25 -0700 Subject: [PATCH 08/11] Rename callback to `wolfDTLS_SetChGoodCb` and add doxygen for it. Clarify `DTLS_CTX.connected`. Fix build errors for `./configure --enable-dtls --enable-dtls13 --disable-examples CFLAGS="-DNO_WOLFSSL_SERVER"`. --- doc/dox_comments/header_files/ssl.h | 33 ++++++++++++++++++++++++++++- src/dtls13.c | 2 ++ src/internal.c | 4 ++-- src/ssl.c | 4 ++-- wolfssl/internal.h | 5 ++++- wolfssl/ssl.h | 5 ++++- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 911ae3972..ad21ba203 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -1595,7 +1595,7 @@ WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); \sa wolfSSL_SetIOReadCtx \sa wolfSSL_SetIOWriteCtx */ -int wolfSSL_set_fd (WOLFSSL* ssl, int fd); +int wolfSSL_set_fd(WOLFSSL* ssl, int fd); /*! \ingroup Setup @@ -1631,9 +1631,40 @@ int wolfSSL_set_fd (WOLFSSL* ssl, int fd); \sa wolfSSL_CTX_SetIORecv \sa wolfSSL_SetIOReadCtx \sa wolfSSL_SetIOWriteCtx + \sa wolfDTLS_SetChGoodCb */ int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd) +/*! + \ingroup Setup + + \brief Allows setting a callback for DTLS client hello "good". + + \return SSL_SUCCESS upon success. + \return BAD_FUNC_ARG upon failure. + + \param ssl pointer to the SSL session, created with wolfSSL_new(). + \param fd file descriptor to use with SSL/TLS connection. + + _Example_ + \code + + // Called when we have verified a connection + static int chGoodCb(WOLFSSL* ssl, void* arg) + { + // setup peer and file descriptors + + } + + if (wolfDTLS_SetChGoodCb(ssl, chGoodCb, NULL) != WOLFSSL_SUCCESS) { + // error setting callback + } + \endcode + + \sa wolfSSL_set_dtls_fd_connected +*/ +int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx); + /*! \ingroup IO diff --git a/src/dtls13.c b/src/dtls13.c index 0954f6f8a..e46ef3c8e 100644 --- a/src/dtls13.c +++ b/src/dtls13.c @@ -331,6 +331,8 @@ static byte Dtls13RtxMsgNeedsAck(WOLFSSL* ssl, enum HandShakeType hs) message */ if (ssl->options.side == WOLFSSL_SERVER_END && (hs == finished)) return 1; +#else + (void)ssl; #endif /* NO_WOLFSSL_SERVER */ if (hs == session_ticket || hs == key_update) diff --git a/src/internal.c b/src/internal.c index f0b3f696d..6d5868847 100644 --- a/src/internal.c +++ b/src/internal.c @@ -554,7 +554,7 @@ int IsDtlsNotSctpMode(WOLFSSL* ssl) #endif } -#ifndef WOLFSSL_NO_TLS12 +#if !defined(WOLFSSL_NO_TLS12) && !defined(NO_WOLFSSL_SERVER) /* Secure Real-time Transport Protocol */ /* If SRTP is not enabled returns the state of the dtls option. * If SRTP is enabled returns dtls && !dtlsSrtpProfiles. */ @@ -566,7 +566,7 @@ static WC_INLINE int IsDtlsNotSrtpMode(WOLFSSL* ssl) return ssl->options.dtls; #endif } -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !WOLFSSL_NO_TLS12 && !NO_WOLFSSL_SERVER */ #endif /* WOLFSSL_DTLS */ diff --git a/src/ssl.c b/src/ssl.c index 53339b752..ead087c95 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12794,9 +12794,9 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #endif /* NO_WOLFSSL_SERVER */ #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER) -int wolfSSL_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx) +int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx) { - WOLFSSL_ENTER("wolfSSL_SetChGoodCb"); + WOLFSSL_ENTER("wolfDTLS_SetChGoodCb"); if (ssl == NULL) return BAD_FUNC_ARG; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 606dc9d4b..c91eb9499 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2228,7 +2228,10 @@ typedef struct WOLFSSL_DTLS_CTX { int rfd; int wfd; byte userSet:1; - byte connected:1; /* Set when the rfd and wfd are connected sockets */ + byte connected:1; /* When set indicates rfd and wfd sockets are + * connected (connect() and bind() both called). + * This means that sendto and recvfrom do not need to + * specify and store the peer address. */ } WOLFSSL_DTLS_CTX; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b35664d84..97d56a930 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3943,10 +3943,13 @@ WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx); #define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */ +#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER) /* notify user we parsed a verified ClientHello is done. This only has an effect * on the server end. */ typedef int (*ClientHelloGoodCb)(WOLFSSL* ssl, void*); -WOLFSSL_API int wolfSSL_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx); +WOLFSSL_API int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx); +#endif + /* notify user the handshake is done */ typedef int (*HandShakeDoneCb)(WOLFSSL* ssl, void*); WOLFSSL_API int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx); From a8adde66c84e867df104ff630e2fa711a60ddc40 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 4 Jul 2022 12:51:50 +0200 Subject: [PATCH 09/11] Use wc_HmacInit and wc_HmacFree in cookie logic --- src/tls13.c | 64 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index b11515f44..73a34e539 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2823,23 +2823,29 @@ static int CreateCookie(WOLFSSL* ssl, byte* hash, byte hashSz) cookieType = WC_SHA256; macSz = WC_SHA256_DIGEST_SIZE; #endif /* NO_SHA256 */ - XMEMSET(&cookieHmac, 0, sizeof(Hmac)); - ret = wc_HmacSetKey(&cookieHmac, cookieType, - ssl->buffers.tls13CookieSecret.buffer, - ssl->buffers.tls13CookieSecret.length); - if (ret != 0) - return ret; - if ((ret = wc_HmacUpdate(&cookieHmac, hash, hashSz)) != 0) - return ret; + ret = wc_HmacInit(&cookieHmac, ssl->heap, INVALID_DEVID); + if (ret == 0) { + ret = wc_HmacSetKey(&cookieHmac, cookieType, + ssl->buffers.tls13CookieSecret.buffer, + ssl->buffers.tls13CookieSecret.length); + } + if (ret == 0) + ret = wc_HmacUpdate(&cookieHmac, hash, hashSz); #ifdef WOLFSSL_DTLS13 /* Tie cookie to peer address */ - if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0 && - (ret = wc_HmacUpdate(&cookieHmac, ssl->buffers.dtlsCtx.peer.sa, - ssl->buffers.dtlsCtx.peer.sz)) != 0) - return ret; + if (ret == 0) { + if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0) { + ret = wc_HmacUpdate(&cookieHmac, ssl->buffers.dtlsCtx.peer.sa, + ssl->buffers.dtlsCtx.peer.sz); + } + } #endif - if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0) + if (ret == 0) + ret = wc_HmacFinal(&cookieHmac, mac); + + wc_HmacFree(&cookieHmac); + if (ret != 0) return ret; /* The cookie data is the hash and the integrity check. */ @@ -4773,23 +4779,29 @@ static int CheckCookie(WOLFSSL* ssl, byte* cookie, byte cookieSz) if (cookieSz < ssl->specs.hash_size + macSz) return HRR_COOKIE_ERROR; cookieSz -= macSz; - XMEMSET(&cookieHmac, 0, sizeof(Hmac)); - ret = wc_HmacSetKey(&cookieHmac, cookieType, - ssl->buffers.tls13CookieSecret.buffer, - ssl->buffers.tls13CookieSecret.length); - if (ret != 0) - return ret; - if ((ret = wc_HmacUpdate(&cookieHmac, cookie, cookieSz)) != 0) - return ret; + ret = wc_HmacInit(&cookieHmac, ssl->heap, INVALID_DEVID); + if (ret == 0) { + ret = wc_HmacSetKey(&cookieHmac, cookieType, + ssl->buffers.tls13CookieSecret.buffer, + ssl->buffers.tls13CookieSecret.length); + } + if (ret == 0) + ret = wc_HmacUpdate(&cookieHmac, cookie, cookieSz); #ifdef WOLFSSL_DTLS13 /* Tie cookie to peer address */ - if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0 && - (ret = wc_HmacUpdate(&cookieHmac, ssl->buffers.dtlsCtx.peer.sa, - ssl->buffers.dtlsCtx.peer.sz)) != 0) - return ret; + if (ret == 0) { + if (ssl->options.dtls && ssl->buffers.dtlsCtx.peer.sz > 0) { + ret = wc_HmacUpdate(&cookieHmac, ssl->buffers.dtlsCtx.peer.sa, + ssl->buffers.dtlsCtx.peer.sz); + } + } #endif - if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0) + if (ret == 0) + ret = wc_HmacFinal(&cookieHmac, mac); + + wc_HmacFree(&cookieHmac); + if (ret != 0) return ret; if (ConstantCompare(cookie + cookieSz, mac, macSz) != 0) From 10c8a1668e27d0a9c412666fe2fdf61b01bbcb98 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 4 Jul 2022 12:52:25 +0200 Subject: [PATCH 10/11] Reset cookie when resetting DTLS 1.3 state --- src/tls13.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tls13.c b/src/tls13.c index 73a34e539..e86026867 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -10834,6 +10834,8 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) ssl->keys.dtls_handshake_number = 0; ssl->msgsReceived.got_client_hello = 0; + /* Remove cookie so that it will get computed again */ + TLSX_Remove(&ssl->extensions, TLSX_COOKIE, ssl->heap); /* Reset states */ ssl->options.serverState = NULL_STATE; From 9dc2c27e3db60f6126f8c5d8645dd9f3310d0316 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 4 Jul 2022 14:31:24 +0200 Subject: [PATCH 11/11] Expand wolfDTLS_SetChGoodCb() docs --- doc/dox_comments/header_files/ssl.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index ad21ba203..729626be3 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -1638,7 +1638,19 @@ int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd) /*! \ingroup Setup - \brief Allows setting a callback for DTLS client hello "good". + \brief Allows setting a callback for a correctly processed and verified DTLS + client hello. When using a cookie exchange mechanism (either the + HelloVerifyRequest in DTLS 1.2 or the HelloRetryRequest with a cookie + extension in DTLS 1.3) this callback is called after the cookie + exchange has succeeded. This is useful to use one WOLFSSL object as + the listener for new connections and being able to isolate the + WOLFSSL object once the ClientHello is verified (either through a + cookie exchange or just checking if the ClientHello had the correct + format). + DTLS 1.2: + https://datatracker.ietf.org/doc/html/rfc6347#section-4.2.1 + DTLS 1.3: + https://www.rfc-editor.org/rfc/rfc8446#section-4.2.2 \return SSL_SUCCESS upon success. \return BAD_FUNC_ARG upon failure.