summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/ssl_lib.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index d1b552d94f..406567b535 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_lib.c,v 1.323 2024/04/15 16:00:05 tb Exp $ */ 1/* $OpenBSD: ssl_lib.c,v 1.324 2024/06/28 14:46:19 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -1785,45 +1785,70 @@ LSSL_ALIAS(SSL_get_servername_type);
1785 * It returns either: 1785 * It returns either:
1786 * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or 1786 * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
1787 * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. 1787 * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
1788 *
1789 * XXX - the out argument points into server_list or client list and should
1790 * therefore really be const. We can't fix that without breaking the callers.
1788 */ 1791 */
1789int 1792int
1790SSL_select_next_proto(unsigned char **out, unsigned char *outlen, 1793SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
1791 const unsigned char *server, unsigned int server_len, 1794 const unsigned char *server_list, unsigned int server_list_len,
1792 const unsigned char *client, unsigned int client_len) 1795 const unsigned char *client_list, unsigned int client_list_len)
1793{ 1796{
1794 unsigned int i, j; 1797 CBS client, client_proto, server, server_proto;
1795 const unsigned char *result; 1798
1796 int status = OPENSSL_NPN_UNSUPPORTED; 1799 *out = NULL;
1800 *outlen = 0;
1801
1802 /* First check that the client list is well-formed. */
1803 CBS_init(&client, client_list, client_list_len);
1804 if (!tlsext_alpn_check_format(&client))
1805 goto err;
1806
1807 /*
1808 * Use first client protocol as fallback. This is one way of doing NPN's
1809 * "opportunistic" protocol selection (see security considerations in
1810 * draft-agl-tls-nextprotoneg-04), and it is the documented behavior of
1811 * this API. For ALPN it's the callback's responsibility to fail on
1812 * OPENSSL_NPN_NO_OVERLAP.
1813 */
1814
1815 if (!CBS_get_u8_length_prefixed(&client, &client_proto))
1816 goto err;
1817
1818 *out = (unsigned char *)CBS_data(&client_proto);
1819 *outlen = CBS_len(&client_proto);
1820
1821 /* Now check that the server list is well-formed. */
1822 CBS_init(&server, server_list, server_list_len);
1823 if (!tlsext_alpn_check_format(&server))
1824 goto err;
1797 1825
1798 /* 1826 /*
1799 * For each protocol in server preference order, 1827 * Walk the server list and select the first protocol that appears in
1800 * see if we support it. 1828 * the client list.
1801 */ 1829 */
1802 for (i = 0; i < server_len; ) { 1830 while (CBS_len(&server) > 0) {
1803 for (j = 0; j < client_len; ) { 1831 if (!CBS_get_u8_length_prefixed(&server, &server_proto))
1804 if (server[i] == client[j] && 1832 goto err;
1805 memcmp(&server[i + 1], 1833
1806 &client[j + 1], server[i]) == 0) { 1834 CBS_init(&client, client_list, client_list_len);
1807 /* We found a match */ 1835
1808 result = &server[i]; 1836 while (CBS_len(&client) > 0) {
1809 status = OPENSSL_NPN_NEGOTIATED; 1837 if (!CBS_get_u8_length_prefixed(&client, &client_proto))
1810 goto found; 1838 goto err;
1839
1840 if (CBS_mem_equal(&client_proto,
1841 CBS_data(&server_proto), CBS_len(&server_proto))) {
1842 *out = (unsigned char *)CBS_data(&server_proto);
1843 *outlen = CBS_len(&server_proto);
1844
1845 return OPENSSL_NPN_NEGOTIATED;
1811 } 1846 }
1812 j += client[j];
1813 j++;
1814 } 1847 }
1815 i += server[i];
1816 i++;
1817 } 1848 }
1818 1849
1819 /* There's no overlap between our protocols and the server's list. */ 1850 err:
1820 result = client; 1851 return OPENSSL_NPN_NO_OVERLAP;
1821 status = OPENSSL_NPN_NO_OVERLAP;
1822
1823 found:
1824 *out = (unsigned char *) result + 1;
1825 *outlen = result[0];
1826 return (status);
1827} 1852}
1828LSSL_ALIAS(SSL_select_next_proto); 1853LSSL_ALIAS(SSL_select_next_proto);
1829 1854