summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2022-08-17 18:45:26 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2022-08-17 18:45:26 +0000
commit00c6058c451a96f096808d53c7e999ee904815b3 (patch)
treec8b0d4e5db98a300a29298dc1e39f7814875c4aa /lib
parent7e68d19c858b997a92d1fc41aa6f8a42127a48df (diff)
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
Diffstat (limited to 'lib')
-rw-r--r--lib/libssl/ssl_locl.h6
-rw-r--r--lib/libssl/t1_lib.c123
2 files changed, 99 insertions, 30 deletions
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)