summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/ssl_tlsext.c85
-rw-r--r--src/regress/lib/libssl/tlsext/tlsexttest.c101
2 files changed, 173 insertions, 13 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. */
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c
index c7983833dc..e61722542e 100644
--- a/src/regress/lib/libssl/tlsext/tlsexttest.c
+++ b/src/regress/lib/libssl/tlsext/tlsexttest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tlsexttest.c,v 1.86 2024/03/26 02:43:56 beck Exp $ */ 1/* $OpenBSD: tlsexttest.c,v 1.87 2024/03/27 22:27:09 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -1109,7 +1109,6 @@ test_tlsext_ecpf_client(void)
1109 goto err; 1109 goto err;
1110 } 1110 }
1111 1111
1112
1113 failure = 0; 1112 failure = 0;
1114 1113
1115 err: 1114 err:
@@ -3648,6 +3647,7 @@ test_tlsext_keyshare_client(void)
3648 const struct tls_extension_funcs *server_funcs; 3647 const struct tls_extension_funcs *server_funcs;
3649 int failure; 3648 int failure;
3650 size_t dlen; 3649 size_t dlen;
3650 size_t idx;
3651 int alert; 3651 int alert;
3652 CBB cbb; 3652 CBB cbb;
3653 CBS cbs; 3653 CBS cbs;
@@ -3701,18 +3701,109 @@ test_tlsext_keyshare_client(void)
3701 goto done; 3701 goto done;
3702 } 3702 }
3703 3703
3704 (ssl)->version = TLS1_3_VERSION; 3704 ssl->version = TLS1_3_VERSION;
3705 CBS_init(&cbs, data, dlen); 3705
3706 /* Fake up the ssl enough so the key share can process */
3707 ssl->session = SSL_SESSION_new();
3708 ssl->s3 = calloc(1, sizeof(*ssl->s3));
3709 ssl->session->tlsext_supportedgroups = calloc(4,
3710 sizeof(unsigned short));
3711 if (ssl->session == NULL || ssl->s3 == NULL ||
3712 ssl->session->tlsext_supportedgroups == NULL) {
3713 FAIL("malloc");
3714 goto done;
3715 }
3716 ssl->session->tlsext_supportedgroups[0] = 29;
3717 ssl->session->tlsext_supportedgroups[1] = 23;
3718 ssl->session->tlsext_supportedgroups[2] = 24;
3719 ssl->session->tlsext_supportedgroups[3] = 25;
3720 ssl->session->tlsext_supportedgroups_length = 4;
3721 tls_extension_find(TLSEXT_TYPE_supported_groups, &idx);
3722 ssl->s3->hs.extensions_processed |= (1 << idx);
3723 ssl->s3->hs.extensions_seen |= (1 << idx);
3724 ssl->s3->hs.our_max_tls_version = TLS1_3_VERSION;
3706 3725
3726 /*
3727 * We should select the key share for group 29, when group 29
3728 * is the most preferred group
3729 */
3730 CBS_init(&cbs, data, dlen);
3707 if (!server_funcs->process(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) { 3731 if (!server_funcs->process(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) {
3708 FAIL("failed to parse client keyshare\n"); 3732 FAIL("failed to process client keyshare\n");
3733 goto done;
3734 }
3735 if (CBS_len(&cbs) != 0) {
3736 FAIL("extension data remaining\n");
3737 goto done;
3738 }
3739 if (ssl->s3->hs.key_share == NULL) {
3740 FAIL("Did not select a key share");
3709 goto done; 3741 goto done;
3710 } 3742 }
3711 3743
3744 /*
3745 * Pretend the client did not send the supported groups extension. We
3746 * should fail to process.
3747 */
3748 ssl->s3->hs.extensions_seen = 0;
3749 free(ssl->s3->hs.key_share);
3750 ssl->s3->hs.key_share = NULL;
3751 CBS_init(&cbs, data, dlen);
3752 if (server_funcs->process(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) {
3753 FAIL("Processed key share when supported groups not provided");
3754 goto done;
3755 }
3756 ssl->s3->hs.extensions_seen |= (1 << idx);
3757
3758 /*
3759 * Pretend supported groups did not get processed. We should fail to
3760 * process
3761 */
3762 ssl->s3->hs.extensions_processed = 0;
3763 ssl->s3->hs.key_share = NULL;
3764 CBS_init(&cbs, data, dlen);
3765 if (server_funcs->process(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) {
3766 FAIL("Processed key share when supported groups unprocesed");
3767 goto done;
3768 }
3769 ssl->s3->hs.extensions_processed |= (1 << idx);
3770
3771 /*
3772 * Remove group 29 by making it 0xbeef, meaning 29 has not been sent in
3773 * supported groups. This should fail to process.
3774 */
3775 ssl->session->tlsext_supportedgroups[0] = 0xbeef;
3776 ssl->s3->hs.key_share = NULL;
3777 CBS_init(&cbs, data, dlen);
3778 if (server_funcs->process(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) {
3779 FAIL("Processed key share with invalid group!");
3780 goto done;
3781 }
3782 ssl->session->tlsext_supportedgroups[0] = 29;
3783
3784 /*
3785 * Make 29 least preferred, while server supports both 29 and 25.
3786 * Client key share is for 29 but it prefers 25. We should successfully
3787 * process, but should not select this key share.
3788 */
3789 ssl->session->tlsext_supportedgroups[0] = 25;
3790 ssl->session->tlsext_supportedgroups[3] = 29;
3791 ssl->s3->hs.key_share = NULL;
3792 CBS_init(&cbs, data, dlen);
3793 if (!server_funcs->process(ssl, SSL_TLSEXT_MSG_CH, &cbs, &alert)) {
3794 FAIL("failed to process client keyshare\n");
3795 goto done;
3796 }
3712 if (CBS_len(&cbs) != 0) { 3797 if (CBS_len(&cbs) != 0) {
3713 FAIL("extension data remaining\n"); 3798 FAIL("extension data remaining\n");
3714 goto done; 3799 goto done;
3715 } 3800 }
3801 if (ssl->s3->hs.key_share != NULL) {
3802 FAIL("Selected a key share when I should not have!");
3803 goto done;
3804 }
3805 ssl->session->tlsext_supportedgroups[0] = 29;
3806 ssl->session->tlsext_supportedgroups[3] = 25;
3716 3807
3717 failure = 0; 3808 failure = 0;
3718 3809