Disallow upgrading to TLS v1.3

Change SupportedVersions extension to only include TLS v1.3 if downgrade
is disabled.
Fix parsing of SupportedVersions extension
Don't upgrade
Only downgrade in SupportedVersions extension if option enabled
This commit is contained in:
Sean Parkinson
2017-10-16 13:59:24 +10:00
parent 130e026139
commit 9e4e58fe8c
3 changed files with 37 additions and 32 deletions

View File

@ -379,7 +379,7 @@ create_port
./examples/client/client -v 4 -p $port ./examples/client/client -v 4 -p $port
RESULT=$? RESULT=$?
remove_ready_file remove_ready_file
if [ $RESULT -ne 0 ]; then if [ $RESULT -eq 0 ]; then
echo -e "\n\nIssue with TLS v1.3 client upgrading server to TLS v1.3" echo -e "\n\nIssue with TLS v1.3 client upgrading server to TLS v1.3"
do_cleanup do_cleanup
exit 1 exit 1

View File

@ -22776,13 +22776,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
if (TLSX_Find(ssl->extensions, if (TLSX_Find(ssl->extensions,
TLSX_SUPPORTED_VERSIONS) != NULL) { TLSX_SUPPORTED_VERSIONS) != NULL) {
TLSX_FreeAll(ssl->extensions, ssl->heap); WOLFSSL_MSG(
ssl->extensions = NULL; "Client attempting to connect with higher version");
ssl->version.minor = TLSv1_3_MINOR; return VERSION_ERROR;
*inOutIdx = begin;
if ((ret = InitHandshakeHashes(ssl)) != 0)
return ret;
return DoTls13ClientHello(ssl, input, inOutIdx, helloSz);
} }
#endif #endif
#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) #if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)

View File

@ -4308,7 +4308,7 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
*/ */
static word16 TLSX_SupportedVersions_GetSize(void* data) static word16 TLSX_SupportedVersions_GetSize(void* data)
{ {
(void)data; WOLFSSL* ssl = (WOLFSSL*)data;
/* TLS v1.2 and TLS v1.3 */ /* TLS v1.2 and TLS v1.3 */
int cnt = 2; int cnt = 2;
@ -4318,6 +4318,9 @@ static word16 TLSX_SupportedVersions_GetSize(void* data)
cnt += 2; cnt += 2;
#endif #endif
if (!ssl->options.downgrade)
cnt = 1;
return OPAQUE8_LEN + cnt * OPAQUE16_LEN; return OPAQUE8_LEN + cnt * OPAQUE16_LEN;
} }
@ -4340,6 +4343,9 @@ static word16 TLSX_SupportedVersions_Write(void* data, byte* output)
cnt += 2; cnt += 2;
#endif #endif
if (!ssl->options.downgrade)
cnt = 1;
*(output++) = cnt * OPAQUE16_LEN; *(output++) = cnt * OPAQUE16_LEN;
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */ /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
@ -4370,8 +4376,9 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
{ {
ProtocolVersion pv = ssl->ctx->method->version; ProtocolVersion pv = ssl->ctx->method->version;
int i; int i;
int ret = 0; int ret = VERSION_ERROR;
int len; int len;
byte major, minor;
/* Must contain a length and at least one version. */ /* Must contain a length and at least one version. */
if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1) if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1)
@ -4387,39 +4394,41 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
/* Find first match. */ /* Find first match. */
for (i = 0; i < len; i += OPAQUE16_LEN) { for (i = 0; i < len; i += OPAQUE16_LEN) {
major = input[i];
minor = input[i + OPAQUE8_LEN];
/* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */ /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
if (input[i] == TLS_DRAFT_MAJOR && if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
input[i + OPAQUE8_LEN] == TLS_DRAFT_MINOR) { major = SSLv3_MAJOR;
ssl->version.minor = TLSv1_3_MINOR; minor = TLSv1_3_MINOR;
ssl->options.tls1_3 = 1;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
ssl->heap);
break;
} }
if (input[i] != pv.major) if (major != pv.major)
continue; continue;
#ifndef NO_OLD_TLS /* No upgrade allowed. */
if (input[i + OPAQUE8_LEN] == TLSv1_MINOR || if (ssl->version.minor > minor)
input[i + OPAQUE8_LEN] == TLSv1_1_MINOR) { continue;
ssl->version.minor = input[i + OPAQUE8_LEN]; /* Check downgrade. */
break; if (ssl->version.minor < minor) {
} if (!ssl->options.downgrade)
continue;
#ifdef NO_OLD_TLS
if (minor < TLSv1_2_MINOR)
continue;
#endif #endif
if (input[i + OPAQUE8_LEN] == TLSv1_2_MINOR) { /* Downgrade the version. */
ssl->version.minor = input[i + OPAQUE8_LEN]; ssl->version.minor = minor;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
ssl->heap);
break;
} }
if (input[i + OPAQUE8_LEN] == TLSv1_3_MINOR) {
ssl->version.minor = input[i + OPAQUE8_LEN]; if (minor >= TLSv1_3_MINOR) {
ssl->options.tls1_3 = 1; ssl->options.tls1_3 = 1;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input, TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
ssl->heap); ssl->heap);
break;
} }
ret = 0;
break;
} }
return ret; return ret;