From: tb Date: Wed, 17 Aug 2022 18:45:25 +0000 (+0000) Subject: Refactor tls1_get_supported_group() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=0373aa6997759111e93553901c37c3fc9e62e0c1;p=openbsd Refactor tls1_get_supported_group() This splits tls1_get_supported_group() into a few helper functions to be able to count shared groups and to return the n-th shared group since someone thought it is a great idea to expose that in a single API and some others thought it is useful to add this info to log noise. This is all made a bit more complicated thanks to the security level having its tentacles everywhere and because a user-provided security callback can influence the list of groups shared by the peers. ok jsing --- diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index 6e4eb403cda..35fa4c693cb 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.420 2022/08/17 18:42:13 tb Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.421 2022/08/17 18:45:25 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1527,7 +1527,9 @@ int tls1_ec_group_id2nid(uint16_t group_id, int *out_nid); int tls1_ec_group_id2bits(uint16_t group_id, int *out_bits); int tls1_ec_nid2group_id(int nid, uint16_t *out_group_id); int tls1_check_group(SSL *s, uint16_t group_id); -int tls1_get_supported_group(SSL *s, int *group_nid); +int tls1_count_shared_groups(const SSL *ssl, size_t *out_count); +int tls1_get_shared_group_by_index(const SSL *ssl, size_t n, int *out_nid); +int tls1_get_supported_group(const SSL *s, int *out_nid); int ssl_check_clienthello_tlsext_early(SSL *s); int ssl_check_clienthello_tlsext_late(SSL *s); diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c index 049a55288d1..355c9827efb 100644 --- a/lib/libssl/t1_lib.c +++ b/lib/libssl/t1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t1_lib.c,v 1.194 2022/08/17 18:42:13 tb Exp $ */ +/* $OpenBSD: t1_lib.c,v 1.195 2022/08/17 18:45:25 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -441,6 +441,100 @@ tls1_get_group_list(const SSL *s, int client_groups, const uint16_t **pgroups, } } +static int +tls1_get_group_lists(const SSL *ssl, const uint16_t **pref, size_t *preflen, + const uint16_t **supp, size_t *supplen) +{ + unsigned long server_pref; + + /* Cannot do anything on the client side. */ + if (!ssl->server) + return 0; + + server_pref = (ssl->internal->options & SSL_OP_CIPHER_SERVER_PREFERENCE); + tls1_get_group_list(ssl, (server_pref == 0), pref, preflen); + tls1_get_group_list(ssl, (server_pref != 0), supp, supplen); + + return 1; +} + +static int +tls1_group_id_present(uint16_t group_id, const uint16_t *list, size_t list_len) +{ + size_t i; + + for (i = 0; i < list_len; i++) { + if (group_id == list[i]) + return 1; + } + + return 0; +} + +int +tls1_count_shared_groups(const SSL *ssl, size_t *out_count) +{ + size_t count, preflen, supplen, i; + const uint16_t *pref, *supp; + + if (!tls1_get_group_lists(ssl, &pref, &preflen, &supp, &supplen)) + return 0; + + count = 0; + for (i = 0; i < preflen; i++) { + if (!tls1_group_id_present(pref[i], supp, supplen)) + continue; + + if (!ssl_security_shared_group(ssl, pref[i])) + continue; + + count++; + } + + *out_count = count; + + return 1; +} + +static int +tls1_group_by_index(const SSL *ssl, size_t n, int *out_nid, + int (*ssl_security_fn)(const SSL *, uint16_t)) +{ + size_t count, preflen, supplen, i; + const uint16_t *pref, *supp; + + if (!tls1_get_group_lists(ssl, &pref, &preflen, &supp, &supplen)) + return 0; + + count = 0; + for (i = 0; i < preflen; i++) { + if (!tls1_group_id_present(pref[i], supp, supplen)) + continue; + + if (!ssl_security_fn(ssl, pref[i])) + continue; + + if (count++ == n) + return tls1_ec_group_id2nid(pref[i], out_nid); + } + + return 0; +} + +int +tls1_get_shared_group_by_index(const SSL *ssl, size_t index, int *out_nid) +{ + return tls1_group_by_index(ssl, index, out_nid, + ssl_security_shared_group); +} + +int +tls1_get_supported_group(const SSL *ssl, int *out_nid) +{ + return tls1_group_by_index(ssl, 0, out_nid, + ssl_security_supported_group); +} + int tls1_set_groups(uint16_t **out_group_ids, size_t *out_group_ids_len, const int *groups, size_t ngroups) @@ -530,33 +624,6 @@ tls1_check_group(SSL *s, uint16_t group_id) return 0; } -int -tls1_get_supported_group(SSL *s, int *out_nid) -{ - size_t preflen, supplen, i, j; - const uint16_t *pref, *supp; - unsigned long server_pref; - - /* Cannot do anything on the client side. */ - if (s->server == 0) - return 0; - - /* Return first preference supported group. */ - server_pref = (s->internal->options & SSL_OP_CIPHER_SERVER_PREFERENCE); - tls1_get_group_list(s, (server_pref == 0), &pref, &preflen); - tls1_get_group_list(s, (server_pref != 0), &supp, &supplen); - - for (i = 0; i < preflen; i++) { - if (!ssl_security_supported_group(s, pref[i])) - continue; - for (j = 0; j < supplen; j++) { - if (pref[i] == supp[j]) - return tls1_ec_group_id2nid(pref[i], out_nid); - } - } - return 0; -} - /* For an EC key set TLS ID and required compression based on parameters. */ static int tls1_set_ec_id(uint16_t *group_id, uint8_t *comp_id, EC_KEY *ec)