From 1d05503d203b1af1f05710b039f1ea89a6aa9f5f Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 1 Jul 2019 12:20:37 +1000 Subject: [PATCH] TLS 1.3 extension fixes When major version is TLS Draft then this is now ignored. If version negotitation occurs but none matched then send an alert and return an error. Store the rsa_pss_pss_* signature algorithms in the bit mask. KeyShare Entry parsing returns INVALID_PARAMETER when length is 0 and results in a different alert being sent. Check negotiated protocol version is not TLS 1.3 when determing whether to parse point formats. --- src/tls.c | 22 ++++++++++++++++++++-- wolfssl/internal.h | 18 ++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/tls.c b/src/tls.c index d6b90114b..c5c500523 100644 --- a/src/tls.c +++ b/src/tls.c @@ -5711,6 +5711,7 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input, int len; byte major, minor; int newMinor = 0; + int set = 0; if (msgType == client_hello) { /* Must contain a length and at least one version. */ @@ -5735,6 +5736,9 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input, major = SSLv3_MAJOR; minor = TLSv1_3_MINOR; } +#else + if (major == TLS_DRAFT_MAJOR) + continue; #endif if (major != pv.major) @@ -5773,6 +5777,12 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input, } else if (minor > ssl->options.oldMinor) ssl->options.oldMinor = minor; + + set = 1; + } + if (!set) { + SendAlert(ssl, alert_fatal, protocol_version); + return VERSION_ERROR; } } #ifndef WOLFSSL_TLS13_DRAFT_18 @@ -6061,6 +6071,12 @@ static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, byte* input, for (i = 0; i < length; i += 2) { if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac) ssl->pssAlgo |= 1 << input[i + 1]; + #ifdef WOLFSSL_TLS13 + if (input[i] == rsa_pss_sa_algo && input[i + 1] >= pss_sha256 && + input[i + 1] <= pss_sha512) { + ssl->pssAlgo |= 1 << input[i + 1]; + } + #endif } return 0; @@ -7076,7 +7092,9 @@ static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length, /* Key exchange data - public key. */ ato16(&input[offset], &keLen); offset += OPAQUE16_LEN; - if (keLen < 1 || keLen > length - offset) + if (keLen == 0) + return INVALID_PARAMETER; + if (keLen > length - offset) return BUFFER_ERROR; /* Store a copy in the key share object. */ @@ -10353,7 +10371,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, WOLFSSL_MSG("Point Formats extension received"); #ifdef WOLFSSL_TLS13 - if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) + if (IsAtLeastTLSv1_3(ssl->version)) break; #endif ret = PF_PARSE(ssl, input + offset, size, isRequest); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index b522ee543..8ee8bf77c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1151,8 +1151,8 @@ enum Misc { TLSv1_1_MINOR = 2, /* TLSv1_1 minor version number */ TLSv1_2_MINOR = 3, /* TLSv1_2 minor version number */ TLSv1_3_MINOR = 4, /* TLSv1_3 minor version number */ -#ifdef WOLFSSL_TLS13_DRAFT TLS_DRAFT_MAJOR = 0x7f, /* Draft TLS major version number */ +#ifdef WOLFSSL_TLS13_DRAFT #ifdef WOLFSSL_TLS13_DRAFT_18 TLS_DRAFT_MINOR = 0x12, /* Minor version number of TLS draft */ #elif defined(WOLFSSL_TLS13_DRAFT_22) @@ -2825,6 +2825,20 @@ enum SignatureAlgorithm { ed25519_sa_algo = 9 }; +#ifdef WOLFSSL_TLS13 +#define PSS_RSAE_TO_PSS_PSS(macAlgo) \ + (macAlgo + (pss_sha256 - sha256_mac)) + +#define PSS_PSS_HASH_TO_MAC(macAlgo) \ + (macAlgo - (pss_sha256 - sha256_mac)) + +enum SigAlgRsaPss { + pss_sha256 = 0x09, + pss_sha384 = 0x0a, + pss_sha512 = 0x0b, +}; +#endif + /* Supprted ECC Curve Types */ enum EccCurves { @@ -3737,7 +3751,7 @@ struct WOLFSSL { word16 group[WOLFSSL_MAX_GROUP_COUNT]; byte numGroups; #endif - byte pssAlgo; + word16 pssAlgo; #ifdef WOLFSSL_TLS13 #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) word16 certHashSigAlgoSz; /* SigAlgoCert ext length in bytes */