diff options
Diffstat (limited to 'ssl/statem/extensions_clnt.c')
-rw-r--r-- | ssl/statem/extensions_clnt.c | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 381a6c9d7b..75d786a54a 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -191,6 +191,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, const uint16_t *pgroups = NULL; size_t num_groups = 0, i, tls13added = 0, added = 0; int min_version, max_version, reason; + const int isdtls = SSL_CONNECTION_IS_DTLS(s); reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -199,12 +200,13 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, } /* - * We only support EC groups in TLSv1.2 or below, and in DTLS. Therefore + * We only support EC groups in (D)TLSv1.2 or below, and in DTLS. Therefore * if we don't have EC support then we don't send this extension. */ - if (!use_ecc(s, min_version, max_version) - && (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION)) - return EXT_RETURN_NOT_SENT; + if (!use_ecc(s, min_version, max_version)) + if ((!isdtls && max_version < TLS1_3_VERSION) + || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) + return EXT_RETURN_NOT_SENT; /* * Add TLS extension supported_groups to the ClientHello message @@ -230,7 +232,8 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - if (okfortls13 && max_version == TLS1_3_VERSION) + if ((okfortls13 && max_version == TLS1_3_VERSION) + || (okfortls13 && max_version == DTLS1_3_VERSION)) tls13added++; added++; } @@ -244,7 +247,8 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - if (tls13added == 0 && max_version == TLS1_3_VERSION) { + if (tls13added == 0 && (max_version == TLS1_3_VERSION + || max_version == DTLS1_3_VERSION)) { SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_GROUPS, "No groups enabled for max supported SSL/TLS version"); return EXT_RETURN_FAIL; @@ -264,7 +268,8 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, if (!s->new_session && s->session != NULL && s->session->ext.tick != NULL - && s->session->ssl_version != TLS1_3_VERSION) { + && s->session->ssl_version != TLS1_3_VERSION + && s->session->ssl_version != DTLS1_3_VERSION) { ticklen = s->session->ext.ticklen; } else if (s->session && s->ext.session_ticket != NULL && s->ext.session_ticket->data != NULL) { @@ -534,6 +539,7 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt size_t chainidx) { int currv, min_version, max_version, reason; + int isdtls = SSL_CONNECTION_IS_DTLS(s); reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -542,10 +548,10 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt } /* - * Don't include this if we can't negotiate TLSv1.3. We can do a straight - * comparison here because we will never be called in DTLS. + * Don't include this if we can't negotiate (D)TLSv1.3. */ - if (max_version < TLS1_3_VERSION) + if ((!isdtls && max_version < TLS1_3_VERSION) + || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions) @@ -555,10 +561,19 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt return EXT_RETURN_FAIL; } - for (currv = max_version; currv >= min_version; currv--) { - if (!WPACKET_put_bytes_u16(pkt, currv)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; + if (isdtls) { + for (currv = max_version; DTLS_VERSION_GE(currv, min_version); currv++) { + if (!WPACKET_put_bytes_u16(pkt, currv)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + } + } else { + for (currv = max_version; currv >= min_version; currv--) { + if (!WPACKET_put_bytes_u16(pkt, currv)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { @@ -684,10 +699,14 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, curve_id = s->s3.group_id; } else { for (i = 0; i < num_groups; i++) { + int version; + if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) continue; - if (!tls_valid_group(s, pgroups[i], TLS1_3_VERSION, TLS1_3_VERSION, + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + + if (!tls_valid_group(s, pgroups[i], version, version, 0, NULL)) continue; @@ -765,7 +784,8 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, if (s->psk_use_session_cb != NULL && (!s->psk_use_session_cb(ssl, handmd, &id, &idlen, &psksess) || (psksess != NULL - && psksess->ssl_version != TLS1_3_VERSION))) { + && psksess->ssl_version != TLS1_3_VERSION + && psksess->ssl_version != DTLS1_3_VERSION))) { SSL_SESSION_free(psksess); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; @@ -787,6 +807,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } else if (psklen > 0) { const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; const SSL_CIPHER *cipher; + int version; idlen = strlen(identity); if (idlen > PSK_MAX_IDENTITY_LEN) { @@ -797,7 +818,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, /* * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec + * the digest so we default to SHA256 as per the (D)TLSv1.3 spec */ cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); if (cipher == NULL) { @@ -806,10 +827,12 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } psksess = SSL_SESSION_new(); + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (psksess == NULL || !SSL_SESSION_set1_master_key(psksess, psk, psklen) || !SSL_SESSION_set_cipher(psksess, cipher) - || !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) { + || !SSL_SESSION_set_protocol_version(psksess, version)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); OPENSSL_cleanse(psk, psklen); return EXT_RETURN_FAIL; @@ -941,7 +964,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, * If we're going to send a PSK then that will be written out after this * extension, so we need to calculate how long it is going to be. */ - if (s->session->ssl_version == TLS1_3_VERSION + if ((s->session->ssl_version == TLS1_3_VERSION || s->session->ssl_version == DTLS1_3_VERSION) && s->session->ext.ticklen != 0 && s->session->cipher != NULL) { const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s), @@ -1011,7 +1034,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, * If this is an incompatible or new session then we have nothing to resume * so don't add this extension. */ - if (s->session->ssl_version != TLS1_3_VERSION + if ((s->session->ssl_version != TLS1_3_VERSION && s->session->ssl_version != DTLS1_3_VERSION) || (s->session->ext.ticklen == 0 && s->psksession == NULL)) return EXT_RETURN_NOT_SENT; @@ -1419,18 +1442,18 @@ int tls_parse_stoc_status_request(SSL_CONNECTION *s, PACKET *pkt, /* * MUST only be sent if we've requested a status - * request message. In TLS <= 1.2 it must also be empty. + * request message. In (D)TLS <= 1.2 it must also be empty. */ if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) { SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } - if (!SSL_CONNECTION_IS_TLS13(s) && PACKET_remaining(pkt) > 0) { + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && PACKET_remaining(pkt) > 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) { /* We only know how to handle this if it's for the first Certificate in * the chain. We ignore any other responses. */ @@ -1742,9 +1765,9 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, /* * The only protocol version we support which is valid in this extension in - * a ServerHello is TLSv1.3 therefore we shouldn't be getting anything else. + * a ServerHello is (D)TLSv1.3 therefore we shouldn't be getting anything else. */ - if (version != TLS1_3_VERSION) { + if (version != TLS1_3_VERSION && version != DTLS1_3_VERSION) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; @@ -1788,6 +1811,7 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if ((context & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) { const uint16_t *pgroups = NULL; size_t i, num_groups; + int version; if (PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -1809,10 +1833,12 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if (group_id == pgroups[i]) break; } + + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (i >= num_groups || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) - || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, - 0, NULL)) { + || !tls_valid_group(s, group_id, version, version, 0, NULL)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } |