diff options
author | Frederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk> | 2024-05-08 11:19:09 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2024-05-30 18:27:57 +0200 |
commit | dcbf02b219cec91ce3dc082a1f270fd2551c16b7 (patch) | |
tree | ad893f2891f53b92615dd27953e6f0acfccba8d9 | |
parent | 412839321187121c254bb44065b157f5adbf6251 (diff) |
Refactor code and fix a couple of missing DTLSv1.3 checks.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24345)
-rw-r--r-- | apps/s_client.c | 31 | ||||
-rw-r--r-- | apps/s_server.c | 19 | ||||
-rw-r--r-- | ssl/record/methods/tls_common.c | 5 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 19 | ||||
-rw-r--r-- | ssl/ssl_ciph.c | 18 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 24 | ||||
-rw-r--r-- | ssl/ssl_local.h | 39 | ||||
-rw-r--r-- | ssl/statem/extensions.c | 14 | ||||
-rw-r--r-- | ssl/statem/extensions_clnt.c | 76 | ||||
-rw-r--r-- | ssl/statem/extensions_srvr.c | 16 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 26 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 9 | ||||
-rw-r--r-- | ssl/t1_lib.c | 28 | ||||
-rw-r--r-- | test/sslapitest.c | 3 |
14 files changed, 204 insertions, 123 deletions
diff --git a/apps/s_client.c b/apps/s_client.c index 0e50b7f536..d3f7dbcf2a 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -205,6 +205,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md, { SSL_SESSION *usesess = NULL; const SSL_CIPHER *cipher = NULL; + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (psksess != NULL) { SSL_SESSION_up_ref(psksess); @@ -231,7 +232,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md, if (usesess == NULL || !SSL_SESSION_set1_master_key(usesess, key, key_len) || !SSL_SESSION_set_cipher(usesess, cipher) - || !SSL_SESSION_set_protocol_version(usesess, TLS1_3_VERSION)) { + || !SSL_SESSION_set_protocol_version(usesess, version1_3)) { OPENSSL_free(key); goto err; } @@ -813,6 +814,7 @@ static void freeandcopy(char **dest, const char *source) static int new_session_cb(SSL *s, SSL_SESSION *sess) { + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (sess_out != NULL) { BIO *stmp = BIO_new_file(sess_out, "w"); @@ -826,10 +828,10 @@ static int new_session_cb(SSL *s, SSL_SESSION *sess) } /* - * Session data gets dumped on connection for TLSv1.2 and below, and on - * arrival of the NewSessionTicket for TLSv1.3. + * Session data gets dumped on connection for (D)TLSv1.2 and below, and on + * arrival of the NewSessionTicket for (D)TLSv1.3. */ - if (SSL_version(s) == TLS1_3_VERSION || SSL_version(s) == DTLS1_3_VERSION) { + if (SSL_version(s) == version1_3) { BIO_printf(bio_c_out, "---\nPost-Handshake New Session Ticket arrived:\n"); SSL_SESSION_print(bio_c_out, sess); @@ -932,6 +934,9 @@ int s_client_main(int argc, char **argv) char *ctlog_file = NULL; int ct_validation = 0; #endif +#ifndef OPENSSL_NO_NEXTPROTONEG + int version1_3; +#endif int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; int async = 0; unsigned int max_send_fragment = 0; @@ -1589,6 +1594,10 @@ int s_client_main(int argc, char **argv) } } +#ifndef OPENSSL_NO_NEXTPROTONEG + version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; +#endif + /* Optional argument is connect string if -connect not used. */ if (opt_num_rest() == 1) { /* Don't allow -connect and a separate argument. */ @@ -1629,7 +1638,7 @@ int s_client_main(int argc, char **argv) } #ifndef OPENSSL_NO_NEXTPROTONEG - if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { + if (min_version == version1_3 && next_proto_neg_in != NULL) { BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n"); goto opthelp; } @@ -3377,7 +3386,8 @@ static void print_stuff(BIO *bio, SSL *s, int full) STACK_OF(X509) *sk; const SSL_CIPHER *c; EVP_PKEY *public_key; - int i, istls13 = (SSL_version(s) == TLS1_3_VERSION); + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + int i; long verify_result; #ifndef OPENSSL_NO_COMP const COMP_METHOD *comp, *expansion; @@ -3570,7 +3580,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) } #endif - if (istls13) { + if (SSL_version(s) == version1_3) { switch (SSL_get_early_data_status(s)) { case SSL_EARLY_DATA_NOT_SENT: BIO_printf(bio, "Early data was not sent\n"); @@ -3831,6 +3841,8 @@ static int user_data_add(struct user_data_st *user_data, size_t i) static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg) { + const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION; + switch (cmd) { case USER_COMMAND_HELP: /* This only ever occurs in advanced mode, so just emit advanced help */ @@ -3843,7 +3855,7 @@ static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg) BIO_printf(bio_err, " {reconnect}: Reconnect to the peer\n"); if (SSL_is_quic(user_data->con)) { BIO_printf(bio_err, " {fin}: Send FIN on the stream. No further writing is possible\n"); - } else if(SSL_version(user_data->con) == TLS1_3_VERSION) { + } else if(SSL_version(user_data->con) == version1_3) { BIO_printf(bio_err, " {keyup:req|noreq}: Send a Key Update message\n"); BIO_printf(bio_err, " Arguments:\n"); BIO_printf(bio_err, " req = peer update requested (default)\n"); @@ -3907,6 +3919,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len, { char *buf_start = user_data->buf + user_data->bufoff; size_t outlen = user_data->buflen; + const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (user_data->buflen == 0) { *len = 0; @@ -3992,7 +4005,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len, } else if(SSL_is_quic(user_data->con)) { if (OPENSSL_strcasecmp(cmd_start, "fin") == 0) cmd = USER_COMMAND_FIN; - } if (SSL_version(user_data->con) == TLS1_3_VERSION) { + } if (SSL_version(user_data->con) == version1_3) { if (OPENSSL_strcasecmp(cmd_start, "keyup") == 0) { cmd = USER_COMMAND_KEY_UPDATE; if (arg_start == NULL) diff --git a/apps/s_server.c b/apps/s_server.c index bd3c508b24..d607d28af2 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -131,17 +131,17 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, { long key_len = 0; unsigned char *key; + const int version1_3 = SSL_is_dtls(ssl) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (s_debug) BIO_printf(bio_s_out, "psk_server_cb\n"); - if ((SSL_is_dtls(ssl) && DTLS_VERSION_GE(SSL_version(ssl), DTLS1_3_VERSION)) - || (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION)) { + if (PROTOCOL_VERSION_CMP(SSL_is_dtls(ssl), SSL_version(ssl), version1_3) >= 0) { /* * This callback is designed for use in (D)TLSv1.2 (or below). It is * possible to use a single callback for all protocol versions - but it - * is preferred to use a dedicated callback for TLSv1.3. For TLSv1.3 we - * have psk_find_session_cb. + * is preferred to use a dedicated callback for (D)TLSv1.3. For + * (D)TLSv1.3 we have psk_find_session_cb. */ return 0; } @@ -1071,6 +1071,9 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_SRTP char *srtp_profiles = NULL; #endif +#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK)) + int version1_3; +#endif int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; int s_server_verify = SSL_VERIFY_NONE; int s_server_session_id_context = 1; /* anything will do */ @@ -1721,6 +1724,10 @@ int s_server_main(int argc, char *argv[]) } } +#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK)) + version1_3 = (socket_type == SOCK_DGRAM) ? DTLS1_3_VERSION : TLS1_3_VERSION; +#endif + /* No extra arguments. */ if (!opt_check_rest_arg(NULL)) goto opthelp; @@ -1729,7 +1736,7 @@ int s_server_main(int argc, char *argv[]) goto end; #ifndef OPENSSL_NO_NEXTPROTONEG - if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { + if (min_version == version1_3 && next_proto_neg_in != NULL) { BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n"); goto opthelp; } @@ -2219,7 +2226,7 @@ int s_server_main(int argc, char *argv[]) } if (psk_identity_hint != NULL) { - if (min_version == TLS1_3_VERSION) { + if (min_version == version1_3) { BIO_printf(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n"); } else { if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index 006584bde2..0aed93eba9 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -148,6 +148,7 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes, size_t currpipe; size_t defltlen = 0; size_t contenttypelen = 0; + const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; if (firstlen == 0 || (numwpipes > 1 && nextlen == 0)) { if (rl->isdtls) @@ -155,8 +156,8 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes, else headerlen = SSL3_RT_HEADER_LENGTH; - /* TLSv1.3 adds an extra content type byte after payload data */ - if (rl->version == TLS1_3_VERSION) + /* (D)TLSv1.3 adds an extra content type byte after payload data */ + if (rl->version == version1_3) contenttypelen = 1; #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index f11eb75827..d5dc8afe09 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1141,8 +1141,10 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex) { - int level, minbits, pfs_mask; + int level, minbits, pfs_mask, minversion; const SSL_CONNECTION *sc; + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + const int version1_2 = SSL_is_dtls(s) ? DTLS1_2_VERSION : TLS1_2_VERSION; minbits = ssl_get_security_level_bits(s, ctx, &level); @@ -1173,9 +1175,12 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, /* SHA1 HMAC is 160 bits of security */ if (minbits > 160 && c->algorithm_mac & SSL_SHA1) return 0; + /* Level 3: forward secure ciphersuites only */ pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK; - if (level >= 3 && c->min_tls != TLS1_3_VERSION && + minversion = SSL_is_dtls(s) ? c->min_dtls : c->min_tls; + + if (level >= 3 && minversion != version1_3 && !(c->algorithm_mkey & pfs_mask)) return 0; break; @@ -1183,15 +1188,9 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, case SSL_SECOP_VERSION: if ((sc = SSL_CONNECTION_FROM_CONST_SSL(s)) == NULL) return 0; - if (!SSL_CONNECTION_IS_DTLS(sc)) { - /* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */ - if (nid <= TLS1_1_VERSION && level > 0) + /* SSLv3, TLS v1.0 and TLS v1.1 and DTLS v1.0 only allowed at level 0 */ + if (ssl_version_cmp(sc, nid, version1_2) < 0 && level > 0) return 0; - } else { - /* DTLS v1.0 only allowed at level 0 */ - if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level > 0) - return 0; - } break; case SSL_SECOP_COMPRESSION: diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index ddde21b968..2cdb1beae9 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -1389,15 +1389,23 @@ static int update_cipher_list(SSL_CTX *ctx, return 0; /* - * Delete any existing TLSv1.3 ciphersuites. These are always first in the + * Delete any existing (D)TLSv1.3 ciphersuites. These are always first in the * list. */ - while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0 - && sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls - == TLS1_3_VERSION) + + while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0) { + const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(tmp_cipher_list, 0); + const int version1_3 = SSL_CTX_IS_DTLS(ctx) ? DTLS1_3_VERSION + : TLS1_3_VERSION; + const int minversion = SSL_CTX_IS_DTLS(ctx) ? cipher->min_dtls + : cipher->min_tls; + + if (minversion != version1_3) + break; (void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0); + } - /* Insert the new TLSv1.3 ciphersuites */ + /* Insert the new (D)TLSv1.3 ciphersuites */ for (i = sk_SSL_CIPHER_num(tls13_ciphersuites) - 1; i >= 0; i--) { const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 714c38ba89..39847f0b64 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -469,6 +469,10 @@ static int ssl_check_allowed_versions(int min_version, int max_version) min_version = DTLS1_VERSION; if (max_version == 0) max_version = DTLS1_3_VERSION; +#ifdef OPENSSL_NO_DTLS1_3 + if (max_version == DTLS1_3_VERSION) + max_version = DTLS1_2_VERSION; +#endif #ifdef OPENSSL_NO_DTLS1_2 if (max_version == DTLS1_2_VERSION) max_version = DTLS1_VERSION; @@ -487,6 +491,10 @@ static int ssl_check_allowed_versions(int min_version, int max_version) || (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION) && DTLS_VERSION_GE(DTLS1_2_VERSION, max_version)) #endif +#ifdef OPENSSL_NO_DTLS1_3 + || (DTLS_VERSION_GE(min_version, DTLS1_3_VERSION) + && DTLS_VERSION_GE(DTLS1_3_VERSION, max_version)) +#endif ) return 0; } else { @@ -935,6 +943,9 @@ int SSL_is_dtls(const SSL *s) { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + if (s == NULL) + return 0; + #ifndef OPENSSL_NO_QUIC if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) return 0; @@ -3308,16 +3319,21 @@ STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) * Distinguish between ciphers controlled by set_ciphersuite() and * set_cipher_list() when counting. */ -static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk) +static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk, int isdtls) { int i, num = 0; const SSL_CIPHER *c; + const int version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; if (sk == NULL) return 0; for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) { + int minversion; + c = sk_SSL_CIPHER_value(sk, i); - if (c->min_tls >= TLS1_3_VERSION) + minversion = isdtls ? c->min_dtls : c->min_tls; + + if (PROTOCOL_VERSION_CMP(isdtls, minversion, version1_3) >= 0) continue; num++; } @@ -3341,7 +3357,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) */ if (sk == NULL) return 0; - else if (cipher_list_tls12_num(sk) == 0) { + else if (cipher_list_tls12_num(sk, SSL_CTX_IS_DTLS(ctx)) == 0) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); return 0; } @@ -3363,7 +3379,7 @@ int SSL_set_cipher_list(SSL *s, const char *str) /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; - else if (cipher_list_tls12_num(sk) == 0) { + else if (cipher_list_tls12_num(sk, SSL_CONNECTION_IS_DTLS(sc)) == 0) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); return 0; } diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index d7b6f0a733..31d92f473e 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -56,6 +56,42 @@ # define DTLS_VERSION_GE(v1, v2) (dtls_ver_ordinal(v1) <= dtls_ver_ordinal(v2)) # define DTLS_VERSION_LT(v1, v2) (dtls_ver_ordinal(v1) > dtls_ver_ordinal(v2)) # define DTLS_VERSION_LE(v1, v2) (dtls_ver_ordinal(v1) >= dtls_ver_ordinal(v2)) +/* + * SSL/TLS version comparison + * + * Returns + * 0 if versiona is equal to versionb or if either are 0 or less + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +# define TLS_VERSION_CMP(versiona, versionb) \ + ((!ossl_assert((versiona) > 0) || !ossl_assert((versionb) > 0) \ + || (versiona) == (versionb)) ? 0 \ + : ((versiona) < (versionb) ? -1 : 1)) +/* + * DTLS version comparison + * + * Returns + * 0 if versiona is equal to versionb or if either are 0 or less + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +# define DTLS_VERSION_CMP(versiona, versionb) \ + ((!ossl_assert((versiona) > 0) || !ossl_assert((versionb) > 0) \ + || (versiona) == (versionb)) ? 0 \ + : (DTLS_VERSION_LT((versiona), \ + (versionb)) ? -1 : 1)) +/* + * SSL/TLS/DTLS version comparison + * + * Returns + * 0 if versiona is equal to versionb or if either are 0 or less + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +# define PROTOCOL_VERSION_CMP(isdtls, versiona, versionb) \ + ((isdtls) ? DTLS_VERSION_CMP(versiona, versionb) \ + : TLS_VERSION_CMP(versiona, versionb)) # define SSL_AD_NO_ALERT -1 @@ -1209,6 +1245,9 @@ struct ssl_ctx_st { # endif }; +# define SSL_CTX_IS_DTLS(ctx) \ + (((ctx)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) != 0) + typedef struct cert_pkey_st CERT_PKEY; #define SSL_TYPE_SSL_CONNECTION 0 diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 9930de9510..0d6c0b1422 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -822,6 +822,8 @@ int tls_parse_all_extensions(SSL_CONNECTION *s, int context, int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx, int max_version) { + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + /* Skip if not relevant for our context */ if ((extctx & thisctx) == 0) return 0; @@ -830,8 +832,7 @@ int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, if (!extension_is_relevant(s, extctx, thisctx) || ((extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) != 0 - && (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_LT(max_version, DTLS1_3_VERSION) - : max_version < TLS1_3_VERSION))) + && ssl_version_cmp(s, max_version, version1_3) < 0)) return 0; return 1; @@ -1446,18 +1447,17 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) * Find the first group we allow that is also in client's list */ for (i = 0; i < num_groups; i++) { - int version; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; group_id = pgroups[i]; - version = SSL_CONNECTION_IS_DTLS(s) ? - DTLS1_3_VERSION : TLS1_3_VERSION; if (check_in_list(s, group_id, clntgroups, clnt_num_groups, 1) && tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) - && tls_valid_group(s, group_id, version, - version, 0, NULL)) + && tls_valid_group(s, group_id, version1_3, + version1_3, 0, NULL)) break; } diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 560f1097ad..4d6d829e3e 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -143,6 +143,7 @@ static int use_ecc(SSL_CONNECTION *s, int min_version, int max_version) const uint16_t *pgroups = NULL; size_t num_groups, j; SSL *ssl = SSL_CONNECTION_GET_SSL(s); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; /* See if we support any ECC ciphersuites */ if (s->version == SSL3_VERSION) @@ -152,12 +153,14 @@ static int use_ecc(SSL_CONNECTION *s, int min_version, int max_version) end = sk_SSL_CIPHER_num(cipher_stack); for (i = 0; i < end; i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); + const int cipher_minversion = SSL_CONNECTION_IS_DTLS(s) ? c->min_dtls + : c->min_tls; alg_k = c->algorithm_mkey; alg_a = c->algorithm_auth; if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) || (alg_a & SSL_aECDSA) - || c->min_tls >= TLS1_3_VERSION) { + || ssl_version_cmp(s, cipher_minversion, version1_3) >= 0) { ret = 1; break; } @@ -217,7 +220,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); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -230,8 +233,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, * if we don't have EC support then we don't send this extension. */ if (!use_ecc(s, min_version, max_version)) - if ((!isdtls && max_version < TLS1_3_VERSION) - || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) + if (ssl_version_cmp(s, max_version, version1_3) < 0) return EXT_RETURN_NOT_SENT; /* @@ -258,8 +260,7 @@ 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) - || (okfortls13 && max_version == DTLS1_3_VERSION)) + if (okfortls13 && max_version == version1_3) tls13added++; added++; } @@ -273,8 +274,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - if (tls13added == 0 && (max_version == TLS1_3_VERSION - || max_version == DTLS1_3_VERSION)) { + if (tls13added == 0 && max_version == version1_3) { 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; @@ -288,14 +288,14 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, size_t chainidx) { size_t ticklen; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!tls_use_ticket(s)) return EXT_RETURN_NOT_SENT; if (!s->new_session && s->session != NULL && s->session->ext.tick != NULL - && s->session->ssl_version != TLS1_3_VERSION - && s->session->ssl_version != DTLS1_3_VERSION) { + && s->session->ssl_version != version1_3) { ticklen = s->session->ext.ticklen; } else if (s->session && s->ext.session_ticket != NULL && s->ext.session_ticket->data != NULL) { @@ -565,7 +565,8 @@ 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); + const int isdtls = SSL_CONNECTION_IS_DTLS(s); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -576,8 +577,7 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt /* * Don't include this if we can't negotiate (D)TLSv1.3. */ - if ((!isdtls && max_version < TLS1_3_VERSION) - || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) + if (ssl_version_cmp(s, max_version, version1_3) < 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions) @@ -587,19 +587,11 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt 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; - } + for (currv = max_version; ssl_version_cmp(s, currv, min_version) >= 0; + isdtls ? currv++ : 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)) { @@ -725,14 +717,13 @@ 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; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) continue; - version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; - - if (!tls_valid_group(s, pgroups[i], version, version, + if (!tls_valid_group(s, pgroups[i], version1_3, version1_3, 0, NULL)) continue; @@ -803,15 +794,14 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, SSL_SESSION *edsess = NULL; const EVP_MD *handmd = NULL; SSL *ssl = SSL_CONNECTION_GET_SSL(s); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (s->hello_retry_request == SSL_HRR_PENDING) handmd = ssl_handshake_md(s); 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 != DTLS1_3_VERSION))) { + || (psksess != NULL && psksess->ssl_version != version1_3))) { SSL_SESSION_free(psksess); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; @@ -833,7 +823,6 @@ 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) { @@ -853,12 +842,11 @@ 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, version)) { + || !SSL_SESSION_set_protocol_version(psksess, version1_3)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); OPENSSL_cleanse(psk, psklen); return EXT_RETURN_FAIL; @@ -971,6 +959,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, { unsigned char *padbytes; size_t hlen; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if ((s->options & SSL_OP_TLSEXT_PADDING) == 0) return EXT_RETURN_NOT_SENT; @@ -990,7 +979,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 || s->session->ssl_version == DTLS1_3_VERSION) + if (s->session->ssl_version == version1_3 && s->session->ext.ticklen != 0 && s->session->cipher != NULL) { const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s), @@ -1047,6 +1036,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, int dores = 0; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); OSSL_TIME t; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; s->ext.tick_identity = 0; @@ -1060,7 +1050,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 && s->session->ssl_version != DTLS1_3_VERSION) + if (s->session->ssl_version != version1_3 || (s->session->ext.ticklen == 0 && s->psksession == NULL)) return EXT_RETURN_NOT_SENT; @@ -1782,6 +1772,7 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, X509 *x, size_t chainidx) { unsigned int version; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!PACKET_get_net_2(pkt, &version) || PACKET_remaining(pkt) != 0) { @@ -1793,7 +1784,7 @@ 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 (D)TLSv1.3 therefore we shouldn't be getting anything else. */ - if (version != TLS1_3_VERSION && version != DTLS1_3_VERSION) { + if ((int)version != version1_3) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; @@ -1837,7 +1828,8 @@ 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; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; if (PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -1860,11 +1852,9 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, 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, version, version, 0, NULL)) { + || !tls_valid_group(s, group_id, version1_3, version1_3, 0, NULL)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index e880095e2d..10aa9b3273 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -647,8 +647,8 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, } while (PACKET_remaining(&key_share_list) > 0) { - const int version13 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION - : TLS1_3_VERSION; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; if (!PACKET_get_net_2(&key_share_list, &group_id) || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt) @@ -688,7 +688,7 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, * We tolerate but ignore a group id that we don't think is * suitable for (D)TLSv1.3 */ - || !tls_valid_group(s, group_id, version13, version13, + || !tls_valid_group(s, group_id, version1_3, version1_3, 0, NULL)) { /* Share not suitable */ continue; @@ -734,6 +734,7 @@ int tl |