mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-31 06:59:16 +01:00
Merge pull request #6929 from julek-wolfssl/dtls13-early-data-server-side
dtls 1.3: allow to skip cookie exchange on resumption
This commit is contained in:
21
src/dtls.c
21
src/dtls.c
@@ -21,11 +21,13 @@
|
||||
|
||||
/*
|
||||
* WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||
* WOLFSSL_DTLS13_NO_HRR_ON_RESUME
|
||||
* If defined, a DTLS server will not do a cookie exchange on successful
|
||||
* client resumption: the resumption will be faster (one RTT less) and
|
||||
* will consume less bandwidth (one ClientHello and one HelloVerifyRequest
|
||||
* less). On the other hand, if a valid SessionID is collected, forged
|
||||
* clientHello messages will consume resources on the server.
|
||||
* will consume less bandwidth (one ClientHello and one
|
||||
* HelloVerifyRequest/HelloRetryRequest less). On the other hand, if a valid
|
||||
* SessionID/ticket/psk is collected, forged clientHello messages will
|
||||
* consume resources on the server.
|
||||
* WOLFSSL_DTLS_CH_FRAG
|
||||
* Allow a server to process a fragmented second/verified (one containing a
|
||||
* valid cookie response) ClientHello message. The first/unverified (one
|
||||
@@ -769,6 +771,15 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS13_NO_HRR_ON_RESUME
|
||||
if (ssl->options.dtls13NoHrrOnResume && usePSK && pskInfo.isValid &&
|
||||
!cs.doHelloRetry) {
|
||||
/* Skip HRR on resumption */
|
||||
((WOLFSSL*)ssl)->options.dtlsStateful = 1;
|
||||
goto dtls13_cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
if (cs.doHelloRetry) {
|
||||
ret = TLSX_KeyShare_SetSupported(ssl, &parsedExts);
|
||||
@@ -949,7 +960,7 @@ int DoClientHelloStateless(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
ret = COOKIE_ERROR;
|
||||
else
|
||||
#endif
|
||||
ret = SendStatelessReply((WOLFSSL*)ssl, &ch, isTls13);
|
||||
ret = SendStatelessReply(ssl, &ch, isTls13);
|
||||
}
|
||||
else {
|
||||
byte cookieGood;
|
||||
@@ -970,7 +981,7 @@ int DoClientHelloStateless(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
ret = COOKIE_ERROR;
|
||||
else
|
||||
#endif
|
||||
ret = SendStatelessReply((WOLFSSL*)ssl, &ch, isTls13);
|
||||
ret = SendStatelessReply(ssl, &ch, isTls13);
|
||||
}
|
||||
else {
|
||||
ssl->options.dtlsStateful = 1;
|
||||
|
||||
10
src/dtls13.c
10
src/dtls13.c
@@ -2844,5 +2844,15 @@ int wolfSSL_dtls13_allow_ch_frag(WOLFSSL *ssl, int enabled)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS13_NO_HRR_ON_RESUME
|
||||
int wolfSSL_dtls13_no_hrr_on_resume(WOLFSSL *ssl, int enabled)
|
||||
{
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
ssl->options.dtls13NoHrrOnResume = !!enabled;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
@@ -20185,20 +20185,8 @@ static int DtlsShouldDrop(WOLFSSL* ssl, int retcode)
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END
|
||||
&& ssl->curRL.type != handshake && !IsSCR(ssl)) {
|
||||
int beforeCookieVerified = 0;
|
||||
if (!IsAtLeastTLSv1_3(ssl->version)) {
|
||||
beforeCookieVerified =
|
||||
ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE;
|
||||
}
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
else {
|
||||
beforeCookieVerified =
|
||||
ssl->options.acceptState < TLS13_ACCEPT_SECOND_REPLY_DONE;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
if (beforeCookieVerified) {
|
||||
WOLFSSL_MSG("Drop non-handshake record before handshake");
|
||||
if (!ssl->options.dtlsStateful) {
|
||||
WOLFSSL_MSG("Drop non-handshake record when not stateful");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -34441,6 +34429,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
|
||||
if (cs.doHelloRetry) {
|
||||
/* Make sure we don't send HRR twice */
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE)
|
||||
return INVALID_PARAMETER;
|
||||
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
|
||||
return TLSX_KeyShare_SetSupported(ssl, &ssl->extensions);
|
||||
}
|
||||
|
||||
11
src/ssl.c
11
src/ssl.c
@@ -16793,11 +16793,13 @@ cleanup:
|
||||
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
|
||||
|
||||
/* return true if connection established */
|
||||
int wolfSSL_is_init_finished(WOLFSSL* ssl)
|
||||
int wolfSSL_is_init_finished(const WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl == NULL)
|
||||
return 0;
|
||||
|
||||
/* Can't use ssl->options.connectState and ssl->options.acceptState because
|
||||
* they differ in meaning for TLS <=1.2 and 1.3 */
|
||||
if (ssl->options.handShakeState == HANDSHAKE_DONE)
|
||||
return 1;
|
||||
|
||||
@@ -31970,12 +31972,7 @@ int wolfSSL_SSL_in_init(WOLFSSL *ssl)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_SSL_in_init");
|
||||
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
/* Can't use ssl->options.connectState and ssl->options.acceptState because
|
||||
* they differ in meaning for TLS <=1.2 and 1.3 */
|
||||
return ssl->options.handShakeState != HANDSHAKE_DONE;
|
||||
return !wolfSSL_is_init_finished(ssl);
|
||||
}
|
||||
|
||||
int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
|
||||
|
||||
78
src/tls13.c
78
src/tls13.c
@@ -6204,6 +6204,8 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
|
||||
return ret;
|
||||
|
||||
ssl->keys.encryptionOn = 1;
|
||||
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
if (ssl->options.dtls) {
|
||||
ret = Dtls13NewEpoch(ssl,
|
||||
@@ -6916,7 +6918,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
}
|
||||
else {
|
||||
ERROR_OUT(HRR_COOKIE_ERROR, exit_dch);
|
||||
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_DTLS13_NO_HRR_ON_RESUME)
|
||||
/* Don't error out as we may be resuming. We confirm this later. */
|
||||
if (!ssl->options.dtls)
|
||||
#endif
|
||||
ERROR_OUT(HRR_COOKIE_ERROR, exit_dch);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -6982,7 +6988,6 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
goto exit_dch;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
if (args->usingPSK == 2) {
|
||||
@@ -6990,6 +6995,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
int doHelloRetry = 0;
|
||||
ret = TLSX_KeyShare_Establish(ssl, &doHelloRetry);
|
||||
if (doHelloRetry) {
|
||||
/* Make sure we don't send HRR twice */
|
||||
if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE)
|
||||
ERROR_OUT(INVALID_PARAMETER, exit_dch);
|
||||
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
|
||||
if (ret != WC_PENDING_E)
|
||||
ret = 0; /* for hello_retry return 0 */
|
||||
@@ -7082,32 +7090,58 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
ret = INPUT_CASE_ERROR;
|
||||
} /* switch (ssl->options.asyncState) */
|
||||
|
||||
#if defined(WOLFSSL_SEND_HRR_COOKIE)
|
||||
if (ret == 0 && ssl->options.sendCookie && ssl->options.cookieGood &&
|
||||
(ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* DTLS cookie exchange should be done in stateless code in
|
||||
* DoClientHelloStateless. If we verified the cookie then
|
||||
* always advance the state. */
|
||||
|| ssl->options.dtls
|
||||
#endif
|
||||
))
|
||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SEND_HRR_COOKIE
|
||||
if (ret == 0 && ssl->options.sendCookie) {
|
||||
if (ssl->options.cookieGood &&
|
||||
ssl->options.acceptState == TLS13_ACCEPT_FIRST_REPLY_DONE) {
|
||||
/* Processing second ClientHello. Clear HRR state. */
|
||||
ssl->options.serverState = NULL_STATE;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
|
||||
if (ret == 0 && ssl->options.dtls && ssl->options.sendCookie &&
|
||||
ssl->options.serverState <= SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
||||
/* Cookie and key share negotiation should be handled in
|
||||
* DoClientHelloStateless. If we enter here then something went wrong
|
||||
* in our logic. */
|
||||
ERROR_OUT(BAD_HELLO, exit_dch);
|
||||
if (ssl->options.cookieGood &&
|
||||
ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
||||
/* If we already verified the peer with a cookie then we can't
|
||||
* do another HRR for cipher negotiation. Send alert and restart
|
||||
* the entire handshake. */
|
||||
ERROR_OUT(INVALID_PARAMETER, exit_dch);
|
||||
}
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
if (ssl->options.dtls &&
|
||||
ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
||||
/* Cookie and key share negotiation should be handled in
|
||||
* DoClientHelloStateless. If we enter here then something went
|
||||
* wrong in our logic. */
|
||||
ERROR_OUT(BAD_HELLO, exit_dch);
|
||||
}
|
||||
#endif
|
||||
/* Send a cookie */
|
||||
if (!ssl->options.cookieGood &&
|
||||
ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
if (ssl->options.dtls) {
|
||||
#ifdef WOLFSSL_DTLS13_NO_HRR_ON_RESUME
|
||||
/* We can skip cookie on resumption */
|
||||
if (!ssl->options.dtls || !ssl->options.dtls13NoHrrOnResume ||
|
||||
!args->usingPSK)
|
||||
#endif
|
||||
ERROR_OUT(BAD_HELLO, exit_dch);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Need to remove the keyshare ext if we found a common group
|
||||
* and are not doing curve negotiation. */
|
||||
TLSX_Remove(&ssl->extensions, TLSX_KEY_SHARE, ssl->heap);
|
||||
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
#ifdef WOLFSSL_DTLS_CID
|
||||
/* do not modify CID state if we are sending an HRR */
|
||||
if (ssl->options.useDtlsCID &&
|
||||
if (ret == 0 && ssl->options.dtls && ssl->options.useDtlsCID &&
|
||||
ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE)
|
||||
DtlsCIDOnExtensionsParsed(ssl);
|
||||
#endif /* WOLFSSL_DTLS_CID */
|
||||
|
||||
Reference in New Issue
Block a user