Adding TLS group name retrieval

Function SSL_group_to_name() added, together with documentation and tests.
This now permits displaying names of internal and external
provider-implemented groups.

Partial fix of #13767

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13785)
This commit is contained in:
Michael Baentsch 2021-01-07 09:09:32 +01:00 committed by Matt Caswell
parent 22aa4a3afb
commit becbacd705
8 changed files with 93 additions and 20 deletions

View File

@ -345,7 +345,6 @@ int ssl_print_point_formats(BIO *out, SSL *s)
int ssl_print_groups(BIO *out, SSL *s, int noshared)
{
int i, ngroups, *groups, nid;
const char *gname;
ngroups = SSL_get1_groups(s, NULL);
if (ngroups <= 0)
@ -353,39 +352,25 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared)
groups = app_malloc(ngroups * sizeof(int), "groups to print");
SSL_get1_groups(s, groups);
BIO_puts(out, "Supported Elliptic Groups: ");
BIO_puts(out, "Supported groups: ");
for (i = 0; i < ngroups; i++) {
if (i)
BIO_puts(out, ":");
nid = groups[i];
/* If unrecognised print out hex version */
if (nid & TLSEXT_nid_unknown) {
BIO_printf(out, "0x%04X", nid & 0xFFFF);
} else {
/* TODO(TLS1.3): Get group name here */
/* Use NIST name for curve if it exists */
gname = EC_curve_nid2nist(nid);
if (gname == NULL)
gname = OBJ_nid2sn(nid);
BIO_printf(out, "%s", gname);
}
BIO_printf(out, "%s", SSL_group_to_name(s, nid));
}
OPENSSL_free(groups);
if (noshared) {
BIO_puts(out, "\n");
return 1;
}
BIO_puts(out, "\nShared Elliptic groups: ");
BIO_puts(out, "\nShared groups: ");
ngroups = SSL_get_shared_group(s, -1);
for (i = 0; i < ngroups; i++) {
if (i)
BIO_puts(out, ":");
nid = SSL_get_shared_group(s, i);
/* TODO(TLS1.3): Convert for DH groups */
gname = EC_curve_nid2nist(nid);
if (gname == NULL)
gname = OBJ_nid2sn(nid);
BIO_printf(out, "%s", gname);
BIO_printf(out, "%s", SSL_group_to_name(s, nid));
}
if (ngroups == 0)
BIO_puts(out, "NONE");

View File

@ -0,0 +1,43 @@
=pod
=head1 NAME
SSL_group_to_name - get name of group
=head1 SYNOPSIS
#include <openssl/ssl.h>
const char *SSL_group_to_name(const SSL *ssl, int id);
=head1 DESCRIPTION
SSL_group_to_name() is used to retrieve the TLS group name
associated with a given TLS group ID, as registered via built-in
or external providers and as returned by a call to SSL_get1_groups()
or SSL_get_shared_group().
=head1 RETURN VALUES
If non-NULL, SSL_group_to_name() returns the TLS group name
corresponding to the given I<id> as a NULL-terminated string.
If SSL_group_to_name() returns NULL, an error occurred; possibly no
corresponding tlsname was registered during provider initialisation.
Note that the return value is valid only during the lifetime of the
SSL object I<ssl>.
=head1 SEE ALSO
L<ssl(7)>
=head1 COPYRIGHT
Copyright 2021 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<https://www.openssl.org/source/license.html>.
=cut

View File

@ -1501,6 +1501,8 @@ 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_group_to_name(SSL *s, int id);
/* Backwards compatibility, original 1.1.0 names */
# define SSL_CTRL_GET_SERVER_TMP_KEY \
SSL_CTRL_GET_PEER_TMP_KEY

View File

@ -4986,3 +4986,21 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey,
EVP_PKEY_CTX_free(pctx);
return rv;
}
const char *SSL_group_to_name(SSL *s, int nid) {
int group_id = 0;
const TLS_GROUP_INFO *cinf = NULL;
/* first convert to real group id for internal and external IDs */
if (nid & TLSEXT_nid_unknown)
group_id = nid & 0xFFFF;
else
group_id = tls1_nid2group_id(nid);
/* then look up */
cinf = tls1_group_id_lookup(s->ctx, group_id);
if (cinf != NULL)
return cinf->tlsname;
return NULL;
}

