From d4bf135ddd908c1205502ed5bf595d8ac0b336c8 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Tue, 3 Oct 2023 09:39:47 +0200 Subject: [PATCH 01/16] Adds initial dtls 1.3 structs and definitions --- include/openssl/prov_ssl.h | 1 + include/openssl/ssl.h.in | 1 + ssl/d1_lib.c | 15 +++++++++++++++ ssl/methods.c | 18 ++++++++++++++++++ ssl/record/methods/recmethod_local.h | 1 + ssl/record/methods/tls13_meth.c | 21 +++++++++++++++++++++ ssl/ssl_local.h | 11 ++++++++++- 7 files changed, 67 insertions(+), 1 deletion(-) diff --git a/include/openssl/prov_ssl.h b/include/openssl/prov_ssl.h index 76d01e1eb89c49..9f3e8197e30881 100644 --- a/include/openssl/prov_ssl.h +++ b/include/openssl/prov_ssl.h @@ -27,6 +27,7 @@ extern "C" { # define TLS1_3_VERSION 0x0304 # define DTLS1_VERSION 0xFEFF # define DTLS1_2_VERSION 0xFEFD +# define DTLS1_3_VERSION 0xFEFC # define DTLS1_BAD_VER 0x0100 /* QUIC uses a 4 byte unsigned version number */ diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index 5df101ff872101..0ee447ebabd1b6 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -405,6 +405,7 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); # define SSL_OP_NO_TLSv1_3 SSL_OP_BIT(29) # define SSL_OP_NO_DTLSv1 SSL_OP_BIT(26) # define SSL_OP_NO_DTLSv1_2 SSL_OP_BIT(27) +# define SSL_OP_NO_DTLSv1_3 SSL_OP_BIT(29) /* Disallow all renegotiation */ # define SSL_OP_NO_RENEGOTIATION SSL_OP_BIT(30) /* diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 8bbabd8f413ef0..40362a0ddb46b1 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -51,6 +51,21 @@ const SSL3_ENC_METHOD DTLSv1_2_enc_data = { dtls1_handshake_write }; +const SSL3_ENC_METHOD DTLSv1_3_enc_data = { + tls13_setup_key_block, + tls13_generate_master_secret, + tls13_change_cipher_state, + tls13_final_finish_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls13_alert_code, + tls13_export_keying_material, + SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF, + dtls1_set_handshake_header, + dtls1_close_construct_packet, + dtls1_handshake_write +}; + OSSL_TIME dtls1_default_timeout(void) { /* diff --git a/ssl/methods.c b/ssl/methods.c index 525f59e91231c7..836d859ec73bcc 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -125,6 +125,12 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ossl_statem_accept, ossl_statem_connect, DTLSv1_2_enc_data) #endif +#ifndef OPENSSL_NO_DTLS1_3_METHOD +IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, + dtlsv1_3_method, + ossl_statem_accept, + ossl_statem_connect, DTLSv1_3_enc_data) +#endif IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_method, ossl_statem_accept, @@ -145,6 +151,12 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ossl_statem_accept, ssl_undefined_function, DTLSv1_2_enc_data) #endif +#ifndef OPENSSL_NO_DTLS1_3_METHOD +IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, + dtlsv1_3_server_method, + ossl_statem_accept, + ssl_undefined_function, DTLSv1_3_enc_data) +#endif IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_server_method, ossl_statem_accept, @@ -169,6 +181,12 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ssl_undefined_function, ossl_statem_connect, DTLSv1_2_enc_data) #endif +#ifndef OPENSSL_NO_DTLS1_3_METHOD +IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, + dtlsv1_3_client_method, + ssl_undefined_function, + ossl_statem_connect, DTLSv1_3_enc_data) +#endif IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_client_method, ssl_undefined_function, diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index 300b146a7b07f4..4d507951b5121c 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -382,6 +382,7 @@ extern struct record_functions_st tls_1_funcs; extern struct record_functions_st tls_1_3_funcs; extern struct record_functions_st tls_any_funcs; extern struct record_functions_st dtls_1_funcs; +extern struct record_functions_st dtls_1_3_funcs; extern struct record_functions_st dtls_any_funcs; void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, diff --git a/ssl/record/methods/tls13_meth.c b/ssl/record/methods/tls13_meth.c index ec22f1ee49e400..b676e765b06a43 100644 --- a/ssl/record/methods/tls13_meth.c +++ b/ssl/record/methods/tls13_meth.c @@ -323,3 +323,24 @@ struct record_functions_st tls_1_3_funcs = { tls_post_encryption_processing_default, NULL }; + +struct record_functions_st dtls_1_3_funcs = { + tls13_set_crypto_state, + tls13_cipher, + NULL, + tls_default_set_protocol_version, + tls_default_read_n, + dtls_get_more_records, + NULL, + tls13_post_process_record, + NULL, + tls_write_records_default, + tls_allocate_write_buffers_default, + tls_initialise_write_packets_default, + tls13_get_record_type, + dtls_prepare_record_header, + tls13_add_record_padding, + tls_prepare_for_encryption_default, + dtls_post_encryption_processing, + NULL +}; diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index d1ef358932e00d..bf5d761fa79441 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -258,13 +258,18 @@ # define SSL_CONNECTION_IS_DTLS(s) \ (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) +/* Check if we are using DTLSv1.3 */ +# define SSL_CONNECTION_IS_DTLS13(s) (SSL_CONNECTION_IS_DTLS(s) \ + && DTLS_VERSION_GE(SSL_CONNECTION_GET_SSL(s)->method->version, DTLS1_3_VERSION) \ + && SSL_CONNECTION_GET_SSL(s)->method->version != DTLS_ANY_VERSION) + /* Check if we are using TLSv1.3 */ # define SSL_CONNECTION_IS_TLS13(s) (!SSL_CONNECTION_IS_DTLS(s) \ && SSL_CONNECTION_GET_SSL(s)->method->version >= TLS1_3_VERSION \ && SSL_CONNECTION_GET_SSL(s)->method->version != TLS_ANY_VERSION) # define SSL_CONNECTION_TREAT_AS_TLS13(s) \ - (SSL_CONNECTION_IS_TLS13(s) \ + ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) \ || (s)->early_data_state == SSL_EARLY_DATA_CONNECTING \ || (s)->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY \ || (s)->early_data_state == SSL_EARLY_DATA_WRITING \ @@ -2258,6 +2263,9 @@ __owur const SSL_METHOD *dtls_bad_ver_client_method(void); __owur const SSL_METHOD *dtlsv1_2_method(void); __owur const SSL_METHOD *dtlsv1_2_server_method(void); __owur const SSL_METHOD *dtlsv1_2_client_method(void); +__owur const SSL_METHOD *dtlsv1_3_method(void); +__owur const SSL_METHOD *dtlsv1_3_server_method(void); +__owur const SSL_METHOD *dtlsv1_3_client_method(void); extern const SSL3_ENC_METHOD TLSv1_enc_data; extern const SSL3_ENC_METHOD TLSv1_1_enc_data; @@ -2266,6 +2274,7 @@ extern const SSL3_ENC_METHOD TLSv1_3_enc_data; extern const SSL3_ENC_METHOD SSLv3_enc_data; extern const SSL3_ENC_METHOD DTLSv1_enc_data; extern const SSL3_ENC_METHOD DTLSv1_2_enc_data; +extern const SSL3_ENC_METHOD DTLSv1_3_enc_data; /* * Flags for SSL methods From a106016a79f36c3e935707706496f9ca411a40f7 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Tue, 3 Oct 2023 12:43:19 +0200 Subject: [PATCH 02/16] Integrate dtls1.3 in s_client and s_server --- apps/include/opt.h | 6 +++--- apps/lib/s_cb.c | 6 +++++- apps/s_client.c | 23 +++++++++++++++++++---- apps/s_server.c | 24 +++++++++++++++++++----- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/apps/include/opt.h b/apps/include/opt.h index 5a2faa150b4095..6c5956b142b1c3 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -213,12 +213,12 @@ "Groups to advertise (colon-separated list)" }, \ {"named_curve", OPT_S_NAMEDCURVE, 's', \ "Elliptic curve used for ECDHE (server-side only)" }, \ - {"cipher", OPT_S_CIPHER, 's', "Specify TLSv1.2 and below cipher list to be used"}, \ - {"ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify TLSv1.3 ciphersuites to be used"}, \ + {"cipher", OPT_S_CIPHER, 's', "Specify (D)TLSv1.2 and below cipher list to be used"}, \ + {"ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify (D)TLSv1.3 ciphersuites to be used"}, \ {"min_protocol", OPT_S_MINPROTO, 's', "Specify the minimum protocol version to be used"}, \ {"max_protocol", OPT_S_MAXPROTO, 's', "Specify the maximum protocol version to be used"}, \ {"record_padding", OPT_S_RECORD_PADDING, 's', \ - "Block size to pad TLS 1.3 records to."}, \ + "Block size to pad (D)TLS 1.3 records to."}, \ {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \ "Perform all sorts of protocol violations for testing purposes"}, \ {"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \ diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index dcfea55dc5696e..b768ce2053c082 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -500,6 +500,8 @@ static STRINT_PAIR ssl_versions[] = { {"TLS 1.2", TLS1_2_VERSION}, {"TLS 1.3", TLS1_3_VERSION}, {"DTLS 1.0", DTLS1_VERSION}, + {"DTLS 1.2", DTLS1_2_VERSION}, + {"DTLS 1.3", DTLS1_3_VERSION}, {"DTLS 1.0 (bad)", DTLS1_BAD_VER}, {NULL} }; @@ -582,7 +584,9 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, version == TLS1_1_VERSION || version == TLS1_2_VERSION || version == TLS1_3_VERSION || - version == DTLS1_VERSION || version == DTLS1_BAD_VER) { + version == DTLS1_VERSION || + version == DTLS1_2_VERSION || + version == DTLS1_3_VERSION || version == DTLS1_BAD_VER) { str_version = lookup(version, ssl_versions, "???"); switch (content_type) { case SSL3_RT_CHANGE_CIPHER_SPEC: diff --git a/apps/s_client.c b/apps/s_client.c index 5577a9e9038660..32b92dc4ebbd1a 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -490,9 +490,9 @@ typedef enum OPTION_choice { #endif OPT_SSL3, OPT_SSL_CONFIG, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, - OPT_DTLS1_2, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, - OPT_PASS, OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, - OPT_NEXTPROTONEG, OPT_ALPN, + OPT_DTLS1_2, OPT_DTLS1_3, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, + OPT_KEYFORM, OPT_PASS, OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, + OPT_BUILD_CHAIN, OPT_NEXTPROTONEG, OPT_ALPN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE, @@ -695,6 +695,9 @@ const OPTIONS s_client_options[] = { #ifndef OPENSSL_NO_DTLS1_2 {"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"}, #endif +#ifndef OPENSSL_NO_DTLS1_3 + {"dtls1_3", OPT_DTLS1_3, '-', "Just use DTLSv1.3"}, +#endif #ifndef OPENSSL_NO_SCTP {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, @@ -797,7 +800,7 @@ static const OPT_PAIR services[] = { #define IS_PROT_FLAG(o) \ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \ - || o == OPT_QUIC) + || o == OPT_DTLS1_3 || o == OPT_QUIC) /* Free |*dest| and optionally set it to a copy of |source|. */ static void freeandcopy(char **dest, const char *source) @@ -1349,6 +1352,18 @@ int s_client_main(int argc, char **argv) socket_type = SOCK_DGRAM; isdtls = 1; isquic = 0; +#endif + break; + case OPT_DTLS1_3: +#ifndef OPENSSL_NO_DTLS1_3 + meth = DTLS_client_method(); + min_version = DTLS1_3_VERSION; + max_version = DTLS1_3_VERSION; + socket_type = SOCK_DGRAM; + isdtls = 1; +# ifndef OPENSS_NO_QUIC + isquic = 0; +# endif #endif break; case OPT_QUIC: diff --git a/apps/s_server.c b/apps/s_server.c index 93f6cb2983f7df..a021590be8f7b7 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -54,6 +54,7 @@ typedef unsigned int u_int; #include #endif #include "internal/sockets.h" +#include "ssl/ssl_local.h" static int not_resumable_sess_cb(SSL *s, int is_forward_secure); static int sv_body(int s, int stype, int prot, unsigned char *context); @@ -134,7 +135,8 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, if (s_debug) BIO_printf(bio_s_out, "psk_server_cb\n"); - if (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION) { + if ((SSL_is_dtls(ssl) && DTLS_VERSION_GE(SSL_version(ssl), DTLS1_3_VERSION)) + || (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION)) { /* * 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 @@ -714,8 +716,8 @@ typedef enum OPTION_choice { OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, - OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS, - OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, + OPT_DTLS1_2, OPT_DTLS1_3, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, + OPT_STATELESS, OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_SENDFILE, OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, @@ -923,7 +925,7 @@ const OPTIONS s_server_options[] = { "The maximum number of bytes of early data (hard limit)"}, {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, {"num_tickets", OPT_S_NUM_TICKETS, 'n', - "The number of TLSv1.3 session tickets that a server will automatically issue" }, + "The number of (D)TLSv1.3 session tickets that a server will automatically issue" }, {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, {"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"}, @@ -956,6 +958,9 @@ const OPTIONS s_server_options[] = { #ifndef OPENSSL_NO_DTLS1_2 {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"}, #endif +#ifndef OPENSSL_NO_DTLS1_3 + {"dtls1_3", OPT_DTLS1_3, '-', "Just talk DTLSv1.3"}, +#endif #ifndef OPENSSL_NO_SCTP {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, @@ -988,7 +993,8 @@ const OPTIONS s_server_options[] = { #define IS_PROT_FLAG(o) \ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ - || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) + || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \ + || o == OPT_DTLS1_3) int s_server_main(int argc, char *argv[]) { @@ -1538,6 +1544,14 @@ int s_server_main(int argc, char *argv[]) min_version = DTLS1_2_VERSION; max_version = DTLS1_2_VERSION; socket_type = SOCK_DGRAM; +#endif + break; + case OPT_DTLS1_3: +#ifndef OPENSSL_NO_DTLS + meth = DTLS_server_method(); + min_version = DTLS1_3_VERSION; + max_version = DTLS1_3_VERSION; + socket_type = SOCK_DGRAM; #endif break; case OPT_SCTP: From fc5b23e2522b98e1b5d2a15883bbe57ffdaed68c Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Wed, 4 Oct 2023 09:41:14 +0200 Subject: [PATCH 03/16] Remove compile guards for dtls1.3 method implementations --- ssl/methods.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ssl/methods.c b/ssl/methods.c index 836d859ec73bcc..5dd29fbbb29fec 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -125,12 +125,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ossl_statem_accept, ossl_statem_connect, DTLSv1_2_enc_data) #endif -#ifndef OPENSSL_NO_DTLS1_3_METHOD IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, dtlsv1_3_method, ossl_statem_accept, ossl_statem_connect, DTLSv1_3_enc_data) -#endif IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_method, ossl_statem_accept, @@ -151,12 +149,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ossl_statem_accept, ssl_undefined_function, DTLSv1_2_enc_data) #endif -#ifndef OPENSSL_NO_DTLS1_3_METHOD IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, dtlsv1_3_server_method, ossl_statem_accept, ssl_undefined_function, DTLSv1_3_enc_data) -#endif IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_server_method, ossl_statem_accept, @@ -181,12 +177,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ssl_undefined_function, ossl_statem_connect, DTLSv1_2_enc_data) #endif -#ifndef OPENSSL_NO_DTLS1_3_METHOD IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, dtlsv1_3_client_method, ssl_undefined_function, ossl_statem_connect, DTLSv1_3_enc_data) -#endif IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_client_method, ssl_undefined_function, From 73ad73dcac9431252e66bd3570cded7c072b6cfe Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Wed, 4 Oct 2023 10:03:45 +0200 Subject: [PATCH 04/16] Adds DTLS1.3 to ssl protocol to text structs --- ssl/ssl_conf.c | 3 ++- ssl/t1_trce.c | 1 + test/helpers/ssl_test_ctx.c | 1 + test/ssl_old_test.c | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 3142370016846e..a9ef6854b82ef8 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -318,7 +318,8 @@ static int protocol_from_string(const char *value) {"TLSv1.2", TLS1_2_VERSION}, {"TLSv1.3", TLS1_3_VERSION}, {"DTLSv1", DTLS1_VERSION}, - {"DTLSv1.2", DTLS1_2_VERSION} + {"DTLSv1.2", DTLS1_2_VERSION}, + {"DTLSv1.3", DTLS1_3_VERSION} }; size_t i; size_t n = OSSL_NELEM(versions); diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index b05012f74fd671..3810bdc2763b24 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -68,6 +68,7 @@ static const ssl_trace_tbl ssl_version_tbl[] = { {TLS1_3_VERSION, "TLS 1.3"}, {DTLS1_VERSION, "DTLS 1.0"}, {DTLS1_2_VERSION, "DTLS 1.2"}, + {DTLS1_3_VERSION, "DTLS 1.3"}, {DTLS1_BAD_VER, "DTLS 1.0 (bad)"} }; diff --git a/test/helpers/ssl_test_ctx.c b/test/helpers/ssl_test_ctx.c index ec2c7885ba7c72..10bbdc4f1b2c8a 100644 --- a/test/helpers/ssl_test_ctx.c +++ b/test/helpers/ssl_test_ctx.c @@ -156,6 +156,7 @@ static const test_enum ssl_protocols[] = { {"SSLv3", SSL3_VERSION}, {"DTLSv1", DTLS1_VERSION}, {"DTLSv1.2", DTLS1_2_VERSION}, + {"DTLSv1.3", DTLS1_3_VERSION}, }; __owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value) diff --git a/test/ssl_old_test.c b/test/ssl_old_test.c index fe168472d3022b..f97acb5d8953b8 100644 --- a/test/ssl_old_test.c +++ b/test/ssl_old_test.c @@ -825,7 +825,8 @@ static int protocol_from_string(const char *value) {"tls1.2", TLS1_2_VERSION}, {"tls1.3", TLS1_3_VERSION}, {"dtls1", DTLS1_VERSION}, - {"dtls1.2", DTLS1_2_VERSION}}; + {"dtls1.2", DTLS1_2_VERSION}, + {"dtls1.3", DTLS1_3_VERSION}}; size_t i; size_t n = OSSL_NELEM(versions); From 0a6b7cac23eefb061c11e022529750f95a6fbf89 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Wed, 4 Oct 2023 11:37:10 +0200 Subject: [PATCH 05/16] Add dtls1.3 to ssl_protocol_to_string() --- ssl/ssl_lib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index f15fe126a22f54..9a223282b4cc05 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -4820,6 +4820,9 @@ const char *ssl_protocol_to_string(int version) case DTLS1_2_VERSION: return "DTLSv1.2"; + case DTLS1_3_VERSION: + return "DTLSv1.3"; + default: return "unknown"; } From a0c53fd7b0fc05066d92b1f2fa55b5cabc49f9bd Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Wed, 4 Oct 2023 11:58:06 +0200 Subject: [PATCH 06/16] Update dtls max version --- include/openssl/dtls1.h | 2 +- ssl/ssl_local.h | 2 +- ssl/statem/statem_clnt.c | 2 +- ssl/statem/statem_lib.c | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/openssl/dtls1.h b/include/openssl/dtls1.h index 5dc6b5419c2752..024584f426e9c4 100644 --- a/include/openssl/dtls1.h +++ b/include/openssl/dtls1.h @@ -27,7 +27,7 @@ extern "C" { /* DTLS*_VERSION constants are defined in prov_ssl.h */ # ifndef OPENSSL_NO_DEPRECATED_3_0 # define DTLS_MIN_VERSION DTLS1_VERSION -# define DTLS_MAX_VERSION DTLS1_2_VERSION +# define DTLS_MAX_VERSION DTLS1_3_VERSION # endif # define DTLS1_VERSION_MAJOR 0xFE diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index d1ef358932e00d..5109cb95906d2f 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -45,7 +45,7 @@ # endif # define TLS_MAX_VERSION_INTERNAL TLS1_3_VERSION -# define DTLS_MAX_VERSION_INTERNAL DTLS1_2_VERSION +# define DTLS_MAX_VERSION_INTERNAL DTLS1_3_VERSION /* * DTLS version numbers are strange because they're inverted. Except for diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index cbf5a57bebf47c..06904ca95e9571 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -191,7 +191,7 @@ static int ossl_statem_client13_read_transition(SSL_CONNECTION *s, int mt) if (mt == SSL3_MT_CERTIFICATE_REQUEST) { #if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION /* Restore digest for PHA before adding message.*/ -# error Internal DTLS version error +# warning Internal DTLS version error #endif if (!SSL_CONNECTION_IS_DTLS(s) && s->post_handshake_auth == SSL_PHA_EXT_SENT) { diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index d979b6d5fc4377..fa99aaf4d26050 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1834,12 +1834,13 @@ static const version_info tls_version_table[] = { {0, NULL, NULL}, }; -#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION -# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. +#if DTLS_MAX_VERSION_INTERNAL != DTLS1_3_VERSION +# error Code needs update for DTLS_method() support beyond DTLS1_3_VERSION. #endif /* Must be in order high to low */ static const version_info dtls_version_table[] = { + {DTLS1_3_VERSION, dtlsv1_3_client_method, dtlsv1_3_server_method}, #ifndef OPENSSL_NO_DTLS1_2 {DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method}, #else From 3ac3cc3a642b5e387986f99249f3ec4fa3d2fcce Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Thu, 12 Oct 2023 13:55:32 +0200 Subject: [PATCH 07/16] Don't allow renegotiation for DTLS 1.3 --- apps/include/s_apps.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/include/s_apps.h b/apps/include/s_apps.h index 33c3b6278c823f..89b27bcc585bec 100644 --- a/apps/include/s_apps.h +++ b/apps/include/s_apps.h @@ -16,7 +16,8 @@ #define PROTOCOL "tcp" #define SSL_VERSION_ALLOWS_RENEGOTIATION(s) \ - (SSL_is_dtls(s) || (SSL_version(s) < TLS1_3_VERSION)) + ((SSL_is_dtls(s) && SSL_version(s) > DTLS1_3_VERSION) \ + || (!SSL_is_dtls(s) && SSL_version(s) < TLS1_3_VERSION)) typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context); void get_sock_info_address(int asock, char **hostname, char **service); From 91c825c7c46caa28771bcedd56abb2ba4501aa97 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Thu, 12 Oct 2023 14:22:40 +0200 Subject: [PATCH 08/16] Update documentation for DTLS1.3 --- doc/man1/openssl-s_client.pod.in | 2 +- doc/man3/SSL_CIPHER_get_name.pod | 4 ++-- doc/man3/SSL_CONF_cmd.pod | 2 +- doc/man3/SSL_CTX_set0_CA_list.pod | 2 +- doc/man3/SSL_CTX_set1_sigalgs.pod | 4 ++-- doc/man3/SSL_CTX_set_min_proto_version.pod | 2 +- doc/man3/SSL_CTX_set_num_tickets.pod | 2 +- doc/man3/SSL_CTX_set_options.pod | 4 ++-- doc/man3/SSL_check_chain.pod | 4 ++-- doc/man3/SSL_export_keying_material.pod | 2 +- doc/man3/SSL_get_shared_sigalgs.pod | 2 +- doc/man3/SSL_get_version.pod | 4 ++++ 12 files changed, 19 insertions(+), 15 deletions(-) diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 84cf6fdd81f1f5..cf59ef32d5e561 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -353,7 +353,7 @@ See L for more information on the C scheme. A file containing a list of certificates whose subject names will be sent to the server in the B extension. Only supported -for TLS 1.3 +for TLS 1.3 and DTLS 1.3 =item B<-dane_tlsa_domain> I diff --git a/doc/man3/SSL_CIPHER_get_name.pod b/doc/man3/SSL_CIPHER_get_name.pod index 44af9d6dfe9e5f..cb25caed89ea93 100644 --- a/doc/man3/SSL_CIPHER_get_name.pod +++ b/doc/man3/SSL_CIPHER_get_name.pod @@ -74,7 +74,7 @@ different to the digest used to calculate the MAC for encrypted records. SSL_CIPHER_get_kx_nid() returns the key exchange NID corresponding to the method used by B. If there is no key exchange, then B is returned. -If any appropriate key exchange algorithm can be used (as in the case of TLS 1.3 +If any appropriate key exchange algorithm can be used (as in the case of (D)TLS 1.3 cipher suites) B is returned. Examples (not comprehensive): NID_kx_rsa @@ -85,7 +85,7 @@ cipher suites) B is returned. Examples (not comprehensive): SSL_CIPHER_get_auth_nid() returns the authentication NID corresponding to the method used by B. If there is no authentication, then B is returned. If any appropriate authentication algorithm can be used (as in the case of -TLS 1.3 cipher suites) B is returned. Examples (not comprehensive): +(D)TLS 1.3 cipher suites) B is returned. Examples (not comprehensive): NID_auth_rsa NID_auth_ecdsa diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index 7ffd731410a0ea..114e19f91a0028 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -330,7 +330,7 @@ if certificate operations are permitted. This option indicates a file containing a set of certificates in PEM form. The subject names of the certificates are sent to the peer in the -B extension for TLS 1.3 (in ClientHello or +B extension for (D)TLS 1.3 (in ClientHello or CertificateRequest) or in a certificate request for previous versions or TLS. diff --git a/doc/man3/SSL_CTX_set0_CA_list.pod b/doc/man3/SSL_CTX_set0_CA_list.pod index 64e8117f923614..ce7ed0e6585cb5 100644 --- a/doc/man3/SSL_CTX_set0_CA_list.pod +++ b/doc/man3/SSL_CTX_set0_CA_list.pod @@ -47,7 +47,7 @@ server to the client when requesting a client certificate. So any list of CA names set is never sent from client to server and the list of CA names retrieved by SSL_get0_peer_CA_list() is always B. -For TLS 1.3 the list of CA names is sent using the B +For (D)TLS 1.3 the list of CA names is sent using the B extension and may be sent by a client (in the ClientHello message) or by a server (when requesting a certificate). diff --git a/doc/man3/SSL_CTX_set1_sigalgs.pod b/doc/man3/SSL_CTX_set1_sigalgs.pod index eb3100634626fc..9273dff6395661 100644 --- a/doc/man3/SSL_CTX_set1_sigalgs.pod +++ b/doc/man3/SSL_CTX_set1_sigalgs.pod @@ -32,7 +32,7 @@ SSL_CTX_set1_sigalgs_list() and SSL_set1_sigalgs_list() set the supported signature algorithms for B or B. The B parameter must be a null terminated string consisting of a colon separated list of elements, where each element is either a combination of a public key -algorithm and a digest separated by B<+>, or a TLS 1.3-style named +algorithm and a digest separated by B<+>, or a (D)TLS 1.3-style named SignatureScheme such as rsa_pss_pss_sha256. SSL_CTX_set1_client_sigalgs(), SSL_set1_client_sigalgs(), @@ -78,7 +78,7 @@ The short or long name values for digests can be used in a string (for example "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512") and the public key algorithm strings "RSA", "RSA-PSS", "DSA" or "ECDSA". -The TLS 1.3 signature scheme names (such as "rsa_pss_pss_sha256") can also +The (D)TLS 1.3 signature scheme names (such as "rsa_pss_pss_sha256") can also be used with the B<_list> forms of the API. The use of MD5 as a digest is strongly discouraged due to security weaknesses. diff --git a/doc/man3/SSL_CTX_set_min_proto_version.pod b/doc/man3/SSL_CTX_set_min_proto_version.pod index 9a2da37ab72949..34b7a40cf3c396 100644 --- a/doc/man3/SSL_CTX_set_min_proto_version.pod +++ b/doc/man3/SSL_CTX_set_min_proto_version.pod @@ -40,7 +40,7 @@ automatically use the lowest or highest version supported by the library. Currently supported versions are B, B, B, B, B for TLS and -B, B for DTLS. +B, B, B for DTLS. In the current version of OpenSSL only QUICv1 is supported in conjunction with TLSv1.3. Calling these functions on a QUIC object has no effect. diff --git a/doc/man3/SSL_CTX_set_num_tickets.pod b/doc/man3/SSL_CTX_set_num_tickets.pod index 0c7331bc6da94b..e81679e609a050 100644 --- a/doc/man3/SSL_CTX_set_num_tickets.pod +++ b/doc/man3/SSL_CTX_set_num_tickets.pod @@ -46,7 +46,7 @@ To issue tickets after other events (such as application-layer changes), SSL_new_session_ticket() is used by a server application to request that a new ticket be sent when it is safe to do so. New tickets are only allowed to be sent in this manner after the initial handshake has completed, and only for -TLS 1.3 connections. By default, the ticket generation and transmission are +(D)TLS 1.3 connections. By default, the ticket generation and transmission are delayed until the server is starting a new write operation, so that it is bundled with other application data being written and properly aligned to a record boundary. If the connection was at a record boundary when diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 56695e4abd507d..ec5a42f5f325fc 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -285,10 +285,10 @@ When performing renegotiation as a server, always start a new session handshake). This option is not needed for clients. =item SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, -SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3, SSL_OP_NO_DTLSv1, SSL_OP_NO_DTLSv1_2 +SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3, SSL_OP_NO_DTLSv1, SSL_OP_NO_DTLSv1_2, SSL_OP_NO_DTLSv1_3 These options turn off the SSLv3, TLSv1, TLSv1.1, TLSv1.2 or TLSv1.3 protocol -versions with TLS or the DTLSv1, DTLSv1.2 versions with DTLS, +versions with TLS or the DTLSv1, DTLSv1.2, DTLSv1.3 versions with DTLS, respectively. As of OpenSSL 1.1.0, these options are deprecated, use L and diff --git a/doc/man3/SSL_check_chain.pod b/doc/man3/SSL_check_chain.pod index d00badbd753f05..e90ab0dd6fa2fd 100644 --- a/doc/man3/SSL_check_chain.pod +++ b/doc/man3/SSL_check_chain.pod @@ -72,8 +72,8 @@ The validity of a chain is determined by checking if it matches a supported signature algorithm, supported curves and in the case of client authentication certificate types and issuer names. -Since the supported signature algorithms extension is only used in TLS 1.2, -TLS 1.3 and DTLS 1.2 the results for earlier versions of TLS and DTLS may not +Since the supported signature algorithms extension is only used in (D)TLS 1.2 +and (D)TLS 1.3 the results for earlier versions of TLS and DTLS may not be very useful. Applications may wish to specify a different "legacy" chain for earlier versions of TLS or DTLS. diff --git a/doc/man3/SSL_export_keying_material.pod b/doc/man3/SSL_export_keying_material.pod index c7c5320295e647..a0b54d70da2e26 100644 --- a/doc/man3/SSL_export_keying_material.pod +++ b/doc/man3/SSL_export_keying_material.pod @@ -31,7 +31,7 @@ accordance with RFC5705 (for TLSv1.2 and below) or RFC8446 (for TLSv1.3). SSL_export_keying_material() derives keying material using the F established in the handshake. -SSL_export_keying_material_early() is only usable with TLSv1.3, and derives +SSL_export_keying_material_early() is only usable with (D)TLSv1.3, and derives keying material using the F (as defined in the TLS 1.3 RFC). For the client, the F is only available when the client attempts to send 0-RTT data. For the server, it is diff --git a/doc/man3/SSL_get_shared_sigalgs.pod b/doc/man3/SSL_get_shared_sigalgs.pod index c18114cdf47200..f7a1d4f062b3a5 100644 --- a/doc/man3/SSL_get_shared_sigalgs.pod +++ b/doc/man3/SSL_get_shared_sigalgs.pod @@ -54,7 +54,7 @@ signature algorithms: after a client hello (for servers) or a certificate request (for clients). They can (for example) be called in the certificate callback. -Only TLS 1.2, TLS 1.3 and DTLS 1.2 currently support signature algorithms. +Only (D)TLS 1.2 and (D)TLS 1.3 currently support signature algorithms. If these functions are called on an earlier version of TLS or DTLS zero is returned. diff --git a/doc/man3/SSL_get_version.pod b/doc/man3/SSL_get_version.pod index b8a0f5e3b15de0..a6f5e7fb84bbcc 100644 --- a/doc/man3/SSL_get_version.pod +++ b/doc/man3/SSL_get_version.pod @@ -125,6 +125,10 @@ The connection uses the DTLSv1 protocol The connection uses the DTLSv1.2 protocol +=item DTLS1_3_VERSION + +The connection uses the DTLSv1.3 protocol + =item OSSL_QUIC1_VERSION The connection uses the QUICv1 protocol. From 174ba241d33ddb7cbd10e07b54ef5cce9e0e58dd Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Thu, 12 Oct 2023 14:35:37 +0200 Subject: [PATCH 09/16] Support TLS 1.3 kexs and groups with DTLS 1.3 --- providers/common/capabilities.c | 16 ++++++++-------- ssl/s3_lib.c | 22 +++++++++++----------- ssl/t1_lib.c | 5 ++++- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/providers/common/capabilities.c b/providers/common/capabilities.c index f7234615e4ca00..35b7dfa45673b6 100644 --- a/providers/common/capabilities.c +++ b/providers/common/capabilities.c @@ -86,15 +86,15 @@ static const TLS_GROUP_CONSTANTS group_list[] = { DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_x25519, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, { OSSL_TLS_GROUP_ID_x448, 224, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, - { OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, -1, -1 }, - { OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, -1, -1 }, - { OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, -1, -1 }, + { OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, /* Security bit values as given by BN_security_bits() */ - { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, -1, -1 }, - { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, -1, -1 }, - { OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, -1, -1 }, - { OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, -1, -1 }, - { OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, -1, -1 }, + { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, }; #define TLS_GROUP_ENTRY(tlsname, realname, algorithm, idx) \ diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 1f778c34234731..e29f81815b0a53 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -45,7 +45,7 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AES128GCM, SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, 0, + DTLS1_3_VERSION, DTLS1_3_VERSION, SSL_HIGH, SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 128, @@ -60,7 +60,7 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AES256GCM, SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, 0, + DTLS1_3_VERSION, DTLS1_3_VERSION, SSL_HIGH, SSL_HANDSHAKE_MAC_SHA384 | SSL_QUIC, 256, @@ -76,7 +76,7 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_CHACHA20POLY1305, SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, 0, + DTLS1_3_VERSION, DTLS1_3_VERSION, SSL_HIGH, SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 256, @@ -92,7 +92,7 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AES128CCM, SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, 0, + DTLS1_3_VERSION, DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_HIGH, SSL_HANDSHAKE_MAC_SHA256, 128, @@ -107,7 +107,7 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AES128CCM8, SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, 0, + DTLS1_3_VERSION, DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256, 64, /* CCM8 uses a short tag, so we have a low security strength */ @@ -3670,7 +3670,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) { unsigned int id; - if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc)) && sc->s3.did_kex) id = sc->s3.group_id; else id = sc->session->kex_group; @@ -4258,7 +4258,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl allow = srvr; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { #ifndef OPENSSL_NO_PSK size_t j; @@ -4298,7 +4298,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl * Since TLS 1.3 ciphersuites can be used with any auth or * key exchange scheme skip tests. */ - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { mask_k = s->s3.tmp.mask_k; mask_a = s->s3.tmp.mask_a; #ifndef OPENSSL_NO_SRP @@ -4841,7 +4841,7 @@ int ssl_gensecret(SSL_CONNECTION *s, unsigned char *pms, size_t pmslen) int rv = 0; /* SSLfatal() called as appropriate in the below functions */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) { /* * If we are resuming then we already generated the early secret * when we created the ClientHello, so don't recreate it. @@ -4884,7 +4884,7 @@ int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gense goto err; } - if (SSL_CONNECTION_IS_TLS13(s) && EVP_PKEY_is_a(privkey, "DH")) + if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && EVP_PKEY_is_a(privkey, "DH")) EVP_PKEY_CTX_set_dh_pad(pctx, 1); pms = OPENSSL_malloc(pmslen); @@ -5036,7 +5036,7 @@ const char *SSL_get0_group_name(SSL *s) if (sc == NULL) return NULL; - if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc)) && sc->s3.did_kex) id = sc->s3.group_id; else id = sc->session->kex_group; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 631e1fdef93cef..50a630fb7cdd38 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -865,6 +865,9 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, ret = DTLS_VERSION_LE(minversion, ginfo->maxdtls); if (ginfo->mindtls > 0) ret &= DTLS_VERSION_GE(maxversion, ginfo->mindtls); + if (ret && okfortls13 != NULL && maxversion == DTLS1_3_VERSION) + *okfortls13 = (ginfo->maxdtls == 0) + || DTLS_VERSION_GE(ginfo->maxdtls, DTLS1_3_VERSION); } else { if (ginfo->mintls < 0 || ginfo->maxtls < 0) return 0; @@ -1207,7 +1210,7 @@ static int tls1_check_pkey_comp(SSL_CONNECTION *s, EVP_PKEY *pkey) return 0; if (point_conv == POINT_CONVERSION_UNCOMPRESSED) { comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; - } else if (SSL_CONNECTION_IS_TLS13(s)) { + } else if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { /* * ec_point_formats extension is not used in TLSv1.3 so we ignore * this check. From de3acd0596b0edf1a38f39bec5887fcb445e1cce Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Fri, 13 Oct 2023 11:26:35 +0200 Subject: [PATCH 10/16] Fix protocol list for cmd_Protocol() --- ssl/ssl_conf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index a9ef6854b82ef8..c95a890d4ceaa2 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -285,7 +285,8 @@ static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2), SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3), SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1), - SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2) + SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2), + SSL_FLAG_TBL_INV("DTLSv1.3", SSL_OP_NO_DTLSv1_3) }; cctx->tbl = ssl_protocol_list; cctx->ntbl = OSSL_NELEM(ssl_protocol_list); From 4749081a094b8aa735c033cce465f2a3c41d97e3 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Fri, 13 Oct 2023 12:21:47 +0200 Subject: [PATCH 11/16] Correct traces for crtificates in dtls13 --- ssl/t1_trce.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index b05012f74fd671..ecdd2132d46baa 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -1344,7 +1344,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server { size_t clen; - if (SSL_CONNECTION_IS_TLS13(sc) + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc)) && !ssl_print_hexbuf(bio, indent, "context", 1, &msg, &msglen)) return 0; @@ -1358,7 +1358,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server || (!server && sc->ext.client_cert_type == TLSEXT_cert_type_rpk)) { if (!ssl_print_raw_public_key(bio, &sc->ssl, server, indent, &msg, &clen)) return 0; - if (SSL_CONNECTION_IS_TLS13(sc) + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc)) && !ssl_print_extensions(bio, indent + 2, server, SSL3_MT_CERTIFICATE, &msg, &clen)) return 0; @@ -1369,7 +1369,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server while (clen > 0) { if (!ssl_print_certificate(bio, sc, indent + 2, &msg, &clen)) return 0; - if (SSL_CONNECTION_IS_TLS13(sc) + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc)) && !ssl_print_extensions(bio, indent + 2, server, SSL3_MT_CERTIFICATE, &msg, &clen)) return 0; @@ -1455,7 +1455,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc size_t xlen; unsigned int sigalg; - if (SSL_CONNECTION_IS_TLS13(sc)) { + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc))) { if (!ssl_print_hexbuf(bio, indent, "request_context", 1, &msg, &msglen)) return 0; if (!ssl_print_extensions(bio, indent, 1, @@ -1530,7 +1530,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc xlen -= dlen + 2; msg += dlen; } - if (SSL_CONNECTION_IS_TLS13(sc)) { + if ((SSL_CONNECTION_IS_TLS13(sc) || SSL_CONNECTION_IS_DTLS13(sc))) { if (!ssl_print_hexbuf(bio, indent, "request_extensions", 2, &msg, &msglen)) return 0; From c70f3325529724aeebfdc2b999be59f8de01838a Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Fri, 24 Nov 2023 11:03:32 +0100 Subject: [PATCH 12/16] Adds DTLS 1.3 functionality to s_client and s_server documentation. --- doc/man1/openssl-s_client.pod.in | 25 +++++++++---------- doc/man1/openssl-s_server.pod.in | 41 ++++++++++++++++---------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 84cf6fdd81f1f5..60f171d5958d9a 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -542,13 +542,13 @@ This option must be provided in order to use a PSK cipher. =item B<-psk_session> I Use the pem encoded SSL_SESSION data stored in I as the basis of a PSK. -Note that this will only work if TLSv1.3 is negotiated. +Note that this will only work if (D)TLSv1.3 is negotiated. =item B<-sctp> Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in -conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only -available where OpenSSL has support for SCTP enabled. +conjunction with B<-dtls>, B<-dtls1>, B<-dtls1_2> or B<-dtls1_3>. This option +is only available where OpenSSL has support for SCTP enabled. =item B<-sctp_label_bug> @@ -618,11 +618,11 @@ option enables various workarounds. =item B<-no_tx_cert_comp> -Disables support for sending TLSv1.3 compressed certificates. +Disables support for sending (D)TLSv1.3 compressed certificates. =item B<-no_rx_cert_comp> -Disables support for receiving TLSv1.3 compressed certificate. +Disables support for receiving (D)TLSv1.3 compressed certificate. =item B<-comp> @@ -743,7 +743,8 @@ for example "http/1.1" or "spdy/3". An empty list of protocols is treated specially and will cause the client to advertise support for the TLS extension but disconnect just after receiving ServerHello with a list of server supported protocols. -The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used. +The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> or B<-dtls1_3> is +used. =item B<-ct>, B<-noct> @@ -773,8 +774,8 @@ data and when the server accepts the early data. =item B<-enable_pha> -For TLSv1.3 only, send the Post-Handshake Authentication extension. This will -happen whether or not a certificate has been provided via B<-cert>. +For (D)TLSv1.3 only, send the Post-Handshake Authentication extension. This +will happen whether or not a certificate has been provided via B<-cert>. =item B<-use_srtp> I @@ -884,7 +885,7 @@ End the current SSL connection and exit. =item B -Renegotiate the SSL session (TLSv1.2 and below only). +Renegotiate the SSL session ((D)TLSv1.2 and below only). =item B @@ -892,11 +893,11 @@ Attempt to reconnect to the server using a resumption handshake. =item B -Send a key update message to the server (TLSv1.3 only) +Send a key update message to the server ((D)TLSv1.3 only) =item B -Send a key update message to the server and request one back (TLSv1.3 only) +Send a key update message to the server and request one back ((D)TLSv1.3 only) =back @@ -937,7 +938,7 @@ Reconnect to the peer and attempt a resumption handshake =item B -Send a Key Update message. TLSv1.3 only. This command takes an optional +Send a Key Update message. (D)TLSv1.3 only. This command takes an optional argument. If the argument "req" is supplied then the peer is also requested to update its keys. Otherwise if "noreq" is supplied the the peer is not requested to update its keys. The default is "req". diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in index 611b410cfd63c8..257f500c74a4ae 100644 --- a/doc/man1/openssl-s_server.pod.in +++ b/doc/man1/openssl-s_server.pod.in @@ -612,11 +612,11 @@ option enables various workarounds. =item B<-no_tx_cert_comp> -Disables support for sending TLSv1.3 compressed certificates. +Disables support for sending (D)TLSv1.3 compressed certificates. =item B<-no_rx_cert_comp> -Disables support for receiving TLSv1.3 compressed certificates. +Disables support for receiving (D)TLSv1.3 compressed certificates. =item B<-no_comp> @@ -633,14 +633,14 @@ OpenSSL 1.1.0. =item B<-no_ticket> -Disable RFC4507bis session ticket support. This option has no effect if TLSv1.3 -is negotiated. See B<-num_tickets>. +Disable RFC4507bis session ticket support. This option has no effect if +(D)TLSv1.3 is negotiated. See B<-num_tickets>. =item B<-num_tickets> Control the number of tickets that will be sent to the client after a full -handshake in TLSv1.3. The default number of tickets is 2. This option does not -affect the number of tickets sent after a resumption handshake. +handshake in (D)TLSv1.3. The default number of tickets is 2. This option does +not affect the number of tickets sent after a resumption handshake. =item B<-serverpref> @@ -751,8 +751,8 @@ connect to that peer and complete the handshake. =item B<-sctp> Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in -conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only -available where OpenSSL has support for SCTP enabled. +conjunction with B<-dtls>, B<-dtls1>, B<-dtls1_2> or B<-dtls1_3>. This option +is only available where OpenSSL has support for SCTP enabled. =item B<-sctp_label_bug> @@ -780,7 +780,8 @@ The I list is a comma-separated list of supported protocol names. The list should contain the most desirable protocols first. Protocol names are printable ASCII strings, for example "http/1.1" or "spdy/3". -The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used. +The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> or B<-dtls1_3> +is used. =item B<-ktls> @@ -828,16 +829,16 @@ B<-WWW>, B<-HTTP> or B<-rev>. =item B<-stateless> -Require TLSv1.3 cookies. +Require (D)TLSv1.3 cookies. =item B<-anti_replay>, B<-no_anti_replay> Switches replay protection on or off, respectively. Replay protection is on by default unless overridden by a configuration file. When it is on, OpenSSL will -automatically detect if a session ticket has been used more than once, TLSv1.3 -has been negotiated, and early data is enabled on the server. A full handshake -is forced if a session ticket is used a second or subsequent time. Any early -data that was sent will be rejected. +automatically detect if a session ticket has been used more than once, +(D)TLSv1.3 has been negotiated, and early data is enabled on the server. A full +handshake is forced if a session ticket is used a second or subsequent time. +Any early data that was sent will be rejected. =item B<-tfo> @@ -913,12 +914,12 @@ End the current SSL connection and exit. =item B -Renegotiate the SSL session (TLSv1.2 and below only). +Renegotiate the SSL session ((D)TLSv1.2 and below only). =item B -Renegotiate the SSL session and request a client certificate (TLSv1.2 and below -only). +Renegotiate the SSL session and request a client certificate ((D)TLSv1.2 and +below only). =item B

@@ -931,15 +932,15 @@ Print out some session cache status information. =item B -Send a key update message to the client (TLSv1.3 only) +Send a key update message to the client ((D)TLSv1.3 only). =item B -Send a key update message to the client and request one back (TLSv1.3 only) +Send a key update message to the client and request one back ((D)TLSv1.3 only). =item B -Send a certificate request to the client (TLSv1.3 only) +Send a certificate request to the client ((D)TLSv1.3 only). =back From 70342ecb5fe8061fff9f3b883c2ca1110a9c48ae Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Tue, 3 Oct 2023 13:19:42 +0200 Subject: [PATCH 13/16] Support TLS1.3 extensions with DTLS1.3 --- ssl/statem/extensions.c | 65 ++++++++++++++++++------------------ ssl/statem/extensions_clnt.c | 48 ++++++++++++++------------ ssl/statem/extensions_srvr.c | 42 ++++++++++++----------- 3 files changed, 83 insertions(+), 72 deletions(-) diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 0a64ca2246987e..b7a8be29199730 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -188,7 +188,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * to indicate to the client the complete list of groups supported * by the server, with the server instead just indicating the * selected group for this connection in the ServerKeyExchange - * message. TLS 1.3 adds a scheme for the server to indicate + * message. (D)TLS 1.3 adds a scheme for the server to indicate * to the client its list of supported groups in the * EncryptedExtensions message, but none of the relevant * specifications permit sending supported_groups in the ServerHello. @@ -198,7 +198,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * ServerHello anyway. Up to and including the 1.1.0 release, * we did not check for the presence of nonpermitted extensions, * so to avoid a regression, we must permit this extension in the - * TLS 1.2 ServerHello as well. + * (D)TLS 1.2 ServerHello as well. * * Note that there is no tls_parse_stoc_supported_groups function, * so we do not perform any additional parsing, validation, or @@ -339,7 +339,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { { TLSEXT_TYPE_supported_versions, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY, + | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, NULL, /* Processed inline as part of version selection */ NULL, tls_parse_stoc_supported_versions, @@ -348,8 +348,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { }, { TLSEXT_TYPE_psk_kex_modes, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS_IMPLEMENTATION_ONLY - | SSL_EXT_TLS1_3_ONLY, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ONLY, init_psk_kex_modes, tls_parse_ctos_psk_kex_modes, NULL, NULL, tls_construct_ctos_psk_kex_modes, NULL }, @@ -360,7 +359,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { */ TLSEXT_TYPE_key_share, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY + | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS1_3_ONLY, NULL, tls_parse_ctos_key_share, tls_parse_stoc_key_share, tls_construct_stoc_key_share, tls_construct_ctos_key_share, @@ -370,7 +369,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { /* Must be after key_share */ TLSEXT_TYPE_cookie, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, NULL, tls_parse_ctos_cookie, tls_parse_stoc_cookie, tls_construct_stoc_cookie, tls_construct_ctos_cookie, NULL }, @@ -388,7 +387,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { { TLSEXT_TYPE_compress_certificate, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, tls_init_compress_certificate, tls_parse_compress_certificate, tls_parse_compress_certificate, tls_construct_compress_certificate, tls_construct_compress_certificate, @@ -420,10 +419,10 @@ static const EXTENSION_DEFINITION ext_defs[] = { NULL, NULL, NULL, tls_construct_ctos_padding, NULL }, { - /* Required by the TLSv1.3 spec to always be the last extension */ + /* Required by the (D)TLSv1.3 spec to always be the last extension */ TLSEXT_TYPE_psk, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk, tls_construct_ctos_psk, final_psk } @@ -554,33 +553,33 @@ static int verify_extension(SSL_CONNECTION *s, unsigned int context, int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx) { - int is_tls13; + int is_tls13_or_dtls13; /* * For HRR we haven't selected the version yet but we know it will be - * TLSv1.3 + * (D)TLSv1.3 */ if ((thisctx & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) - is_tls13 = 1; + is_tls13_or_dtls13 = 1; else - is_tls13 = SSL_CONNECTION_IS_TLS13(s); + is_tls13_or_dtls13 = SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s); if ((SSL_CONNECTION_IS_DTLS(s) && (extctx & SSL_EXT_TLS_IMPLEMENTATION_ONLY) != 0) || (s->version == SSL3_VERSION && (extctx & SSL_EXT_SSL3_ALLOWED) == 0) /* - * Note that SSL_IS_TLS13() means "TLS 1.3 has been negotiated", + * Note that is_tls13_or_dtls13 means "(D)TLS 1.3 has been negotiated", * which is never true when generating the ClientHello. * However, version negotiation *has* occurred by the time the * ClientHello extensions are being parsed. - * Be careful to allow TLS 1.3-only extensions when generating + * Be careful to allow (D)TLS 1.3-only extensions when generating * the ClientHello. */ - || (is_tls13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0) - || (!is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0 + || (is_tls13_or_dtls13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0) + || (!is_tls13_or_dtls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) == 0) - || (s->server && !is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0) + || (s->server && !is_tls13_or_dtls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0) || (s->hit && (extctx & SSL_EXT_IGNORE_ON_RESUMPTION) != 0)) return 0; return 1; @@ -831,7 +830,8 @@ 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) || max_version < TLS1_3_VERSION))) + && (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_LT(max_version, DTLS1_3_VERSION) + : max_version < TLS1_3_VERSION))) return 0; return 1; @@ -858,7 +858,7 @@ int tls_construct_extensions(SSL_CONNECTION *s, WPACKET *pkt, /* * If extensions are of zero length then we don't even add the * extensions length bytes to a ClientHello/ServerHello - * (for non-TLSv1.3). + * (for non-(D)TLSv1.3). */ || ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0 @@ -1069,8 +1069,8 @@ static int final_server_name(SSL_CONNECTION *s, unsigned int context, int sent) return 0; case SSL_TLSEXT_ERR_ALERT_WARNING: - /* TLSv1.3 doesn't have warning alerts so we suppress this */ - if (!SSL_CONNECTION_IS_TLS13(s)) + /* (D)TLSv1.3 doesn't have warning alerts so we suppress this */ + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) ssl3_send_alert(s, SSL3_AL_WARNING, altmp); s->servername_done = 0; return 1; @@ -1177,15 +1177,15 @@ static int final_alpn(SSL_CONNECTION *s, unsigned int context, int sent) if (!s->server && !sent && s->session->ext.alpn_selected != NULL) s->ext.early_data_ok = 0; - if (!s->server || !SSL_CONNECTION_IS_TLS13(s)) + if (!s->server || !(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) return 1; /* * Call alpn_select callback if needed. Has to be done after SNI and - * cipher negotiation (HTTP/2 restricts permitted ciphers). In TLSv1.3 + * cipher negotiation (HTTP/2 restricts permitted ciphers). In (D)TLSv1.3 * we also have to do this before we decide whether to accept early_data. - * In TLSv1.3 we've already negotiated our cipher so we do this call now. - * For < TLSv1.3 we defer it until after cipher negotiation. + * In (D)TLSv1.3 we've already negotiated our cipher so we do this call now. + * For < (D)TLSv1.3 we defer it until after cipher negotiation. * * On failure SSLfatal() already called. */ @@ -1337,7 +1337,7 @@ static int init_srtp(SSL_CONNECTION *s, unsigned int context) static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent) { - if (!sent && SSL_CONNECTION_IS_TLS13(s) && !s->hit) { + if (!sent && (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && !s->hit) { SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_R_MISSING_SIGALGS_EXTENSION); return 0; @@ -1349,7 +1349,7 @@ static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent) static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) { #if !defined(OPENSSL_NO_TLS1_3) - if (!SSL_CONNECTION_IS_TLS13(s)) + if (!(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) return 1; /* Nothing to do for key_share in an HRR */ @@ -1447,13 +1447,14 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) */ for (i = 0; i < num_groups; i++) { group_id = pgroups[i]; - + const int 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, TLS1_3_VERSION, - TLS1_3_VERSION, 0, NULL)) + && tls_valid_group(s, group_id, version, + version, 0, NULL)) break; } diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 381a6c9d7b9099..86944e3bb479a9 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -199,11 +199,12 @@ 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)) + && (!SSL_CONNECTION_IS_DTLS(s) && max_version < TLS1_3_VERSION) + && (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) return EXT_RETURN_NOT_SENT; /* @@ -230,7 +231,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) + if ((okfortls13 && max_version == TLS1_3_VERSION) || (okfortls13 && max_version == DTLS1_3_VERSION)) tls13added++; added++; } @@ -244,7 +245,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) { + 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 +265,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) { @@ -542,10 +544,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 ((!SSL_CONNECTION_IS_DTLS(s) && max_version < TLS1_3_VERSION) + || (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions) @@ -687,7 +689,8 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, 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, + const int 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 +768,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; @@ -797,7 +801,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 +810,11 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } psksess = SSL_SESSION_new(); + const int 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 +946,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 +1016,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 +1424,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 +1747,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; @@ -1809,10 +1814,11 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if (group_id == pgroups[i]) break; } + + const int 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; } diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 64ccb3ed6d1bef..4fd140333919b5 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -133,10 +133,10 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, } /* - * In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3 + * In (D)TLSv1.2 and below the SNI is associated with the session. In (D)TLSv1.3 * we always use the SNI value from the handshake. */ - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) { SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION); return 0; @@ -161,9 +161,9 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, s->servername_done = 1; } else { /* - * In TLSv1.2 and below we should check if the SNI is consistent between - * the initial handshake and the resumption. In TLSv1.3 SNI is not - * associated with the session. + * In (D)TLSv1.2 and below we should check if the SNI is consistent + * between the initial handshake and the resumption. In (D)TLSv1.3 SNI + * is not associated with the session. */ s->servername_done = (s->session->ext.hostname != NULL) && PACKET_equal(&hostname, s->session->ext.hostname, @@ -664,13 +664,14 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, } /* Check if this share is for a group we can use */ + const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!check_in_list(s, group_id, srvrgroups, srvr_num_groups, 1) || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) /* * We tolerate but ignore a group id that we don't think is - * suitable for TLSv1.3 + * suitable for (D)TLSv1.3 */ - || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, + || !tls_valid_group(s, group_id, version, version, 0, NULL)) { /* Share not suitable */ continue; @@ -788,7 +789,7 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - 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; @@ -924,7 +925,7 @@ int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt, return 0; } - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || (SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) { OPENSSL_free(s->ext.peer_supportedgroups); s->ext.peer_supportedgroups = NULL; s->ext.peer_supportedgroups_len = 0; @@ -1069,7 +1070,7 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, /* * 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) { @@ -1079,12 +1080,13 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } sess = SSL_SESSION_new(); + const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (sess == NULL || !SSL_SESSION_set1_master_key(sess, pskdata, pskdatalen) || !SSL_SESSION_set_cipher(sess, cipher) || !SSL_SESSION_set_protocol_version(sess, - TLS1_3_VERSION)) { + version)) { OPENSSL_cleanse(pskdata, pskdatalen); SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -1291,10 +1293,10 @@ EXT_RETURN tls_construct_stoc_server_name(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_NOT_SENT; /* - * Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming. + * Prior to (D)TLSv1.3 we ignore any SNI in the current handshake if resuming. * We just use the servername from the initial handshake. */ - if (s->hit && !SSL_CONNECTION_IS_TLS13(s)) + if (s->hit && !(SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s))) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) @@ -1445,7 +1447,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, if (!s->ext.status_expected) return EXT_RETURN_NOT_SENT; - if (SSL_CONNECTION_IS_TLS13(s) && chainidx != 0) + if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) && chainidx != 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) @@ -1455,11 +1457,12 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, } /* - * In TLSv1.3 we include the certificate status itself. In <= TLSv1.2 we + * In (D)TLSv1.3 we include the certificate status itself. In <= (D)TLSv1.2 we * send back an empty extension, with the certificate status appearing as a * separate message */ - if (SSL_CONNECTION_IS_TLS13(s) && !tls_construct_cert_status_body(s, pkt)) { + if ((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)) + && !tls_construct_cert_status_body(s, pkt)) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; } @@ -1595,7 +1598,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL_CONNECTION *s, WPACKET *pkt unsigned int context, X509 *x, size_t chainidx) { - if (!ossl_assert(SSL_CONNECTION_IS_TLS13(s))) { + if (!ossl_assert((SSL_CONNECTION_IS_TLS13(s) || SSL_CONNECTION_IS_DTLS13(s)))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1766,13 +1769,14 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } + const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_get_total_written(pkt, &startlen) || !WPACKET_reserve_bytes(pkt, MAX_COOKIE_SIZE, &cookie) || !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION) - || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION) + || !WPACKET_put_bytes_u16(pkt, version) || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) || !ssl->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &ciphlen) @@ -1968,7 +1972,7 @@ EXT_RETURN tls_construct_stoc_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, /* * Note: only supposed to send this if we are going to do a cert request, - * but TLSv1.3 could do a PHA request if the client supports it + * but (D)TLSv1.3 could do a PHA request if the client supports it */ if ((!send_certificate_request(sc) && sc->post_handshake_auth != SSL_PHA_EXT_RECEIVED) || sc->ext.client_cert_type_ctos != OSSL_CERT_TYPE_CTOS_GOOD From d791d9d18d2548d59b7b4cc1ca207d3bbe37d9ea Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Fri, 24 Nov 2023 11:40:10 +0100 Subject: [PATCH 14/16] Fix style nits --- ssl/statem/extensions.c | 5 ++++- ssl/statem/extensions_clnt.c | 13 ++++++++++--- ssl/statem/extensions_srvr.c | 10 +++++++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index b7a8be29199730..e47841dd0dcb9e 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1446,9 +1446,12 @@ 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++) { + const int version; + group_id = pgroups[i]; - const int version = SSL_CONNECTION_IS_DTLS(s) ? + 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, diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 86944e3bb479a9..ba23e15576583e 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -686,10 +686,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++) { + const int version; + if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) continue; - const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_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; @@ -791,6 +794,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; + const int version; idlen = strlen(identity); if (idlen > PSK_MAX_IDENTITY_LEN) { @@ -810,7 +814,8 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } psksess = SSL_SESSION_new(); - const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + 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) @@ -1793,6 +1798,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; + const int version; if (PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -1815,7 +1821,8 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, break; } - const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + 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)) { diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 4fd140333919b5..d94bfb0c776040 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -632,6 +632,7 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, } while (PACKET_remaining(&key_share_list) > 0) { + const int version; if (!PACKET_get_net_2(&key_share_list, &group_id) || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt) || PACKET_remaining(&encoded_pt) == 0) { @@ -663,8 +664,9 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, return 0; } + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + /* Check if this share is for a group we can use */ - const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!check_in_list(s, group_id, srvrgroups, srvr_num_groups, 1) || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) /* @@ -1067,6 +1069,7 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } else if (pskdatalen > 0) { const SSL_CIPHER *cipher; const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; + const int version; /* * We found a PSK using an old style callback. We don't know @@ -1080,7 +1083,8 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } sess = SSL_SESSION_new(); - const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (sess == NULL || !SSL_SESSION_set1_master_key(sess, pskdata, pskdatalen) @@ -1760,6 +1764,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, int ret = EXT_RETURN_FAIL; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); SSL *ssl = SSL_CONNECTION_GET_SSL(s); + const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return EXT_RETURN_NOT_SENT; @@ -1769,7 +1774,6 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u16(pkt) From 355fbe924011043b0c8f57b75d27f297b3734544 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Fri, 24 Nov 2023 11:54:51 +0100 Subject: [PATCH 15/16] Fix wrong check for (d)tls version below 1.3 --- ssl/statem/extensions_clnt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index ba23e15576583e..9cdeab93370cbe 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -203,8 +203,8 @@ 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) - && (!SSL_CONNECTION_IS_DTLS(s) && max_version < TLS1_3_VERSION) - && (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION))) + && ((!SSL_CONNECTION_IS_DTLS(s) && max_version < TLS1_3_VERSION) + || (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION)))) return EXT_RETURN_NOT_SENT; /* From b1a4b12130b388068b99d92a8588da087e0aee29 Mon Sep 17 00:00:00 2001 From: Frederik Wedel-Heinen Date: Fri, 24 Nov 2023 11:57:49 +0100 Subject: [PATCH 16/16] Fix line breaks --- ssl/statem/extensions_clnt.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 9cdeab93370cbe..f84d979e3a1a68 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) { @@ -203,8 +204,8 @@ 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) - && ((!SSL_CONNECTION_IS_DTLS(s) && max_version < TLS1_3_VERSION) - || (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION)))) + && ((!isdtls && max_version < TLS1_3_VERSION) + || (isdtls && DTLS_VERSION_LT(max_version, DTLS1_3_VERSION)))) return EXT_RETURN_NOT_SENT; /* @@ -231,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) || (okfortls13 && max_version == DTLS1_3_VERSION)) + if ((okfortls13 && max_version == TLS1_3_VERSION) + || (okfortls13 && max_version == DTLS1_3_VERSION)) tls13added++; added++; } @@ -245,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 || max_version == DTLS1_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;