From 07ad1769c3d96ff6953d85b5d1e489389d0823ac Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Sun, 16 Sep 2018 15:36:10 +0100 Subject: [PATCH] fix: in TLSv1.3, the ALPN extension must be sent in EE serverHandshakeState::readClientHello was setting selected ALPN protocol always on hs.hello.alpnProtocol, which is specific to TLS 1.2 and older. Because of that server was marshalling ALPN to SH instead of EE. --- _dev/interop_test_runner | 22 ++++++++++++++++------ _dev/tris-localserver/server.go | 1 + handshake_server.go | 6 +++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/_dev/interop_test_runner b/_dev/interop_test_runner index e8a44d1..7c65395 100755 --- a/_dev/interop_test_runner +++ b/_dev/interop_test_runner @@ -15,6 +15,8 @@ RE_PATTERN_HELLO_TLS_13_RESUME = "Hello TLS 1.3 \[resumed\] _o/" RE_PATTERN_HELLO_0RTT = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT\] _o/$" # Checks if 0-RTT was used and confirmed RE_PATTERN_HELLO_0RTT_CONFIRMED = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT confirmed\] _o/$" +# ALPN +RE_PATTERN_ALPN = "ALPN protocol: npn_proto$" class Docker(object): ''' Utility class used for starting/stoping servers and clients during tests''' @@ -205,12 +207,20 @@ class InteropClient(object): # Actual test definition # TRIS as a server -class InteropServer_BoringSSL( - InteropServer, - ServerNominalMixin, - ServerClientAuthMixin, - unittest.TestCase - ): CLIENT_NAME = "tls-tris:boring" +class InteropServer_BoringSSL(InteropServer, ServerNominalMixin, ServerClientAuthMixin, unittest.TestCase): + + CLIENT_NAME = "tls-tris:boring" + + def test_ALPN(self): + ''' + Checks wether ALPN is sent back by tris server in EncryptedExtensions in case of TLS 1.3. The + ALPN protocol is set to 'npn_proto', which is hardcoded in TRIS test server. + ''' + res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":1443 "+'-alpn-protos npn_proto -debug') + print(res[1]) + self.assertEqual(res[0], 0) + self.assertIsNotNone(re.search(RE_PATTERN_ALPN, res[1], re.MULTILINE)) + # PicoTLS doesn't seem to implement draft-23 correctly. It will # be enabled when draft-28 is implemented. diff --git a/_dev/tris-localserver/server.go b/_dev/tris-localserver/server.go index 808ad2d..15c4709 100644 --- a/_dev/tris-localserver/server.go +++ b/_dev/tris-localserver/server.go @@ -72,6 +72,7 @@ func (s *server) start() { s.TLS.ClientCAs = x509.NewCertPool() s.TLS.ClientCAs.AppendCertsFromPEM([]byte(rsaCa_client)) s.TLS.Accept0RTTData = ((s.ZeroRTT & ZeroRTT_Accept) == ZeroRTT_Accept) + s.TLS.NextProtos = []string{"npn_proto"} httpServer := &http.Server{ Addr: s.Address, diff --git a/handshake_server.go b/handshake_server.go index 569925b..ca86baf 100644 --- a/handshake_server.go +++ b/handshake_server.go @@ -277,10 +277,10 @@ Curves: if len(hs.clientHello.alpnProtocols) > 0 { if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { - if hs.hello != nil { - hs.hello.alpnProtocol = selectedProto - } else { + if hs.hello13Enc != nil { hs.hello13Enc.alpnProtocol = selectedProto + } else { + hs.hello.alpnProtocol = selectedProto } c.clientProtocol = selectedProto }