summaryrefslogtreecommitdiffstats
path: root/ssl/statem/extensions_clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/statem/extensions_clnt.c')
-rw-r--r--ssl/statem/extensions_clnt.c80
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;
}