diff --git a/doc/build.info b/doc/build.info index 6846b552d8e4a..e4a78e0d1444a 100644 --- a/doc/build.info +++ b/doc/build.info @@ -2495,6 +2495,10 @@ DEPEND[html/man3/SSL_get0_connection.html]=man3/SSL_get0_connection.pod GENERATE[html/man3/SSL_get0_connection.html]=man3/SSL_get0_connection.pod DEPEND[man/man3/SSL_get0_connection.3]=man3/SSL_get0_connection.pod GENERATE[man/man3/SSL_get0_connection.3]=man3/SSL_get0_connection.pod +DEPEND[html/man3/SSL_get0_group_name.html]=man3/SSL_get0_group_name.pod +GENERATE[html/man3/SSL_get0_group_name.html]=man3/SSL_get0_group_name.pod +DEPEND[man/man3/SSL_get0_group_name.3]=man3/SSL_get0_group_name.pod +GENERATE[man/man3/SSL_get0_group_name.3]=man3/SSL_get0_group_name.pod DEPEND[html/man3/SSL_get0_peer_rpk.html]=man3/SSL_get0_peer_rpk.pod GENERATE[html/man3/SSL_get0_peer_rpk.html]=man3/SSL_get0_peer_rpk.pod DEPEND[man/man3/SSL_get0_peer_rpk.3]=man3/SSL_get0_peer_rpk.pod @@ -3523,6 +3527,7 @@ html/man3/SSL_export_keying_material.html \ html/man3/SSL_extension_supported.html \ html/man3/SSL_free.html \ html/man3/SSL_get0_connection.html \ +html/man3/SSL_get0_group_name.html \ html/man3/SSL_get0_peer_rpk.html \ html/man3/SSL_get0_peer_scts.html \ html/man3/SSL_get_SSL_CTX.html \ @@ -4160,6 +4165,7 @@ man/man3/SSL_export_keying_material.3 \ man/man3/SSL_extension_supported.3 \ man/man3/SSL_free.3 \ man/man3/SSL_get0_connection.3 \ +man/man3/SSL_get0_group_name.3 \ man/man3/SSL_get0_peer_rpk.3 \ man/man3/SSL_get0_peer_scts.3 \ man/man3/SSL_get_SSL_CTX.3 \ diff --git a/doc/man3/SSL_get0_group_name.pod b/doc/man3/SSL_get0_group_name.pod new file mode 100644 index 0000000000000..a96340ae86f87 --- /dev/null +++ b/doc/man3/SSL_get0_group_name.pod @@ -0,0 +1,43 @@ +=pod + +=head1 NAME + +SSL_get0_group_name - get name of the group that was used for the key +agreement of the current TLS session establishment + +=head1 SYNOPSIS + + #include + + const char *SSL_get0_group_name(SSL *s); + +=head1 DESCRIPTION + +SSL_get0_group_name() returns the name of the group that was used for +the key agreement of the current TLS session establishment. + + +=head1 RETURN VALUES + +If non-NULL, SSL_get0_group_name() returns the name of the group that was used for +the key agreement of the current TLS session establishment. +If SSL_get0_group_name() returns NULL, an error occurred; possibly no TLS session +has been established. + +Note that the return value is valid only during the lifetime of the +SSL object I. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index bf5ff7c06b34a..beedd8956d60b 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -1504,6 +1504,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_get_max_proto_version(s) \ SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +const char *SSL_get0_group_name(SSL *s); const char *SSL_group_to_name(SSL *s, int id); /* Backwards compatibility, original 1.1.0 names */ diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 835af33fea396..10cff08eaeffb 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -5022,6 +5022,22 @@ int ssl_encapsulate(SSL_CONNECTION *s, EVP_PKEY *pubkey, return rv; } +const char *SSL_get0_group_name(SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + unsigned int id; + + if (sc == NULL) + return NULL; + + if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + id = sc->s3.group_id; + else + id = sc->session->kex_group; + + return tls1_group_id2name(s->ctx, id); +} + const char *SSL_group_to_name(SSL *s, int nid) { int group_id = 0; const TLS_GROUP_INFO *cinf = NULL; diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 7ab84acc8064b..decb02a207b71 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2767,6 +2767,7 @@ __owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL_CONNECTION *s); SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); __owur const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t curve_id); +__owur const char *tls1_group_id2name(SSL_CTX *ctx, uint16_t group_id); __owur int tls1_group_id2nid(uint16_t group_id, int include_unknown); __owur uint16_t tls1_nid2group_id(int nid); __owur int tls1_check_group_id(SSL_CONNECTION *s, uint16_t group_id, diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 189f241f7af46..576c7a3271e55 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -755,6 +755,16 @@ const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id) return NULL; } +const char *tls1_group_id2name(SSL_CTX *ctx, uint16_t group_id) +{ + const TLS_GROUP_INFO *tls_group_info = tls1_group_id_lookup(ctx, group_id); + + if (tls_group_info == NULL) + return NULL; + + return tls_group_info->tlsname; +} + int tls1_group_id2nid(uint16_t group_id, int include_unknown) { size_t i; diff --git a/test/sslapitest.c b/test/sslapitest.c index be1d742021e08..d2c6c774f50aa 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -5037,6 +5037,9 @@ static int test_key_exchange(int idx) /* We don't implement RFC 7919 named groups for TLS 1.2. */ if (idx != 13) { + if (!TEST_str_eq(SSL_get0_group_name(serverssl), kexch_name0) + || !TEST_str_eq(SSL_get0_group_name(clientssl), kexch_name0)) + goto end; if (!TEST_int_eq(SSL_get_negotiated_group(serverssl), kexch_groups[0])) goto end; if (!TEST_int_eq(SSL_get_negotiated_group(clientssl), kexch_groups[0])) @@ -9495,6 +9498,10 @@ static int test_pluggable_group(int idx) SSL_group_to_name(serverssl, SSL_get_shared_group(serverssl, 0)))) goto end; + if (!TEST_str_eq(group_name, SSL_get0_group_name(serverssl)) + || !TEST_str_eq(group_name, SSL_get0_group_name(clientssl))) + goto end; + testresult = 1; end: diff --git a/util/libssl.num b/util/libssl.num index 7f7b763075182..8377ed1b5789a 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -576,3 +576,4 @@ SSL_get_conn_close_info ? 3_2_0 EXIST::FUNCTION: SSL_set_incoming_stream_policy ? 3_2_0 EXIST::FUNCTION: SSL_handle_events ? 3_2_0 EXIST::FUNCTION: SSL_get_event_timeout ? 3_2_0 EXIST::FUNCTION: +SSL_get0_group_name ? 3_2_0 EXIST::FUNCTION: