diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index f5d477e864..d78cb2ac3a 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.325 2024/06/29 07:34:12 tb Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.326 2024/07/11 13:48:52 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 | * |
@@ -1791,56 +1791,58 @@ LSSL_ALIAS(SSL_get_servername_type); | |||
1791 | */ | 1791 | */ |
1792 | int | 1792 | int |
1793 | SSL_select_next_proto(unsigned char **out, unsigned char *outlen, | 1793 | SSL_select_next_proto(unsigned char **out, unsigned char *outlen, |
1794 | const unsigned char *server_list, unsigned int server_list_len, | 1794 | const unsigned char *peer_list, unsigned int peer_list_len, |
1795 | const unsigned char *client_list, unsigned int client_list_len) | 1795 | const unsigned char *supported_list, unsigned int supported_list_len) |
1796 | { | 1796 | { |
1797 | CBS client, client_proto, server, server_proto; | 1797 | CBS peer, peer_proto, supported, supported_proto; |
1798 | 1798 | ||
1799 | *out = NULL; | 1799 | *out = NULL; |
1800 | *outlen = 0; | 1800 | *outlen = 0; |
1801 | 1801 | ||
1802 | /* First check that the client list is well-formed. */ | 1802 | /* First check that the supported list is well-formed. */ |
1803 | CBS_init(&client, client_list, client_list_len); | 1803 | CBS_init(&supported, supported_list, supported_list_len); |
1804 | if (!tlsext_alpn_check_format(&client)) | 1804 | if (!tlsext_alpn_check_format(&supported)) |
1805 | goto err; | 1805 | goto err; |
1806 | 1806 | ||
1807 | /* | 1807 | /* |
1808 | * Use first client protocol as fallback. This is one way of doing NPN's | 1808 | * Use first supported protocol as fallback. This is one way of doing |
1809 | * "opportunistic" protocol selection (see security considerations in | 1809 | * NPN's "opportunistic" protocol selection (see security considerations |
1810 | * draft-agl-tls-nextprotoneg-04), and it is the documented behavior of | 1810 | * in draft-agl-tls-nextprotoneg-04), and it is the documented behavior |
1811 | * this API. For ALPN it's the callback's responsibility to fail on | 1811 | * of this API. For ALPN it's the callback's responsibility to fail on |
1812 | * OPENSSL_NPN_NO_OVERLAP. | 1812 | * OPENSSL_NPN_NO_OVERLAP. |
1813 | */ | 1813 | */ |
1814 | 1814 | ||
1815 | if (!CBS_get_u8_length_prefixed(&client, &client_proto)) | 1815 | if (!CBS_get_u8_length_prefixed(&supported, &supported_proto)) |
1816 | goto err; | 1816 | goto err; |
1817 | 1817 | ||
1818 | *out = (unsigned char *)CBS_data(&client_proto); | 1818 | *out = (unsigned char *)CBS_data(&supported_proto); |
1819 | *outlen = CBS_len(&client_proto); | 1819 | *outlen = CBS_len(&supported_proto); |
1820 | 1820 | ||
1821 | /* Now check that the server list is well-formed. */ | 1821 | /* Now check that the peer list is well-formed. */ |
1822 | CBS_init(&server, server_list, server_list_len); | 1822 | CBS_init(&peer, peer_list, peer_list_len); |
1823 | if (!tlsext_alpn_check_format(&server)) | 1823 | if (!tlsext_alpn_check_format(&peer)) |
1824 | goto err; | 1824 | goto err; |
1825 | 1825 | ||
1826 | /* | 1826 | /* |
1827 | * Walk the server list and select the first protocol that appears in | 1827 | * Walk the peer list and select the first protocol that appears in |
1828 | * the client list. | 1828 | * the supported list. Thus we honor peer preference rather than local |
1829 | * preference contrary to a SHOULD in RFC 7301, section 3.2. | ||
1829 | */ | 1830 | */ |
1830 | while (CBS_len(&server) > 0) { | 1831 | while (CBS_len(&peer) > 0) { |
1831 | if (!CBS_get_u8_length_prefixed(&server, &server_proto)) | 1832 | if (!CBS_get_u8_length_prefixed(&peer, &peer_proto)) |
1832 | goto err; | 1833 | goto err; |
1833 | 1834 | ||
1834 | CBS_init(&client, client_list, client_list_len); | 1835 | CBS_init(&supported, supported_list, supported_list_len); |
1835 | 1836 | ||
1836 | while (CBS_len(&client) > 0) { | 1837 | while (CBS_len(&supported) > 0) { |
1837 | if (!CBS_get_u8_length_prefixed(&client, &client_proto)) | 1838 | if (!CBS_get_u8_length_prefixed(&supported, |
1839 | &supported_proto)) | ||
1838 | goto err; | 1840 | goto err; |
1839 | 1841 | ||
1840 | if (CBS_mem_equal(&client_proto, | 1842 | if (CBS_mem_equal(&supported_proto, |
1841 | CBS_data(&server_proto), CBS_len(&server_proto))) { | 1843 | CBS_data(&peer_proto), CBS_len(&peer_proto))) { |
1842 | *out = (unsigned char *)CBS_data(&server_proto); | 1844 | *out = (unsigned char *)CBS_data(&peer_proto); |
1843 | *outlen = CBS_len(&server_proto); | 1845 | *outlen = CBS_len(&peer_proto); |
1844 | 1846 | ||
1845 | return OPENSSL_NPN_NEGOTIATED; | 1847 | return OPENSSL_NPN_NEGOTIATED; |
1846 | } | 1848 | } |