Fix for downgrading from TLS 1.3 due to old cipher suite

TLS 1.3 specification doesn't allow downgrading based on cipher suite.
This commit is contained in:
Sean Parkinson 2018-06-01 10:41:45 +10:00
parent 70b3ba1c04
commit fcd2234841
4 changed files with 86 additions and 72 deletions

View File

@ -137,6 +137,38 @@ if [ $? -ne 0 ]; then
exit 1
fi
echo ""
echo "Find usable TLS 1.2 cipher suite"
for CS in ECDHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256
do
echo $CS
./examples/client/client -e | grep $CS >/dev/null
if [ "$?" = "0" ]; then
TLS12_CS=$CS
break
fi
done
if [ "$TLS12_CS" != "" ]; then
# TLS 1.3 downgrade server and client - no common TLS 1.3 ciphers
echo -e "\n\nTLS v1.3 downgrade server and client - no common TLS 1.3 ciphers"
port=0
SERVER_CS="TLS13-AES256-GCM-SHA384:$TLS12_CS"
CLIENT_CS="TLS13-AES128-GCM-SHA256:$TLS12_CS"
./examples/server/server -v d -l $SERVER_CS -R $ready_file -p $port &
server_pid=$!
create_port
./examples/client/client -v d -l $CLIENT_CS -p $port
RESULT=$?
remove_ready_file
if [ $RESULT -eq 0 ]; then
echo -e "\n\nTLS v1.3 downgrading to TLS v1.2 due to ciphers"
do_cleanup
exit 1
fi
echo ""
else
echo "No usable TLS 1.2 cipher suite found"
fi
fi
echo -e "\nALL Tests Passed"

View File

@ -16868,36 +16868,6 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
i += RAN_LEN;
if (!ssl->options.resuming) {
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
/* TLS v1.3 capable client not allowed to downgrade when
* connecting to TLS v1.3 capable server unless cipher suite
* demands it.
*/
if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1),
tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
(*(input + i - 1) == 0 || *(input + i - 1) == 1)) {
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
}
}
else
#endif
if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
ssl->ctx->method->version.minor == TLSv1_2_MINOR) {
/* TLS v1.2 capable client not allowed to downgrade when
* connecting to TLS v1.2 capable server.
*/
if (XMEMCMP(input + i - (TLS13_DOWNGRADE_SZ + 1),
tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
*(input + i - 1) == 0) {
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
}
}
}
/* session id */
ssl->arrays->sessionIDSz = input[i++];
@ -17066,7 +17036,37 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
{
int ret;
if (ssl->options.resuming) {
if (!ssl->options.resuming) {
byte* down = ssl->arrays->serverRandom + RAN_LEN -
TLS13_DOWNGRADE_SZ - 1;
byte vers = ssl->arrays->serverRandom[RAN_LEN - 1];
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
/* TLS v1.3 capable client not allowed to downgrade when
* connecting to TLS v1.3 capable server unless cipher suite
* demands it.
*/
if (XMEMCMP(down, tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
(vers == 0 || vers == 1)) {
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
}
}
else
#endif
if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
ssl->ctx->method->version.minor == TLSv1_2_MINOR) {
/* TLS v1.2 capable client not allowed to downgrade when
* connecting to TLS v1.2 capable server.
*/
if (XMEMCMP(down, tls13Downgrade, TLS13_DOWNGRADE_SZ) == 0 &&
vers == 0) {
SendAlert(ssl, alert_fatal, illegal_parameter);
return VERSION_ERROR;
}
}
}
else {
if (DSH_CheckSessionId(ssl)) {
if (SetCipherSpecs(ssl) == 0) {
@ -17097,11 +17097,11 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
ssl->options.resuming = 0; /* server denied resumption try */
}
}
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
DtlsMsgPoolReset(ssl);
}
#endif
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
DtlsMsgPoolReset(ssl);
}
#endif
return SetCipherSpecs(ssl);
}
@ -23461,7 +23461,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->output, args->sigSz,
HashAlgoToType(args->hashAlgo));
if (ret != 0)
return ret;
goto exit_dcv;
}
else
#endif

View File

@ -4810,34 +4810,38 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input,
continue;
/* No upgrade allowed. */
if (ssl->version.minor > minor)
if (minor > ssl->version.minor)
continue;
/* Check downgrade. */
if (ssl->version.minor < minor) {
if (minor < ssl->version.minor) {
if (!ssl->options.downgrade)
continue;
if (minor < ssl->options.minDowngrade)
continue;
/* Downgrade the version. */
ssl->version.minor = minor;
if (newMinor == 0 && minor > ssl->options.oldMinor) {
/* Downgrade the version. */
ssl->version.minor = minor;
}
}
if (minor >= TLSv1_3_MINOR) {
ssl->options.tls1_3 = 1;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl,
ssl->heap);
if (!ssl->options.tls1_3) {
ssl->options.tls1_3 = 1;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl,
ssl->heap);
#ifndef WOLFSSL_TLS13_DRAFT_18
TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
#endif
newMinor = minor;
}
if (minor > newMinor) {
ssl->version.minor = minor;
newMinor = minor;
}
}
else if (ssl->options.oldMinor < minor)
else if (minor > ssl->options.oldMinor)
ssl->options.oldMinor = minor;
if (newMinor != 0 && ssl->options.oldMinor != 0)
break;
}
}
#ifndef WOLFSSL_TLS13_DRAFT_18

View File

@ -3972,31 +3972,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Check that the negotiated ciphersuite matches protocol version. */
if (IsAtLeastTLSv1_3(ssl->version)) {
if (ssl->options.cipherSuite0 != TLS13_BYTE) {
#ifndef WOLFSSL_NO_TLS12
TLSX* ext;
if (!ssl->options.downgrade) {
WOLFSSL_MSG("Negotiated ciphersuite from lesser version "
"than TLS v1.3");
return VERSION_ERROR;
}
WOLFSSL_MSG("Downgrading protocol due to cipher suite");
if (pv.minor < ssl->options.minDowngrade)
return VERSION_ERROR;
ssl->version.minor = ssl->options.oldMinor;
/* Downgrade from TLS v1.3 */
ssl->options.tls1_3 = 0;
ext = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS);
if (ext != NULL)
ext->resp = 0;
#else
WOLFSSL_MSG("Negotiated ciphersuite from lesser version than "
"TLS v1.3");
return VERSION_ERROR;
#endif
}
}
/* VerifyServerSuite handles when version is less than 1.3 */