mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #1390 from SparkiDev/tls13_downgrade
Fix downgrading from TLS v1.3 to TLS v1.2pull/1388/head
commit
41ae47fa3c
|
@ -1027,6 +1027,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||
break;
|
||||
|
||||
case 'v' :
|
||||
if (myoptarg[0] == 'd') {
|
||||
version = CLIENT_DOWNGRADE_VERSION;
|
||||
break;
|
||||
}
|
||||
version = atoi(myoptarg);
|
||||
if (version < 0 || version > 4) {
|
||||
Usage();
|
||||
|
@ -1414,6 +1418,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
|||
method = wolfTLSv1_3_client_method_ex;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CLIENT_DOWNGRADE_VERSION:
|
||||
method = wolfSSLv23_client_method_ex;
|
||||
break;
|
||||
#endif /* NO_TLS */
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
|
|
|
@ -643,6 +643,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||
break;
|
||||
|
||||
case 'v' :
|
||||
if (myoptarg[0] == 'd') {
|
||||
version = SERVER_DOWNGRADE_VERSION;
|
||||
break;
|
||||
}
|
||||
version = atoi(myoptarg);
|
||||
if (version < 0 || version > 4) {
|
||||
Usage();
|
||||
|
@ -893,6 +897,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||
method = wolfTLSv1_3_server_method_ex;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SERVER_DOWNGRADE_VERSION:
|
||||
method = wolfSSLv23_server_method_ex;
|
||||
break;
|
||||
#endif /* NO_TLS */
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
|
|
|
@ -373,6 +373,22 @@ if [ $RESULT -eq 0 ]; then
|
|||
fi
|
||||
echo ""
|
||||
|
||||
# TLS Downgrade server / TLS 1.2 client.
|
||||
echo -e "\n\nTLS server downgrading to TLS v1.2"
|
||||
port=0
|
||||
./examples/server/server -v d -R $ready_file -p $port &
|
||||
server_pid=$!
|
||||
create_port
|
||||
./examples/client/client -v 3 -p $port
|
||||
RESULT=$?
|
||||
remove_ready_file
|
||||
if [ $RESULT -ne 0 ]; then
|
||||
echo -e "\n\nIssue with TLS server downgrading to TLS v1.2"
|
||||
do_cleanup
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# TLS 1.2 server / TLS 1.3 client.
|
||||
echo -e "\n\nTLS v1.3 client upgrading server to TLS v1.3"
|
||||
port=0
|
||||
|
@ -389,6 +405,22 @@ if [ $RESULT -eq 0 ]; then
|
|||
fi
|
||||
echo ""
|
||||
|
||||
# TLS 1.2 server / TLS downgrade client.
|
||||
echo -e "\n\nTLS client downgrading to TLS v1.2"
|
||||
port=0
|
||||
./examples/server/server -v 3 -R $ready_file -p $port &
|
||||
server_pid=$!
|
||||
create_port
|
||||
./examples/client/client -v d -p $port
|
||||
RESULT=$?
|
||||
remove_ready_file
|
||||
if [ $RESULT -ne 0 ]; then
|
||||
echo -e "\n\nIssue with TLS client downgrading to TLS v1.2"
|
||||
do_cleanup
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# TLS 1.3 server / TLS 1.3 client send KeyUpdate before sending app data.
|
||||
echo -e "\n\nTLS v1.3 KeyUpdate"
|
||||
port=0
|
||||
|
|
|
@ -17431,6 +17431,13 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
|||
}
|
||||
#endif /* HAVE_SECRET_CALLBACK */
|
||||
|
||||
return CompleteServerHello(ssl);
|
||||
}
|
||||
|
||||
int CompleteServerHello(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ssl->options.resuming) {
|
||||
if (DSH_CheckSessionId(ssl)) {
|
||||
if (SetCipherSpecs(ssl) == 0) {
|
||||
|
|
|
@ -4679,6 +4679,13 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
|
|||
if (major != pv.major)
|
||||
return VERSION_ERROR;
|
||||
|
||||
/* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
|
||||
if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR &&
|
||||
minor >= TLSv1_3_MINOR) {
|
||||
/* Set minor version back to TLS v1.3+ */
|
||||
ssl->version.minor = ssl->ctx->method->version.minor;
|
||||
}
|
||||
|
||||
/* No upgrade allowed. */
|
||||
if (ssl->version.minor < minor)
|
||||
return VERSION_ERROR;
|
||||
|
@ -8062,7 +8069,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
|||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET)
|
||||
if (ssl->options.resuming) {
|
||||
if (ssl->options.resuming && ssl->session.ticketLen > 0) {
|
||||
WOLFSSL_SESSION* sess = &ssl->session;
|
||||
word32 milli;
|
||||
|
||||
|
|
116
src/tls13.c
116
src/tls13.c
|
@ -2605,6 +2605,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
int ret;
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
byte sessIdSz;
|
||||
const byte* sessId;
|
||||
byte b;
|
||||
#endif
|
||||
word16 totalExtSz;
|
||||
|
@ -2668,35 +2669,18 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
sessIdSz = input[i++];
|
||||
if ((i - begin) + sessIdSz > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
|
||||
if (sessIdSz == 0)
|
||||
return INVALID_PARAMETER;
|
||||
if (ssl->session.sessionIDSz != 0) {
|
||||
if (ssl->session.sessionIDSz != sessIdSz ||
|
||||
XMEMCMP(ssl->session.sessionID, input + i, sessIdSz) != 0) {
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else if (XMEMCMP(ssl->arrays->clientRandom, input + i, sessIdSz) != 0)
|
||||
return INVALID_PARAMETER;
|
||||
#else
|
||||
if (sessIdSz != ssl->session.sessionIDSz || (sessIdSz > 0 &&
|
||||
XMEMCMP(ssl->session.sessionID, input + i, sessIdSz) != 0)) {
|
||||
WOLFSSL_MSG("Server sent different session id");
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
|
||||
sessId = input + i;
|
||||
i += sessIdSz;
|
||||
ssl->options.haveSessionId = 1;
|
||||
#endif /* WOLFSSL_TLS13_DRAFT_18 */
|
||||
ssl->options.haveSessionId = 1;
|
||||
|
||||
#ifdef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Ciphersuite and extensions length check */
|
||||
/* Ciphersuite check */
|
||||
if ((i - begin) + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#else
|
||||
/* Ciphersuite, compression and extensions length check */
|
||||
if ((i - begin) + OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
|
||||
/* Ciphersuite and compression check */
|
||||
if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#endif
|
||||
|
||||
|
@ -2713,18 +2697,33 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Get extension length and length check. */
|
||||
ato16(&input[i], &totalExtSz);
|
||||
i += OPAQUE16_LEN;
|
||||
if ((i - begin) + totalExtSz > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
if ((i - begin) + OPAQUE16_LEN > helloSz) {
|
||||
if (!ssl->options.downgrade)
|
||||
return BUFFER_ERROR;
|
||||
ssl->version.minor = TLSv1_2_MINOR;
|
||||
ssl->options.haveEMS = 0;
|
||||
}
|
||||
if ((i - begin) < helloSz)
|
||||
#endif
|
||||
{
|
||||
/* Get extension length and length check. */
|
||||
ato16(&input[i], &totalExtSz);
|
||||
i += OPAQUE16_LEN;
|
||||
if ((i - begin) + totalExtSz > helloSz)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
/* Parse and handle extensions. */
|
||||
ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, extMsgType, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
if (ssl->options.downgrade)
|
||||
ssl->version.minor = TLSv1_2_MINOR;
|
||||
#endif
|
||||
/* Parse and handle extensions. */
|
||||
ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, extMsgType, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
i += totalExtSz;
|
||||
i += totalExtSz;
|
||||
}
|
||||
*inOutIdx = i;
|
||||
|
||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||
|
@ -2739,6 +2738,51 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
}
|
||||
#endif /* HAVE_SECRET_CALLBACK */
|
||||
|
||||
#ifndef WOLFSSL_TLS13_DRAFT_18
|
||||
/* Version only negotiated in extensions for TLS v1.3.
|
||||
* Only now do we know how to deal with session id.
|
||||
*/
|
||||
if (!IsAtLeastTLSv1_3(ssl->version)) {
|
||||
ssl->arrays->sessionIDSz = sessIdSz;
|
||||
|
||||
if (ssl->arrays->sessionIDSz > ID_LEN) {
|
||||
WOLFSSL_MSG("Invalid session ID size");
|
||||
ssl->arrays->sessionIDSz = 0;
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
else if (ssl->arrays->sessionIDSz) {
|
||||
XMEMCPY(ssl->arrays->sessionID, sessId, ssl->arrays->sessionIDSz);
|
||||
ssl->options.haveSessionId = 1;
|
||||
}
|
||||
|
||||
/* Complete TLS v1.2 processing of ServerHello. */
|
||||
ret = CompleteServerHello(ssl);
|
||||
|
||||
WOLFSSL_LEAVE("DoTls13ServerHello", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
|
||||
if (sessIdSz == 0)
|
||||
return INVALID_PARAMETER;
|
||||
if (ssl->session.sessionIDSz != 0) {
|
||||
if (ssl->session.sessionIDSz != sessIdSz ||
|
||||
XMEMCMP(ssl->session.sessionID, sessId, sessIdSz) != 0) {
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else if (XMEMCMP(ssl->arrays->clientRandom, sessId, sessIdSz) != 0)
|
||||
return INVALID_PARAMETER;
|
||||
#else
|
||||
if (sessIdSz != ssl->session.sessionIDSz || (sessIdSz > 0 &&
|
||||
XMEMCMP(ssl->session.sessionID, sessId, sessIdSz) != 0)) {
|
||||
WOLFSSL_MSG("Server sent different session id");
|
||||
return INVALID_PARAMETER;
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
|
||||
#endif
|
||||
|
||||
ret = SetCipherSpecs(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
@ -3173,6 +3217,9 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
|||
break;
|
||||
}
|
||||
|
||||
if (current == NULL)
|
||||
return 0;
|
||||
|
||||
/* Hash the rest of the ClientHello. */
|
||||
ret = HashInputRaw(ssl, input + helloSz - bindersLen, bindersLen);
|
||||
if (ret != 0)
|
||||
|
@ -3567,10 +3614,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STUNNEL
|
||||
#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
|
||||
if ((ret = SNI_Callback(ssl)) != 0)
|
||||
return ret;
|
||||
#endif /*HAVE_STUNNEL*/
|
||||
ssl->options.side = WOLFSSL_SERVER_END;
|
||||
#endif /* HAVE_STUNNELi || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
|
||||
|
||||
if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) {
|
||||
if (!ssl->options.downgrade) {
|
||||
|
|
|
@ -1481,6 +1481,7 @@ WOLFSSL_LOCAL int DoTls13ClientHello(WOLFSSL* ssl, const byte* input,
|
|||
#endif
|
||||
WOLFSSL_LOCAL int DoServerHello(WOLFSSL* ssl, const byte* input, word32*,
|
||||
word32);
|
||||
WOLFSSL_LOCAL int CompleteServerHello(WOLFSSL *ssl);
|
||||
WOLFSSL_LOCAL int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv);
|
||||
WOLFSSL_LOCAL void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
|
||||
word32 hashSigAlgoSz);
|
||||
|
|
|
@ -234,9 +234,11 @@
|
|||
#define SERVER_DEFAULT_VERSION 3
|
||||
#define SERVER_DTLS_DEFAULT_VERSION (-2)
|
||||
#define SERVER_INVALID_VERSION (-99)
|
||||
#define SERVER_DOWNGRADE_VERSION (-98)
|
||||
#define CLIENT_DEFAULT_VERSION 3
|
||||
#define CLIENT_DTLS_DEFAULT_VERSION (-2)
|
||||
#define CLIENT_INVALID_VERSION (-99)
|
||||
#define CLIENT_DOWNGRADE_VERSION (-98)
|
||||
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
|
||||
#define DEFAULT_MIN_DHKEY_BITS 2048
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue