summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libssl/ssl_clnt.c20
-rw-r--r--lib/libssl/ssl_locl.h26
-rw-r--r--lib/libssl/ssl_pkt.c7
-rw-r--r--lib/libssl/ssl_sigalgs.c8
-rw-r--r--lib/libssl/ssl_srvr.c21
-rw-r--r--lib/libssl/ssl_tlsext.c116
-rw-r--r--lib/libssl/ssl_versions.c26
-rw-r--r--lib/libssl/tls13_client.c20
-rw-r--r--lib/libssl/tls13_server.c9
9 files changed, 145 insertions, 108 deletions
diff --git a/lib/libssl/ssl_clnt.c b/lib/libssl/ssl_clnt.c
index 70bda982c65..97418f1ac74 100644
--- a/lib/libssl/ssl_clnt.c
+++ b/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.84 2021/02/22 15:59:10 jsing Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.85 2021/03/10 18:27:01 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -218,7 +218,14 @@ ssl3_connect(SSL *s)
goto end;
}
- /* s->version=SSL3_VERSION; */
+ if (!ssl_supported_tls_version_range(s,
+ &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
+ SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
+ ret = -1;
+ goto end;
+ }
+
s->internal->type = SSL_ST_CONNECT;
if (!ssl3_setup_init_buffer(s)) {
@@ -904,6 +911,12 @@ ssl3_get_server_hello(SSL *s)
}
s->version = server_version;
+ S3I(s)->hs.negotiated_tls_version = ssl_tls_version(server_version);
+ if (S3I(s)->hs.negotiated_tls_version == 0) {
+ SSLerror(s, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if ((method = ssl_get_method(server_version)) == NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
@@ -1019,7 +1032,7 @@ ssl3_get_server_hello(SSL *s)
/* TLS v1.2 only ciphersuites require v1.2 or later. */
if ((cipher->algorithm_ssl & SSL_TLSV1_2) &&
- (TLS1_get_version(s) < TLS1_2_VERSION)) {
+ S3I(s)->hs.negotiated_tls_version < TLS1_2_VERSION) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerror(s, SSL_R_WRONG_CIPHER_RETURNED);
goto fatal_err;
@@ -1982,6 +1995,7 @@ ssl3_send_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
goto err;
}
+ /* XXX - our max protocol version. */
pms[0] = s->client_version >> 8;
pms[1] = s->client_version & 0xff;
arc4random_buf(&pms[2], sizeof(pms) - 2);
diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h
index b2af8fd7c96..6f66a8932e7 100644
--- a/lib/libssl/ssl_locl.h
+++ b/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.324 2021/02/27 14:20:50 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.325 2021/03/10 18:27:01 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -407,6 +407,23 @@ typedef struct ssl_session_internal_st {
#define SSI(s) (s->session->internal)
typedef struct ssl_handshake_st {
+ /*
+ * Minimum and maximum versions supported for this handshake. These are
+ * initialised at the start of a handshake based on the method in use
+ * and the current protocol version configuration.
+ */
+ uint16_t our_min_tls_version;
+ uint16_t our_max_tls_version;
+
+ /*
+ * Version negotiated for this session. For a client this is set once
+ * the server selected version is parsed from the ServerHello (either
+ * from the legacy version or supported versions extension). For a
+ * server this is set once we select the version we will use with the
+ * client.
+ */
+ uint16_t negotiated_tls_version;
+
/* state contains one of the SSL3_ST_* values. */
int state;
@@ -435,10 +452,6 @@ typedef struct cert_pkey_st {
} CERT_PKEY;
typedef struct ssl_handshake_tls13_st {
- uint16_t min_version;
- uint16_t max_version;
- uint16_t version;
-
int use_legacy;
int hrr;
@@ -468,7 +481,6 @@ typedef struct ssl_handshake_tls13_st {
EVP_MD_CTX *clienthello_md_ctx;
unsigned char *clienthello_hash;
unsigned int clienthello_hash_len;
-
} SSL_HANDSHAKE_TLS13;
struct tls12_record_layer;
@@ -1117,6 +1129,8 @@ int ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver,
uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver);
int ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
int ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
+uint16_t ssl_tls_version(uint16_t version);
+uint16_t ssl_effective_tls_version(SSL *s);
int ssl_downgrade_max_version(SSL *s, uint16_t *max_ver);
int ssl_max_supported_version(SSL *s, uint16_t *max_ver);
int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver);
diff --git a/lib/libssl/ssl_pkt.c b/lib/libssl/ssl_pkt.c
index 894064c8179..5b1af504fb5 100644
--- a/lib/libssl/ssl_pkt.c
+++ b/lib/libssl/ssl_pkt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_pkt.c,v 1.36 2021/02/20 14:14:16 tb Exp $ */
+/* $OpenBSD: ssl_pkt.c,v 1.37 2021/03/10 18:27:02 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -561,8 +561,9 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
* bytes and record version number > TLS 1.0.
*/
version = s->version;
- if (S3I(s)->hs.state == SSL3_ST_CW_CLNT_HELLO_B && !s->internal->renegotiate &&
- TLS1_get_version(s) > TLS1_VERSION)
+ if (S3I(s)->hs.state == SSL3_ST_CW_CLNT_HELLO_B &&
+ !s->internal->renegotiate &&
+ S3I(s)->hs.our_max_tls_version > TLS1_VERSION)
version = TLS1_VERSION;
/*
diff --git a/lib/libssl/ssl_sigalgs.c b/lib/libssl/ssl_sigalgs.c
index 1b5aad72f7b..68bb6a38896 100644
--- a/lib/libssl/ssl_sigalgs.c
+++ b/lib/libssl/ssl_sigalgs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_sigalgs.c,v 1.22 2020/10/11 01:13:04 guenther Exp $ */
+/* $OpenBSD: ssl_sigalgs.c,v 1.23 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
*
@@ -265,7 +265,7 @@ ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
int check_curve = 0;
CBS cbs;
- if (TLS1_get_version(s) >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
check_curve = 1;
@@ -291,7 +291,7 @@ ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
* RFC 5246 allows a TLS 1.2 client to send no sigalgs, in
* which case the server must use the the default.
*/
- if (TLS1_get_version(s) < TLS1_3_VERSION &&
+ if (S3I(s)->hs.negotiated_tls_version < TLS1_3_VERSION &&
S3I(s)->hs.sigalgs == NULL) {
switch (pkey->type) {
case EVP_PKEY_RSA:
@@ -323,7 +323,7 @@ ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
continue;
/* RSA cannot be used without PSS in TLSv1.3. */
- if (TLS1_get_version(s) >= TLS1_3_VERSION &&
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION &&
sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
continue;
diff --git a/lib/libssl/ssl_srvr.c b/lib/libssl/ssl_srvr.c
index be9c27f73f8..373a20d61b4 100644
--- a/lib/libssl/ssl_srvr.c
+++ b/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_srvr.c,v 1.95 2021/02/20 14:16:56 tb Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.96 2021/03/10 18:27:02 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -219,6 +219,14 @@ ssl3_accept(SSL *s)
goto end;
}
+ if (!ssl_supported_tls_version_range(s,
+ &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
+ SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
+ ret = -1;
+ goto end;
+ }
+
s->internal->type = SSL_ST_ACCEPT;
if (!ssl3_setup_init_buffer(s)) {
@@ -844,7 +852,7 @@ ssl3_get_client_hello(SSL *s)
*/
if (!ssl_downgrade_max_version(s, &max_version))
goto err;
- if (ssl_max_shared_version(s, client_version, &shared_version) != 1) {
+ if (!ssl_max_shared_version(s, client_version, &shared_version)) {
if ((s->client_version >> 8) == SSL3_VERSION_MAJOR &&
!tls12_record_layer_write_protected(s->internal->rl)) {
/*
@@ -860,6 +868,12 @@ ssl3_get_client_hello(SSL *s)
s->client_version = client_version;
s->version = shared_version;
+ S3I(s)->hs.negotiated_tls_version = ssl_tls_version(shared_version);
+ if (S3I(s)->hs.negotiated_tls_version == 0) {
+ SSLerror(s, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if ((method = ssl_get_method(shared_version)) == NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
@@ -1718,6 +1732,8 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs)
int al = -1;
arc4random_buf(fakekey, sizeof(fakekey));
+
+ /* XXX - peer max protocol version. */
fakekey[0] = s->client_version >> 8;
fakekey[1] = s->client_version & 0xff;
@@ -1754,6 +1770,7 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs)
/* SSLerror(s, SSL_R_BAD_RSA_DECRYPT); */
}
+ /* XXX - peer max version. */
if ((al == -1) && !((pms[0] == (s->client_version >> 8)) &&
(pms[1] == (s->client_version & 0xff)))) {
/*
diff --git a/lib/libssl/ssl_tlsext.c b/lib/libssl/ssl_tlsext.c
index dca9de03050..4f4a39d4bb5 100644
--- a/lib/libssl/ssl_tlsext.c
+++ b/lib/libssl/ssl_tlsext.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_tlsext.c,v 1.86 2021/02/08 17:20:47 jsing Exp $ */
+/* $OpenBSD: ssl_tlsext.c,v 1.87 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -174,7 +174,7 @@ int
tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type)
{
return ssl_has_ecc_ciphers(s) ||
- (S3I(s)->hs_tls13.max_version >= TLS1_3_VERSION);
+ (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION);
}
int
@@ -472,7 +472,8 @@ tlsext_ri_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_ri_server_needs(SSL *s, uint16_t msg_type)
{
- return (s->version < TLS1_3_VERSION && S3I(s)->send_connection_binding);
+ return (S3I(s)->hs.negotiated_tls_version < TLS1_3_VERSION &&
+ S3I(s)->send_connection_binding);
}
int
@@ -554,7 +555,7 @@ tlsext_ri_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_sigalgs_client_needs(SSL *s, uint16_t msg_type)
{
- return (TLS1_get_client_version(s) >= TLS1_2_VERSION);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_2_VERSION);
}
int
@@ -564,8 +565,7 @@ tlsext_sigalgs_client_build(SSL *s, uint16_t msg_type, CBB *cbb)
size_t tls_sigalgs_len = tls12_sigalgs_len;
CBB sigalgs;
- if (TLS1_get_client_version(s) >= TLS1_3_VERSION &&
- S3I(s)->hs_tls13.min_version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.our_min_tls_version >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
}
@@ -600,7 +600,7 @@ tlsext_sigalgs_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_sigalgs_server_needs(SSL *s, uint16_t msg_type)
{
- return (s->version >= TLS1_3_VERSION);
+ return (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION);
}
int
@@ -610,7 +610,7 @@ tlsext_sigalgs_server_build(SSL *s, uint16_t msg_type, CBB *cbb)
size_t tls_sigalgs_len = tls12_sigalgs_len;
CBB sigalgs;
- if (s->version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
}
@@ -632,7 +632,7 @@ tlsext_sigalgs_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
{
CBS sigalgs;
- if (s->version < TLS1_3_VERSION)
+ if (ssl_effective_tls_version(s) < TLS1_3_VERSION)
return 0;
if (!CBS_get_u16_length_prefixed(cbs, &sigalgs))
@@ -981,7 +981,7 @@ tlsext_ocsp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_ocsp_server_needs(SSL *s, uint16_t msg_type)
{
- if (s->version >= TLS1_3_VERSION &&
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION &&
s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
s->ctx->internal->tlsext_status_cb != NULL) {
s->internal->tlsext_status_expected = 0;
@@ -998,7 +998,7 @@ tlsext_ocsp_server_build(SSL *s, uint16_t msg_type, CBB *cbb)
{
CBB ocsp_response;
- if (s->version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION) {
if (!CBB_add_u8(cbb, TLSEXT_STATUSTYPE_ocsp))
return 0;
if (!CBB_add_u24_length_prefixed(cbb, &ocsp_response))
@@ -1016,11 +1016,10 @@ tlsext_ocsp_server_build(SSL *s, uint16_t msg_type, CBB *cbb)
int
tlsext_ocsp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
{
- CBS response;
- uint16_t version = TLS1_get_client_version(s);
uint8_t status_type;
+ CBS response;
- if (version >= TLS1_3_VERSION) {
+ if (ssl_effective_tls_version(s) >= TLS1_3_VERSION) {
if (msg_type == SSL_TLSEXT_MSG_CR) {
/*
* RFC 8446, 4.4.2.1 - the server may request an OCSP
@@ -1406,11 +1405,7 @@ tlsext_srtp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_keyshare_client_needs(SSL *s, uint16_t msg_type)
{
- /* XXX once this gets initialized when we get tls13_client.c */
- if (S3I(s)->hs_tls13.max_version == 0)
- return 0;
- return (!SSL_is_dtls(s) && S3I(s)->hs_tls13.max_version >=
- TLS1_3_VERSION);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION);
}
int
@@ -1457,7 +1452,7 @@ tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
* Ignore this client share if we're using earlier than TLSv1.3
* or we've already selected a key share.
*/
- if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION)
+ if (S3I(s)->hs.our_max_tls_version < TLS1_3_VERSION)
continue;
if (S3I(s)->hs_tls13.key_share != NULL)
continue;
@@ -1485,10 +1480,8 @@ tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_keyshare_server_needs(SSL *s, uint16_t msg_type)
{
- if (SSL_is_dtls(s) || s->version < TLS1_3_VERSION)
- return 0;
-
- return tlsext_extension_seen(s, TLSEXT_TYPE_key_share);
+ return (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION &&
+ tlsext_extension_seen(s, TLSEXT_TYPE_key_share));
}
int
@@ -1550,9 +1543,7 @@ tlsext_keyshare_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_versions_client_needs(SSL *s, uint16_t msg_type)
{
- if (SSL_is_dtls(s))
- return 0;
- return (S3I(s)->hs_tls13.max_version >= TLS1_3_VERSION);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION);
}
int
@@ -1562,11 +1553,8 @@ tlsext_versions_client_build(SSL *s, uint16_t msg_type, CBB *cbb)
uint16_t version;
CBB versions;
- max = S3I(s)->hs_tls13.max_version;
- min = S3I(s)->hs_tls13.min_version;
-
- if (min < TLS1_VERSION)
- return 0;
+ max = S3I(s)->hs.our_max_tls_version;
+ min = S3I(s)->hs.our_min_tls_version;
if (!CBB_add_u8_length_prefixed(cbb, &versions))
return 0;
@@ -1591,8 +1579,8 @@ tlsext_versions_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
uint16_t max, min;
uint16_t matched_version = 0;
- max = S3I(s)->hs_tls13.max_version;
- min = S3I(s)->hs_tls13.min_version;
+ max = S3I(s)->hs.our_max_tls_version;
+ min = S3I(s)->hs.our_min_tls_version;
if (!CBS_get_u8_length_prefixed(cbs, &versions))
goto err;
@@ -1608,16 +1596,8 @@ tlsext_versions_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
matched_version = version;
}
- /*
- * XXX if we haven't matched a version we should
- * fail - but we currently need to succeed to
- * ignore this before the server code for 1.3
- * is set up and initialized.
- */
- if (max == 0)
- return 1; /* XXX */
-
- if (matched_version != 0) {
+ if (matched_version > 0) {
+ /* XXX - this should be stored for later processing. */
s->version = matched_version;
return 1;
}
@@ -1633,17 +1613,13 @@ tlsext_versions_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_versions_server_needs(SSL *s, uint16_t msg_type)
{
- return (!SSL_is_dtls(s) && s->version >= TLS1_3_VERSION);
+ return (S3I(s)->hs.negotiated_tls_version >= TLS1_3_VERSION);
}
int
tlsext_versions_server_build(SSL *s, uint16_t msg_type, CBB *cbb)
{
- if (!CBB_add_u16(cbb, TLS1_3_VERSION))
- return 0;
- /* XXX set 1.2 in legacy version? */
-
- return 1;
+ return CBB_add_u16(cbb, TLS1_3_VERSION);
}
int
@@ -1656,6 +1632,7 @@ tlsext_versions_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
return 0;
}
+ /* XXX - need to fix for DTLS 1.3 */
if (selected_version < TLS1_3_VERSION) {
*alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
@@ -1675,12 +1652,8 @@ tlsext_versions_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_cookie_client_needs(SSL *s, uint16_t msg_type)
{
- if (SSL_is_dtls(s))
- return 0;
- if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION)
- return 0;
- return (S3I(s)->hs_tls13.cookie_len > 0 &&
- S3I(s)->hs_tls13.cookie != NULL);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION &&
+ S3I(s)->hs_tls13.cookie_len > 0 && S3I(s)->hs_tls13.cookie != NULL);
}
int
@@ -1734,17 +1707,12 @@ tlsext_cookie_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
int
tlsext_cookie_server_needs(SSL *s, uint16_t msg_type)
{
-
- if (SSL_is_dtls(s))
- return 0;
- if (S3I(s)->hs_tls13.max_version < TLS1_3_VERSION)
- return 0;
/*
* Server needs to set cookie value in tls13 handshake
* in order to send one, should only be sent with HRR.
*/
- return (S3I(s)->hs_tls13.cookie_len > 0 &&
- S3I(s)->hs_tls13.cookie != NULL);
+ return (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION &&
+ S3I(s)->hs_tls13.cookie_len > 0 && S3I(s)->hs_tls13.cookie != NULL);
}
int
@@ -2033,13 +2001,10 @@ tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb)
const struct tls_extension *tlsext;
CBB extensions, extension_data;
int extensions_present = 0;
+ uint16_t tls_version;
size_t i;
- uint16_t version;
- if (is_server)
- version = s->version;
- else
- version = TLS1_get_client_version(s);
+ tls_version = ssl_effective_tls_version(s);
if (!CBB_add_u16_length_prefixed(cbb, &extensions))
return 0;
@@ -2049,7 +2014,7 @@ tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb)
ext = tlsext_funcs(tlsext, is_server);
/* RFC 8446 Section 4.2 */
- if (version >= TLS1_3_VERSION &&
+ if (tls_version >= TLS1_3_VERSION &&
!(tlsext->messages & msg_type))
continue;
@@ -2112,15 +2077,12 @@ tlsext_parse(SSL *s, int is_server, uint16_t msg_type, CBS *cbs, int *alert)
CBS extensions, extension_data;
uint16_t type;
size_t idx;
- uint16_t version;
+ uint16_t tls_version;
int alert_desc;
- S3I(s)->hs.extensions_seen = 0;
+ tls_version = ssl_effective_tls_version(s);
- if (is_server)
- version = s->version;
- else
- version = TLS1_get_client_version(s);
+ S3I(s)->hs.extensions_seen = 0;
/* An empty extensions block is valid. */
if (CBS_len(cbs) == 0)
@@ -2143,7 +2105,7 @@ tlsext_parse(SSL *s, int is_server, uint16_t msg_type, CBS *cbs, int *alert)
CBS_len(&extension_data),
s->internal->tlsext_debug_arg);
- if (!SSL_is_dtls(s) && version >= TLS1_3_VERSION && is_server &&
+ if (tls_version >= TLS1_3_VERSION && is_server &&
msg_type == SSL_TLSEXT_MSG_CH) {
if (!tlsext_clienthello_hash_extension(s, type,
&extension_data))
@@ -2155,7 +2117,7 @@ tlsext_parse(SSL *s, int is_server, uint16_t msg_type, CBS *cbs, int *alert)
continue;
/* RFC 8446 Section 4.2 */
- if (version >= TLS1_3_VERSION &&
+ if (tls_version >= TLS1_3_VERSION &&
!(tlsext->messages & msg_type)) {
alert_desc = SSL_AD_ILLEGAL_PARAMETER;
goto err;
diff --git a/lib/libssl/ssl_versions.c b/lib/libssl/ssl_versions.c
index a216de6e811..37957fd0ab4 100644
--- a/lib/libssl/ssl_versions.c
+++ b/lib/libssl/ssl_versions.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_versions.c,v 1.13 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: ssl_versions.c,v 1.14 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
@@ -171,6 +171,30 @@ ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
return 1;
}
+uint16_t
+ssl_tls_version(uint16_t version)
+{
+ if (version == TLS1_VERSION || version == TLS1_1_VERSION ||
+ version == TLS1_2_VERSION || version == TLS1_3_VERSION)
+ return version;
+
+ if (version == DTLS1_VERSION)
+ return TLS1_1_VERSION;
+ if (version == DTLS1_2_VERSION)
+ return TLS1_2_VERSION;
+
+ return 0;
+}
+
+uint16_t
+ssl_effective_tls_version(SSL *s)
+{
+ if (S3I(s)->hs.negotiated_tls_version > 0)
+ return S3I(s)->hs.negotiated_tls_version;
+
+ return S3I(s)->hs.our_max_tls_version;
+}
+
int
ssl_max_supported_version(SSL *s, uint16_t *max_ver)
{
diff --git a/lib/libssl/tls13_client.c b/lib/libssl/tls13_client.c
index a7c3bf2c001..4de3d3693bb 100644
--- a/lib/libssl/tls13_client.c
+++ b/lib/libssl/tls13_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_client.c,v 1.73 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: tls13_client.c,v 1.74 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
@@ -31,12 +31,12 @@ tls13_client_init(struct tls13_ctx *ctx)
size_t groups_len;
SSL *s = ctx->ssl;
- if (!ssl_supported_tls_version_range(s, &ctx->hs->min_version,
- &ctx->hs->max_version)) {
+ if (!ssl_supported_tls_version_range(s, &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return 0;
}
- s->client_version = s->version = ctx->hs->max_version;
+ s->client_version = s->version = S3I(s)->hs.our_max_tls_version;
tls13_record_layer_set_retry_after_phh(ctx->rl,
(s->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
@@ -64,7 +64,8 @@ tls13_client_init(struct tls13_ctx *ctx)
* legacy session identifier triggers compatibility mode (see RFC 8446
* Appendix D.4). In the pre-TLSv1.3 case a zero length value is used.
*/
- if (ctx->middlebox_compat && ctx->hs->max_version >= TLS1_3_VERSION) {
+ if (ctx->middlebox_compat &&
+ S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION) {
arc4random_buf(ctx->hs->legacy_session_id,
sizeof(ctx->hs->legacy_session_id));
ctx->hs->legacy_session_id_len =
@@ -91,7 +92,7 @@ tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb)
SSL *s = ctx->ssl;
/* Legacy client version is capped at TLS 1.2. */
- client_version = ctx->hs->max_version;
+ client_version = S3I(s)->hs.our_max_tls_version;
if (client_version > TLS1_2_VERSION)
client_version = TLS1_2_VERSION;
@@ -133,7 +134,9 @@ tls13_client_hello_build(struct tls13_ctx *ctx, CBB *cbb)
int
tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb)
{
- if (ctx->hs->min_version < TLS1_2_VERSION)
+ SSL *s = ctx->ssl;
+
+ if (S3I(s)->hs.our_min_tls_version < TLS1_2_VERSION)
tls13_record_layer_set_legacy_version(ctx->rl, TLS1_VERSION);
/* We may receive a pre-TLSv1.3 alert in response to the client hello. */
@@ -228,7 +231,7 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
goto err;
if (tls13_server_hello_is_legacy(cbs)) {
- if (ctx->hs->max_version >= TLS1_3_VERSION) {
+ if (S3I(s)->hs.our_max_tls_version >= TLS1_3_VERSION) {
/*
* RFC 8446 section 4.1.3: we must not downgrade if
* the server random value contains the TLS 1.2 or 1.1
@@ -280,6 +283,7 @@ tls13_server_hello_process(struct tls13_ctx *ctx, CBS *cbs)
ctx->alert = TLS13_ALERT_PROTOCOL_VERSION;
goto err;
}
+ S3I(s)->hs.negotiated_tls_version = ctx->hs->server_version;
/* The session_id must match. */
if (!CBS_mem_equal(&session_id, ctx->hs->legacy_session_id,
diff --git a/lib/libssl/tls13_server.c b/lib/libssl/tls13_server.c
index 715066fb591..29c63bcd06b 100644
--- a/lib/libssl/tls13_server.c
+++ b/lib/libssl/tls13_server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_server.c,v 1.70 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: tls13_server.c,v 1.71 2021/03/10 18:27:02 jsing Exp $ */
/*
* Copyright (c) 2019, 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2020 Bob Beck <beck@openbsd.org>
@@ -29,12 +29,12 @@ tls13_server_init(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
- if (!ssl_supported_tls_version_range(s, &ctx->hs->min_version,
- &ctx->hs->max_version)) {
+ if (!ssl_supported_tls_version_range(s, &S3I(s)->hs.our_min_tls_version,
+ &S3I(s)->hs.our_max_tls_version)) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return 0;
}
- s->version = ctx->hs->max_version;
+ s->version = S3I(s)->hs.our_max_tls_version;
tls13_record_layer_set_retry_after_phh(ctx->rl,
(s->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
@@ -163,6 +163,7 @@ tls13_client_hello_process(struct tls13_ctx *ctx, CBS *cbs)
goto err;
return tls13_use_legacy_server(ctx);
}
+ S3I(s)->hs.negotiated_tls_version = TLS1_3_VERSION;
/* Add decoded values to the current ClientHello hash */
if (!tls13_clienthello_hash_init(ctx)) {