tlsconfig: don't negotiate ALPN with client if server refused to do so

This commit is contained in:
Maximilian Hils 2021-03-29 09:01:20 +02:00
parent c195737a0c
commit 80f208fb2a
2 changed files with 8 additions and 0 deletions

View File

@ -34,6 +34,10 @@ def alpn_select_callback(conn: SSL.Connection, options: List[bytes]) -> Any:
http2 = app_data["http2"] http2 = app_data["http2"]
if server_alpn and server_alpn in options: if server_alpn and server_alpn in options:
return server_alpn return server_alpn
if server_alpn == b"":
# We do have a server connection, but the remote server refused to negotiate a protocol:
# We need to mirror this on the client connection.
return SSL.NO_OVERLAPPING_PROTOCOLS
http_alpns = tls.HTTP_ALPNS if http2 else tls.HTTP1_ALPNS http_alpns = tls.HTTP_ALPNS if http2 else tls.HTTP1_ALPNS
for alpn in options: # client sends in order of preference, so we are nice and respect that. for alpn in options: # client sends in order of preference, so we are nice and respect that.
if alpn in http_alpns: if alpn in http_alpns:

View File

@ -30,6 +30,10 @@ def test_alpn_select_callback():
# Test no overlap # Test no overlap
assert tlsconfig.alpn_select_callback(conn, [b"qux", b"quux"]) == SSL.NO_OVERLAPPING_PROTOCOLS assert tlsconfig.alpn_select_callback(conn, [b"qux", b"quux"]) == SSL.NO_OVERLAPPING_PROTOCOLS
# Test that we don't select an ALPN if the server refused to select one.
conn.set_app_data(tlsconfig.AppData(server_alpn=b"", http2=True))
assert tlsconfig.alpn_select_callback(conn, [b"http/1.1"]) == SSL.NO_OVERLAPPING_PROTOCOLS
here = Path(__file__).parent here = Path(__file__).parent