summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>2024-05-08 11:19:09 +0200
committerTomas Mraz <tomas@openssl.org>2024-05-30 18:27:57 +0200
commitdcbf02b219cec91ce3dc082a1f270fd2551c16b7 (patch)
treead893f2891f53b92615dd27953e6f0acfccba8d9
parent412839321187121c254bb44065b157f5adbf6251 (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.c31
-rw-r--r--apps/s_server.c19
-rw-r--r--ssl/record/methods/tls_common.c5
-rw-r--r--ssl/ssl_cert.c19
-rw-r--r--ssl/ssl_ciph.c18
-rw-r--r--ssl/ssl_lib.c24
-rw-r--r--ssl/ssl_local.h39
-rw-r--r--ssl/statem/extensions.c14
-rw-r--r--ssl/statem/extensions_clnt.c76
-rw-r--r--ssl/statem/extensions_srvr.c16
-rw-r--r--ssl/statem/statem_clnt.c26
-rw-r--r--ssl/statem/statem_lib.c9
-rw-r--r--ssl/t1_lib.c28
-rw-r--r--test/sslapitest.c3
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