summaryrefslogtreecommitdiffstats
path: root/ssl/statem
diff options
context:
space:
mode:
authorBenjamin Kaduk <bkaduk@akamai.com>2021-03-16 07:47:09 -0700
committerBenjamin Kaduk <bkaduk@akamai.com>2021-05-15 15:09:07 -0700
commitaa6bd216dd2691d1254eabcbd584691eb3b4b9b8 (patch)
treec666b319f00d45596172c847a1c365edcfc703fd /ssl/statem
parenta8457b4c3d86a42209eabe90eddb605f59041f9e (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.c23
-rw-r--r--ssl/statem/extensions_srvr.c3
-rw-r--r--ssl/statem/statem_clnt.c2
-rw-r--r--ssl/statem/statem_srvr.c4
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;