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
RESULT=$?
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"
do_cleanup
exit 1

View File

@ -22776,13 +22776,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_TLS13
if (TLSX_Find(ssl->extensions,
TLSX_SUPPORTED_VERSIONS) != NULL) {
TLSX_FreeAll(ssl->extensions, ssl->heap);
ssl->extensions = NULL;
ssl->version.minor = TLSv1_3_MINOR;
*inOutIdx = begin;
if ((ret = InitHandshakeHashes(ssl)) != 0)
return ret;
return DoTls13ClientHello(ssl, input, inOutIdx, helloSz);
WOLFSSL_MSG(
"Client attempting to connect with higher version");
return VERSION_ERROR;
}
#endif
#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)
{
(void)data;
WOLFSSL* ssl = (WOLFSSL*)data;
/* TLS v1.2 and TLS v1.3 */
int cnt = 2;
@ -4318,6 +4318,9 @@ static word16 TLSX_SupportedVersions_GetSize(void* data)
cnt += 2;
#endif
if (!ssl->options.downgrade)
cnt = 1;
return OPAQUE8_LEN + cnt * OPAQUE16_LEN;
}
@ -4340,6 +4343,9 @@ static word16 TLSX_SupportedVersions_Write(void* data, byte* output)
cnt += 2;
#endif
if (!ssl->options.downgrade)
cnt = 1;
*(output++) = cnt * OPAQUE16_LEN;
for (i = 0; i < cnt; i++) {
/* 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;
int i;
int ret = 0;
int ret = VERSION_ERROR;
int len;
byte major, minor;
/* Must contain a length and at least one version. */
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. */
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. */
if (input[i] == TLS_DRAFT_MAJOR &&
input[i + OPAQUE8_LEN] == TLS_DRAFT_MINOR) {
ssl->version.minor = TLSv1_3_MINOR;
ssl->options.tls1_3 = 1;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
ssl->heap);
break;
if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
major = SSLv3_MAJOR;
minor = TLSv1_3_MINOR;
}
if (input[i] != pv.major)
if (major != pv.major)
continue;
#ifndef NO_OLD_TLS
if (input[i + OPAQUE8_LEN] == TLSv1_MINOR ||
input[i + OPAQUE8_LEN] == TLSv1_1_MINOR) {
ssl->version.minor = input[i + OPAQUE8_LEN];
break;
}
/* No upgrade allowed. */
if (ssl->version.minor > minor)
continue;
/* Check downgrade. */
if (ssl->version.minor < minor) {
if (!ssl->options.downgrade)
continue;
#ifdef NO_OLD_TLS
if (minor < TLSv1_2_MINOR)
continue;
#endif
if (input[i + OPAQUE8_LEN] == TLSv1_2_MINOR) {
ssl->version.minor = input[i + OPAQUE8_LEN];
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
ssl->heap);
break;
/* Downgrade the version. */
ssl->version.minor = minor;
}
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;
TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, input,
ssl->heap);
break;
}
ret = 0;
break;
}
return ret;