|
@@ -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;
|
|
|
-
|
|
|
- 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;
|
|
|
+ (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 != 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;
|