diff options
author | tb <> | 2024-07-11 13:48:52 +0000 |
---|---|---|
committer | tb <> | 2024-07-11 13:48:52 +0000 |
commit | 5260b37984fa00e9dd3c39361386fef0634a29dd (patch) | |
tree | 947607486d185911b8a164dcc91eb9258875c27a | |
parent | aaeb6af9ab85685268769224ce8866d0f7a3a0a6 (diff) | |
download | openbsd-5260b37984fa00e9dd3c39361386fef0634a29dd.tar.gz openbsd-5260b37984fa00e9dd3c39361386fef0634a29dd.tar.bz2 openbsd-5260b37984fa00e9dd3c39361386fef0634a29dd.zip |
Follow BoringSSL's nomenclature in SSL_select_next_proto()
SSL_select_next_poto() was written with NPN in mind. NPN has a weird
fallback mechanism which is baked into the API. This is makes no sense
for ALPN, where the API behavior is undesirable since it a server
should not end up choosing a protocol it doesn't (want to) support.
Arguably, ALPN should simply have had its own API for protocol selection
supporting the proper semantics, instead of shoehorning an NPN API into
working for ALPN.
Commit https://boringssl-review.googlesource.com/c/boringssl/+/17206/
renamed the arguments to work for both NPN and ALPN, with the slight
downside of honoring client preference instead of the SHOULD in
RFC 7301, section 3.2. This grates for most consumers in the wild,
but so be it. The behavior is saner and safer.
discussed with davidben
ok beck
-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 | } |