View File

@ -2650,6 +2650,7 @@ 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 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 *s, uint16_t group_id, int check_own_curves);
__owur uint16_t tls1_shared_group(SSL *s, int nmatch);
__owur int tls1_set_groups(uint16_t **pext, size_t *pextlen,

View File

@ -460,7 +460,7 @@ int tls1_group_id2nid(uint16_t group_id, int include_unknown)
return TLSEXT_nid_unknown | (int)group_id;
}
static uint16_t tls1_nid2group_id(int nid)
uint16_t tls1_nid2group_id(int nid)
{
size_t i;

View File

@ -4318,6 +4318,7 @@ static int test_key_exchange(int idx)
int *kexch_groups = &kexch_alg;
int kexch_groups_size = 1;
int max_version = TLS1_3_VERSION;
char *kexch_name0 = NULL;
switch (idx) {
# ifndef OPENSSL_NO_EC
@ -4329,47 +4330,60 @@ static int test_key_exchange(int idx)
case 0:
kexch_groups = ecdhe_kexch_groups;
kexch_groups_size = OSSL_NELEM(ecdhe_kexch_groups);
kexch_name0 = "secp256r1";
break;
case 1:
kexch_alg = NID_X9_62_prime256v1;
kexch_name0 = "secp256r1";
break;
case 2:
kexch_alg = NID_secp384r1;
kexch_name0 = "secp384r1";
break;
case 3:
kexch_alg = NID_secp521r1;
kexch_name0 = "secp521r1";
break;
case 4:
kexch_alg = NID_X25519;
kexch_name0 = "x25519";
break;
case 5:
kexch_alg = NID_X448;
kexch_name0 = "x448";
break;
# endif
# ifndef OPENSSL_NO_DH
# ifndef OPENSSL_NO_TLS1_2
case 13:
max_version = TLS1_2_VERSION;
kexch_name0 = "ffdhe2048";
# endif
/* Fall through */
case 6:
kexch_groups = ffdhe_kexch_groups;
kexch_groups_size = OSSL_NELEM(ffdhe_kexch_groups);
kexch_name0 = "ffdhe2048";
break;
case 7:
kexch_alg = NID_ffdhe2048;
kexch_name0 = "ffdhe2048";
break;
case 8:
kexch_alg = NID_ffdhe3072;
kexch_name0 = "ffdhe3072";
break;
case 9:
kexch_alg = NID_ffdhe4096;
kexch_name0 = "ffdhe4096";
break;
case 10:
kexch_alg = NID_ffdhe6144;
kexch_name0 = "ffdhe6144";
break;
case 11:
kexch_alg = NID_ffdhe8192;
kexch_name0 = "ffdhe8192";
break;
# endif
default:
@ -4425,6 +4439,11 @@ static int test_key_exchange(int idx)
if (!TEST_int_eq(SSL_get_shared_group(serverssl, 0),
idx == 13 ? 0 : kexch_groups[0]))
goto end;
if (!TEST_str_eq(SSL_group_to_name(serverssl, kexch_groups[0]),
kexch_name0))
goto end;
if (max_version == TLS1_3_VERSION) {
if (!TEST_int_eq(SSL_get_negotiated_group(serverssl), kexch_groups[0]))
goto end;
@ -8000,6 +8019,10 @@ static int test_pluggable_group(int idx)
if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
goto end;
if (!TEST_str_eq(group_name,
SSL_group_to_name(serverssl, SSL_get_shared_group(serverssl, 0))))
goto end;
testresult = 1;
end:

View File

@ -519,3 +519,4 @@ SSL_get1_peer_certificate ? 3_0_0 EXIST::FUNCTION:
SSL_load_client_CA_file_ex ? 3_0_0 EXIST::FUNCTION:
SSL_set0_tmp_dh_pkey ? 3_0_0 EXIST::FUNCTION:
SSL_CTX_set0_tmp_dh_pkey ? 3_0_0 EXIST::FUNCTION:
SSL_group_to_name ? 3_0_0 EXIST::FUNCTION: