diff options
author | Benjamin Kaduk <bkaduk@akamai.com> | 2021-03-16 07:47:09 -0700 |
---|---|---|
committer | Benjamin Kaduk <bkaduk@akamai.com> | 2021-05-15 15:09:07 -0700 |
commit | aa6bd216dd2691d1254eabcbd584691eb3b4b9b8 (patch) | |
tree | c666b319f00d45596172c847a1c365edcfc703fd /ssl/statem | |
parent | a8457b4c3d86a42209eabe90eddb605f59041f9e (diff) |
Promote SSL_get_negotiated_group() for non-TLSv1.3
It can be useful to know what group was used for the handshake's
key exchange process even on non-TLS 1.3 connections. Allow this
API, new in OpenSSL 3.0.0, to be used on other TLS versions as well.
Since pre-TLS-1.3 key exchange occurs only on full handshakes, this
necessitates adding a field to the SSL_SESSION object to carry the
group information across resumptions. The key exchange group in the
SSL_SESSION can also be relevant in TLS 1.3 when the resumption handshake
uses the "psk_ke" key-exchange mode, so also track whether a fresh key
exchange was done for TLS 1.3.
Since the new field is optional in the ASN.1 sense, there is no need
to increment SSL_SESSION_ASN1_VERSION (which incurs strong incompatibility
churn).
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14750)
Diffstat (limited to 'ssl/statem')
-rw-r--r-- | ssl/statem/extensions_clnt.c | 23 | ||||
-rw-r--r-- | ssl/statem/extensions_srvr.c | 3 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 2 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 4 |
4 files changed, 31 insertions, 1 deletions
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index b3ef1bc16a..fe9f8a9de6 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1793,6 +1793,28 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } + /* Retain this group in the SSL_SESSION */ + if (!s->hit) { + s->session->kex_group = group_id; + } else if (group_id != s->session->kex_group) { + /* + * If this is a resumption but changed what group was used, we need + * to record the new group in the session, but the session is not + * a new session and could be in use by other threads. So, make + * a copy of the session to record the new information so that it's + * useful for any sessions resumed from tickets issued on this + * connection. + */ + SSL_SESSION *new_sess; + + if ((new_sess = ssl_session_dup(s->session, 0)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + return 0; + } + SSL_SESSION_free(s->session); + s->session = new_sess; + s->session->kex_group = group_id; + } if ((ginf = tls1_group_id_lookup(s->ctx, group_id)) == NULL) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); @@ -1836,6 +1858,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } } + s->s3.did_kex = 1; #endif return 1; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index b2d7ff8f39..6b3b33e239 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -669,6 +669,8 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } s->s3.group_id = group_id; + /* Cache the selected group ID in the SSL_SESSION */ + s->session->kex_group = group_id; if (EVP_PKEY_set1_encoded_public_key(s->s3.peer_tmp, PACKET_data(&encoded_pt), @@ -1705,6 +1707,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } } + s->s3.did_kex = 1; return EXT_RETURN_SENT; #else return EXT_RETURN_FAIL; diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index dab4d1c4bc..85ed3e4259 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2167,6 +2167,8 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous ECDH, so no certificate or pkey. */ + /* Cache the agreed upon group in the SSL_SESSION */ + s->session->kex_group = curve_id; return 1; } diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index bad3619170..768e1110e6 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -2519,8 +2519,10 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); goto err; } - s->s3.tmp.pkey = ssl_generate_pkey_group(s, curve_id); + /* Cache the group used in the SSL_SESSION */ + s->session->kex_group = curve_id; /* Generate a new key for this curve */ + s->s3.tmp.pkey = ssl_generate_pkey_group(s, curve_id); if (s->s3.tmp.pkey == NULL) { /* SSLfatal() already called */ goto err; |