summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorbeck <>2024-03-27 22:27:09 +0000
committerbeck <>2024-03-27 22:27:09 +0000
commit298923a130069a65297bca47c69a28e596f74798 (patch)
tree68bd1157c64daf7ea2cfbb0c6ca2d70bba0a9769 /src/lib
parentfeced734cd9525f3d3e8b5db422209833f23147a (diff)
downloadopenbsd-298923a130069a65297bca47c69a28e596f74798.tar.gz
openbsd-298923a130069a65297bca47c69a28e596f74798.tar.bz2
openbsd-298923a130069a65297bca47c69a28e596f74798.zip
Fix up server processing of key shares.
Ensure that the client can not provide a duplicate key share for any group, or send more key shares than groups they support. Ensure that the key shares must be provided in the same order as the client preference order specified in supported_groups. Ensure we only will choose to use a key share that is for the most preferred group by the client that we also support, to avoid the client being downgraded by sending a less preferred key share. If we do not end up with a key share for the most preferred mutually supported group, will then do a hello retry request selecting that group. Add regress for this to regress/tlsext/tlsexttest.c ok jsing@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/ssl_tlsext.c85
1 files changed, 77 insertions, 8 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index e4ba549814..14cf6fce84 100644
--- a/src/lib/libssl/ssl_tlsext.c
+++ b/src/lib/libssl/ssl_tlsext.c
@@ -1,8 +1,8 @@
1/* $OpenBSD: ssl_tlsext.c,v 1.144 2024/03/27 10:44:17 beck Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.145 2024/03/27 22:27:09 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
5 * Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org> 5 * Copyright (c) 2018-2019, 2024 Bob Beck <beck@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
@@ -1464,14 +1464,65 @@ tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb)
1464static int 1464static int
1465tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) 1465tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
1466{ 1466{
1467 CBS client_shares, key_exchange; 1467 const uint16_t *client_groups = NULL, *server_groups = NULL;
1468 size_t client_groups_len = 0, server_groups_len = 0;
1469 size_t i, j, client_groups_index;
1470 int preferred_group_found = 0;
1468 int decode_error; 1471 int decode_error;
1469 uint16_t group; 1472 uint16_t group, client_preferred_group;
1473 CBS client_shares, key_exchange;
1474
1475 /*
1476 * RFC 8446 section 4.2.8:
1477 *
1478 * Each KeyShareEntry value MUST correspond to a group offered in the
1479 * "supported_groups" extension and MUST appear in the same order.
1480 * However, the values MAY be a non-contiguous subset of the
1481 * "supported_groups".
1482 */
1483
1484 if (!tlsext_extension_seen(s, TLSEXT_TYPE_supported_groups)) {
1485 *alert = SSL_AD_ILLEGAL_PARAMETER;
1486 return 0;
1487 }
1488 if (!tlsext_extension_processed(s, TLSEXT_TYPE_supported_groups)) {
1489 *alert = SSL_AD_INTERNAL_ERROR;
1490 return 0;
1491 }
1492
1493 /*
1494 * XXX similar to tls1_get_supported_group, but client pref
1495 * only - consider deduping later.
1496 */
1497 /*
1498 * We are now assured of at least one client group.
1499 * Get the client and server group preference orders.
1500 */
1501 tls1_get_group_list(s, 0, &server_groups, &server_groups_len);
1502 tls1_get_group_list(s, 1, &client_groups, &client_groups_len);
1503
1504 /*
1505 * Find the group that is most preferred by the client that
1506 * we also support.
1507 */
1508 for (i = 0; i < client_groups_len && !preferred_group_found; i++) {
1509 if (!ssl_security_supported_group(s, client_groups[i]))
1510 continue;
1511 for (j = 0; j < server_groups_len; j++) {
1512 if (server_groups[j] == client_groups[i]) {
1513 client_preferred_group = client_groups[i];
1514 preferred_group_found = 1;
1515 break;
1516 }
1517 }
1518 }
1470 1519
1471 if (!CBS_get_u16_length_prefixed(cbs, &client_shares)) 1520 if (!CBS_get_u16_length_prefixed(cbs, &client_shares))
1472 return 0; 1521 return 0;
1473 1522
1523 client_groups_index = 0;
1474 while (CBS_len(&client_shares) > 0) { 1524 while (CBS_len(&client_shares) > 0) {
1525 int client_sent_group;
1475 1526
1476 /* Unpack client share. */ 1527 /* Unpack client share. */
1477 if (!CBS_get_u16(&client_shares, &group)) 1528 if (!CBS_get_u16(&client_shares, &group))
@@ -1480,9 +1531,21 @@ tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
1480 return 0; 1531 return 0;
1481 1532
1482 /* 1533 /*
1483 * XXX - check key exchange against supported groups from client. 1534 * Ensure the client share group was sent in supported groups,
1484 * XXX - check that groups only appear once. 1535 * and was sent in the same order as supported groups. The
1536 * supported groups has already been checked for duplicates.
1485 */ 1537 */
1538 client_sent_group = 0;
1539 while (client_groups_index < client_groups_len) {
1540 if (group == client_groups[client_groups_index++]) {
1541 client_sent_group = 1;
1542 break;
1543 }
1544 }
1545 if (!client_sent_group) {
1546 *alert = SSL_AD_ILLEGAL_PARAMETER;
1547 return 0;
1548 }
1486 1549
1487 /* 1550 /*
1488 * Ignore this client share if we're using earlier than TLSv1.3 1551 * Ignore this client share if we're using earlier than TLSv1.3
@@ -1493,8 +1556,14 @@ tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
1493 if (s->s3->hs.key_share != NULL) 1556 if (s->s3->hs.key_share != NULL)
1494 continue; 1557 continue;
1495 1558
1496 /* XXX - consider implementing server preference. */ 1559 /*
1497 if (!tls1_check_group(s, group)) 1560 * Ignore this client share if it is not for the most client
1561 * preferred supported group. This avoids a potential downgrade
1562 * situation where the client sends a client share for something
1563 * less preferred, and we choose to to use it instead of
1564 * requesting the more preferred group.
1565 */
1566 if (!preferred_group_found || group != client_preferred_group)
1498 continue; 1567 continue;
1499 1568
1500 /* Decode and store the selected key share. */ 1569 /* Decode and store the selected key share. */