crypto/tls: let HTTP/1.1 clients connect to servers with NextProtos "h2"

Fixes #46310

Change-Id: Idd5e30f05c439f736ae6f3904cbb9cc2ba772315
Reviewed-on: https://go-review.googlesource.com/c/go/+/325432
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index 13a7f34..4af3d99 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -711,17 +711,11 @@
 		}
 	}
 
-	if hs.serverHello.alpnProtocol != "" {
-		if len(hs.hello.alpnProtocols) == 0 {
-			c.sendAlert(alertUnsupportedExtension)
-			return false, errors.New("tls: server advertised unrequested ALPN extension")
-		}
-		if mutualProtocol([]string{hs.serverHello.alpnProtocol}, hs.hello.alpnProtocols) == "" {
-			c.sendAlert(alertUnsupportedExtension)
-			return false, errors.New("tls: server selected unadvertised ALPN protocol")
-		}
-		c.clientProtocol = hs.serverHello.alpnProtocol
+	if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
+		c.sendAlert(alertUnsupportedExtension)
+		return false, err
 	}
+	c.clientProtocol = hs.serverHello.alpnProtocol
 
 	c.scts = hs.serverHello.scts
 
@@ -753,6 +747,23 @@
 	return true, nil
 }
 
+// checkALPN ensure that the server's choice of ALPN protocol is compatible with
+// the protocols that we advertised in the Client Hello.
+func checkALPN(clientProtos []string, serverProto string) error {
+	if serverProto == "" {
+		return nil
+	}
+	if len(clientProtos) == 0 {
+		return errors.New("tls: server advertised unrequested ALPN extension")
+	}
+	for _, proto := range clientProtos {
+		if proto == serverProto {
+			return nil
+		}
+	}
+	return errors.New("tls: server selected unadvertised ALPN protocol")
+}
+
 func (hs *clientHandshakeState) readFinished(out []byte) error {
 	c := hs.c
 
@@ -979,19 +990,6 @@
 	return serverAddr.String()
 }
 
-// mutualProtocol finds the mutual ALPN protocol given list of possible
-// protocols and a list of the preference order.
-func mutualProtocol(protos, preferenceProtos []string) string {
-	for _, s := range preferenceProtos {
-		for _, c := range protos {
-			if s == c {
-				return s
-			}
-		}
-	}
-	return ""
-}
-
 // hostnameInSNI converts name into an appropriate hostname for SNI.
 // Literal IP addresses and absolute FQDNs are not permitted as SNI values.
 // See RFC 6066, Section 3.
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index be37c68..eb59ac9 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -396,17 +396,11 @@
 	}
 	hs.transcript.Write(encryptedExtensions.marshal())
 
-	if encryptedExtensions.alpnProtocol != "" {
-		if len(hs.hello.alpnProtocols) == 0 {
-			c.sendAlert(alertUnsupportedExtension)
-			return errors.New("tls: server advertised unrequested ALPN extension")
-		}
-		if mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.hello.alpnProtocols) == "" {
-			c.sendAlert(alertUnsupportedExtension)
-			return errors.New("tls: server selected unadvertised ALPN protocol")
-		}
-		c.clientProtocol = encryptedExtensions.alpnProtocol
+	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
+		c.sendAlert(alertUnsupportedExtension)
+		return err
 	}
+	c.clientProtocol = encryptedExtensions.alpnProtocol
 
 	return nil
 }
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index b231981..43f30e2 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -217,15 +217,13 @@
 		c.serverName = hs.clientHello.serverName
 	}
 
-	if len(c.config.NextProtos) > 0 && len(hs.clientHello.alpnProtocols) > 0 {
-		selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos)
-		if selectedProto == "" {
-			c.sendAlert(alertNoApplicationProtocol)
-			return fmt.Errorf("tls: client requested unsupported application protocols (%s)", hs.clientHello.alpnProtocols)
-		}
-		hs.hello.alpnProtocol = selectedProto
-		c.clientProtocol = selectedProto
+	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+	if err != nil {
+		c.sendAlert(alertNoApplicationProtocol)
+		return err
 	}
+	hs.hello.alpnProtocol = selectedProto
+	c.clientProtocol = selectedProto
 
 	hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
 	if err != nil {
@@ -277,6 +275,34 @@
 	return nil
 }
 
+// negotiateALPN picks a shared ALPN protocol that both sides support in server
+// preference order. If ALPN is not configured or the peer doesn't support it,
+// it returns "" and no error.
+func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
+	if len(serverProtos) == 0 || len(clientProtos) == 0 {
+		return "", nil
+	}
+	var http11fallback bool
+	for _, s := range serverProtos {
+		for _, c := range clientProtos {
+			if s == c {
+				return s, nil
+			}
+			if s == "h2" && c == "http/1.1" {
+				http11fallback = true
+			}
+		}
+	}
+	// As a special case, let http/1.1 clients connect to h2 servers as if they
+	// didn't support ALPN. We used not to enforce protocol overlap, so over
+	// time a number of HTTP servers were configured with only "h2", but
+	// expected to accept connections from "http/1.1" clients. See Issue 46310.
+	if http11fallback {
+		return "", nil
+	}
+	return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
+}
+
 // supportsECDHE returns whether ECDHE key exchanges can be used with this
 // pre-TLS 1.3 client.
 func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index 4483838..f61b4c8 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -949,6 +949,27 @@
 	runServerTestTLS13(t, test)
 }
 
+func TestHandshakeServerALPNFallback(t *testing.T) {
+	config := testConfig.Clone()
+	config.NextProtos = []string{"proto1", "h2", "proto2"}
+
+	test := &serverTest{
+		name: "ALPN-Fallback",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
+		command: []string{"openssl", "s_client", "-alpn", "proto3,http/1.1,proto4", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+		config:  config,
+		validate: func(state ConnectionState) error {
+			if state.NegotiatedProtocol != "" {
+				return fmt.Errorf("Got protocol %q, wanted nothing", state.NegotiatedProtocol)
+			}
+			return nil
+		},
+	}
+	runServerTestTLS12(t, test)
+	runServerTestTLS13(t, test)
+}
+
 // TestHandshakeServerSNI involves a client sending an SNI extension of
 // "snitest.com", which happens to match the CN of testSNICertificate. The test
 // verifies that the server correctly selects that certificate.
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
index c375ec4..08251b8 100644
--- a/src/crypto/tls/handshake_server_tls13.go
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -11,7 +11,6 @@
 	"crypto/hmac"
 	"crypto/rsa"
 	"errors"
-	"fmt"
 	"hash"
 	"io"
 	"sync/atomic"
@@ -551,15 +550,13 @@
 
 	encryptedExtensions := new(encryptedExtensionsMsg)
 
-	if len(c.config.NextProtos) > 0 && len(hs.clientHello.alpnProtocols) > 0 {
-		selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos)
-		if selectedProto == "" {
-			c.sendAlert(alertNoApplicationProtocol)
-			return fmt.Errorf("tls: client requested unsupported application protocols (%s)", hs.clientHello.alpnProtocols)
-		}
-		encryptedExtensions.alpnProtocol = selectedProto
-		c.clientProtocol = selectedProto
+	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+	if err != nil {
+		c.sendAlert(alertNoApplicationProtocol)
+		return err
 	}
+	encryptedExtensions.alpnProtocol = selectedProto
+	c.clientProtocol = selectedProto
 
 	hs.transcript.Write(encryptedExtensions.marshal())
 	if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil {
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
new file mode 100644
index 0000000..4fadf39
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 a6 01 00 00  a2 03 03 b5 c9 ab 32 7f  |..............2.|
+00000010  e1 af 3f f2 ac 2a 11 dd  33 f9 b5 21 88 0d e4 29  |..?..*..3..!...)|
+00000020  e2 47 49 dc c7 31 a8 a5  25 81 0c 00 00 04 cc a8  |.GI..1..%.......|
+00000030  00 ff 01 00 00 75 00 0b  00 04 03 00 01 02 00 0a  |.....u..........|
+00000040  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
+00000050  00 00 00 10 00 19 00 17  06 70 72 6f 74 6f 33 08  |.........proto3.|
+00000060  68 74 74 70 2f 31 2e 31  06 70 72 6f 74 6f 34 00  |http/1.1.proto4.|
+00000070  16 00 00 00 17 00 00 00  0d 00 30 00 2e 04 03 05  |..........0.....|
+00000080  03 06 03 08 07 08 08 08  09 08 0a 08 0b 08 04 08  |................|
+00000090  05 08 06 04 01 05 01 06  01 03 03 02 03 03 01 02  |................|
+000000a0  01 03 02 02 02 04 02 05  02 06 02                 |...........|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 3b 02 00 00  37 03 03 00 00 00 00 00  |....;...7.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 44 4f 57 4e 47  52 44 01 00 cc a8 00 00  |...DOWNGRD......|
+00000030  0f 00 23 00 00 ff 01 00  01 00 00 0b 00 02 01 00  |..#.............|
+00000040  16 03 03 02 59 0b 00 02  55 00 02 52 00 02 4f 30  |....Y...U..R..O0|
+00000050  82 02 4b 30 82 01 b4 a0  03 02 01 02 02 09 00 e8  |..K0............|
+00000060  f0 9d 3f e2 5b ea a6 30  0d 06 09 2a 86 48 86 f7  |..?.[..0...*.H..|
+00000070  0d 01 01 0b 05 00 30 1f  31 0b 30 09 06 03 55 04  |......0.1.0...U.|
+00000080  0a 13 02 47 6f 31 10 30  0e 06 03 55 04 03 13 07  |...Go1.0...U....|
+00000090  47 6f 20 52 6f 6f 74 30  1e 17 0d 31 36 30 31 30  |Go Root0...16010|
+000000a0  31 30 30 30 30 30 30 5a  17 0d 32 35 30 31 30 31  |1000000Z..250101|
+000000b0  30 30 30 30 30 30 5a 30  1a 31 0b 30 09 06 03 55  |000000Z0.1.0...U|
+000000c0  04 0a 13 02 47 6f 31 0b  30 09 06 03 55 04 03 13  |....Go1.0...U...|
+000000d0  02 47 6f 30 81 9f 30 0d  06 09 2a 86 48 86 f7 0d  |.Go0..0...*.H...|
+000000e0  01 01 01 05 00 03 81 8d  00 30 81 89 02 81 81 00  |.........0......|
+000000f0  db 46 7d 93 2e 12 27 06  48 bc 06 28 21 ab 7e c4  |.F}...'.H..(!.~.|
+00000100  b6 a2 5d fe 1e 52 45 88  7a 36 47 a5 08 0d 92 42  |..]..RE.z6G....B|
+00000110  5b c2 81 c0 be 97 79 98  40 fb 4f 6d 14 fd 2b 13  |[.....y.@.Om..+.|
+00000120  8b c2 a5 2e 67 d8 d4 09  9e d6 22 38 b7 4a 0b 74  |....g....."8.J.t|
+00000130  73 2b c2 34 f1 d1 93 e5  96 d9 74 7b f3 58 9f 6c  |s+.4......t{.X.l|
+00000140  61 3c c0 b0 41 d4 d9 2b  2b 24 23 77 5b 1c 3b bd  |a<..A..++$#w[.;.|
+00000150  75 5d ce 20 54 cf a1 63  87 1d 1e 24 c4 f3 1d 1a  |u]. T..c...$....|
+00000160  50 8b aa b6 14 43 ed 97  a7 75 62 f4 14 c8 52 d7  |P....C...ub...R.|
+00000170  02 03 01 00 01 a3 81 93  30 81 90 30 0e 06 03 55  |........0..0...U|
+00000180  1d 0f 01 01 ff 04 04 03  02 05 a0 30 1d 06 03 55  |...........0...U|
+00000190  1d 25 04 16 30 14 06 08  2b 06 01 05 05 07 03 01  |.%..0...+.......|
+000001a0  06 08 2b 06 01 05 05 07  03 02 30 0c 06 03 55 1d  |..+.......0...U.|
+000001b0  13 01 01 ff 04 02 30 00  30 19 06 03 55 1d 0e 04  |......0.0...U...|
+000001c0  12 04 10 9f 91 16 1f 43  43 3e 49 a6 de 6d b6 80  |.......CC>I..m..|
+000001d0  d7 9f 60 30 1b 06 03 55  1d 23 04 14 30 12 80 10  |..`0...U.#..0...|
+000001e0  48 13 49 4d 13 7e 16 31  bb a3 01 d5 ac ab 6e 7b  |H.IM.~.1......n{|
+000001f0  30 19 06 03 55 1d 11 04  12 30 10 82 0e 65 78 61  |0...U....0...exa|
+00000200  6d 70 6c 65 2e 67 6f 6c  61 6e 67 30 0d 06 09 2a  |mple.golang0...*|
+00000210  86 48 86 f7 0d 01 01 0b  05 00 03 81 81 00 9d 30  |.H.............0|
+00000220  cc 40 2b 5b 50 a0 61 cb  ba e5 53 58 e1 ed 83 28  |.@+[P.a...SX...(|
+00000230  a9 58 1a a9 38 a4 95 a1  ac 31 5a 1a 84 66 3d 43  |.X..8....1Z..f=C|
+00000240  d3 2d d9 0b f2 97 df d3  20 64 38 92 24 3a 00 bc  |.-...... d8.$:..|
+00000250  cf 9c 7d b7 40 20 01 5f  aa d3 16 61 09 a2 76 fd  |..}.@ ._...a..v.|
+00000260  13 c3 cc e1 0c 5c ee b1  87 82 f1 6c 04 ed 73 bb  |.....\.....l..s.|
+00000270  b3 43 77 8d 0c 1c f1 0f  a1 d8 40 83 61 c9 4c 72  |.Cw.......@.a.Lr|
+00000280  2b 9d ae db 46 06 06 4d  f4 c1 b3 3e c0 d1 bd 42  |+...F..M...>...B|
+00000290  d4 db fe 3d 13 60 84 5c  21 d3 3b e9 fa e7 16 03  |...=.`.\!.;.....|
+000002a0  03 00 ac 0c 00 00 a8 03  00 1d 20 2f e5 7d a3 47  |.......... /.}.G|
+000002b0  cd 62 43 15 28 da ac 5f  bb 29 07 30 ff f6 84 af  |.bC.(.._.).0....|
+000002c0  c4 cf c2 ed 90 99 5f 58  cb 3b 74 08 04 00 80 5f  |......_X.;t...._|
+000002d0  37 27 84 58 1e ea 1e 40  1b de a9 8f 04 d4 94 64  |7'.X...@.......d|
+000002e0  4e 27 c7 f1 b3 30 d0 53  f5 3d 57 50 d2 17 97 c8  |N'...0.S.=WP....|
+000002f0  3d 61 af a6 21 ab 1c 34  47 70 f8 b1 3b 9c 06 86  |=a..!..4Gp..;...|
+00000300  87 00 e2 13 50 83 91 ad  bc 84 bd b4 7b f3 4b ed  |....P.......{.K.|
+00000310  ca 81 0c 94 37 a8 ec 67  ca 9c f3 00 f6 af c2 92  |....7..g........|
+00000320  c4 8c 78 07 18 0e 43 24  1b 98 16 50 5c 2b 75 0e  |..x...C$...P\+u.|
+00000330  40 66 dc 40 cd 10 1a 51  25 f3 96 25 1a 3e 70 af  |@f.@...Q%..%.>p.|
+00000340  16 24 d0 1c 0e 33 f9 c1  74 cf b7 e2 28 ac 60 16  |.$...3..t...(.`.|
+00000350  03 03 00 04 0e 00 00 00                           |........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 25 10 00 00  21 20 30 f2 bb f7 a7 ac  |....%...! 0.....|
+00000010  23 20 22 ee 73 0d 49 9c  b3 7b c1 9a db 2c 85 f3  |# ".s.I..{...,..|
+00000020  c0 82 31 60 bd 8b 14 4e  73 43 14 03 03 00 01 01  |..1`...NsC......|
+00000030  16 03 03 00 20 09 8d c7  86 ee cc f4 c7 36 a3 49  |.... ........6.I|
+00000040  d3 f7 a1 4a 68 a2 1e b4  fc cc a2 15 cb 01 92 d8  |...Jh...........|
+00000050  72 b0 d1 6f eb                                    |r..o.|
+>>> Flow 4 (server to client)
+00000000  16 03 03 00 8b 04 00 00  87 00 00 00 00 00 81 50  |...............P|
+00000010  46 ad c1 db a8 38 86 7b  2b bb fd d0 c3 42 3e 00  |F....8.{+....B>.|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 94  |................|
+00000030  6f e0 18 83 51 ed 14 ef  68 ca 42 c5 4c a2 ac 05  |o...Q...h.B.L...|
+00000040  9c 69 69 99 08 9f de a4  d4 e7 37 ab 14 38 4c 47  |.ii.......7..8LG|
+00000050  70 f0 97 1d db 2d 0a 14  c2 1e f0 16 9f 6d 37 02  |p....-.......m7.|
+00000060  4b f1 16 be 98 3f df 74  83 7c 19 85 61 49 38 16  |K....?.t.|..aI8.|
+00000070  ee 35 7a e2 3f 74 fe 8d  e3 07 93 a1 5e fa f2 02  |.5z.?t......^...|
+00000080  e5 c8 60 3f 11 83 8b 0e  32 52 f1 aa 52 b7 0a 89  |..`?....2R..R...|
+00000090  14 03 03 00 01 01 16 03  03 00 20 9e 65 15 cf 45  |.......... .e..E|
+000000a0  a5 03 69 c9 b1 d8 9e 92  a3 a2 b0 df 2e 62 b1 3a  |..i..........b.:|
+000000b0  17 78 cd e5 1d f3 51 42  7e 4e 25 17 03 03 00 1d  |.x....QB~N%.....|
+000000c0  d9 ae d0 fa b7 90 a9 2f  28 8d 1d 6f 54 1f c0 1e  |......./(..oT...|
+000000d0  4d ae b6 91 f0 e8 84 cf  86 11 22 25 ea 15 03 03  |M........."%....|
+000000e0  00 12 0e 71 f2 11 9e 9f  58 ad c0 d8 fc fa 34 bc  |...q....X.....4.|
+000000f0  02 5a 60 00                                       |.Z`.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
new file mode 100644
index 0000000..6203e68
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 eb 01 00 00  e7 03 03 1c d3 8e 3b d9  |..............;.|
+00000010  fe 7d e7 f9 9f fa c6 51  c3 8c 1b dd dc 87 95 f4  |.}.....Q........|
+00000020  39 23 67 e4 d6 bd 94 93  fc 88 4e 20 c3 c0 e2 c1  |9#g.......N ....|
+00000030  3d 12 ec 4c 0a 3f 40 51  13 24 61 11 c0 5d 09 f9  |=..L.?@Q.$a..]..|
+00000040  08 d6 3e cd e7 b3 51 c3  06 8f b4 42 00 04 13 03  |..>...Q....B....|
+00000050  00 ff 01 00 00 9a 00 0b  00 04 03 00 01 02 00 0a  |................|
+00000060  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 23  |...............#|
+00000070  00 00 00 10 00 19 00 17  06 70 72 6f 74 6f 33 08  |.........proto3.|
+00000080  68 74 74 70 2f 31 2e 31  06 70 72 6f 74 6f 34 00  |http/1.1.proto4.|
+00000090  16 00 00 00 17 00 00 00  0d 00 1e 00 1c 04 03 05  |................|
+000000a0  03 06 03 08 07 08 08 08  09 08 0a 08 0b 08 04 08  |................|
+000000b0  05 08 06 04 01 05 01 06  01 00 2b 00 03 02 03 04  |..........+.....|
+000000c0  00 2d 00 02 01 01 00 33  00 26 00 24 00 1d 00 20  |.-.....3.&.$... |
+000000d0  f4 05 eb 4a 7a 73 20 18  74 aa 14 2a 0c 35 63 29  |...Jzs .t..*.5c)|
+000000e0  cb f2 ad d1 a2 3d bd 9d  02 b4 62 00 bc eb 10 58  |.....=....b....X|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 7a 02 00 00  76 03 03 00 00 00 00 00  |....z...v.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 c3 c0 e2 c1  |........... ....|
+00000030  3d 12 ec 4c 0a 3f 40 51  13 24 61 11 c0 5d 09 f9  |=..L.?@Q.$a..]..|
+00000040  08 d6 3e cd e7 b3 51 c3  06 8f b4 42 13 03 00 00  |..>...Q....B....|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 2f  |..+.....3.$... /|
+00000060  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
+00000070  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74 14  |.........._X.;t.|
+00000080  03 03 00 01 01 17 03 03  00 17 fb 75 d8 5c 50 35  |...........u.\P5|
+00000090  55 82 ba 65 1e 63 73 b8  c1 e9 d7 f5 28 68 3c c1  |U..e.cs.....(h<.|
+000000a0  5d 17 03 03 02 6d 56 c9  a9 09 73 6a bc fd 1a 3c  |]....mV...sj...<|
+000000b0  6a f8 3e 32 99 83 e8 f6  01 9e 5e 30 e8 53 7f 72  |j.>2......^0.S.r|
+000000c0  fd 86 72 a8 9e 47 25 67  c1 f1 9a 03 c0 9d 6f 9d  |..r..G%g......o.|
+000000d0  bd ed 29 30 8f 3c 01 ce  49 bb 5f dd 58 9a ae 80  |..)0.<..I._.X...|
+000000e0  5c 2d 81 fc ea 7b 03 03  3d 5d bb 92 23 73 67 89  |\-...{..=]..#sg.|
+000000f0  2e f0 ec 08 20 8a 36 eb  43 a6 a1 68 d0 39 95 37  |.... .6.C..h.9.7|
+00000100  6b 15 a9 0e 46 20 92 51  9c 04 bf 3b 07 97 84 cb  |k...F .Q...;....|
+00000110  1f 30 38 37 2e ff e7 0f  f5 14 93 5a 84 f1 f7 10  |.087.......Z....|
+00000120  c2 a5 0d bb 97 96 ef 4a  e0 13 c0 63 72 2b 60 f3  |.......J...cr+`.|
+00000130  59 b5 57 aa 5f d1 da a9  0e dd 9c dd c2 cb 61 fe  |Y.W._.........a.|
+00000140  e2 69 8e db 5d 70 6c 3a  33 e0 9e db 9a 31 26 6a  |.i..]pl:3....1&j|
+00000150  2b 9e 19 8e bb 5d 06 48  ea c0 a1 c6 11 24 fb c4  |+....].H.....$..|
+00000160  ce ae 48 54 64 81 d1 84  38 a6 e0 7a 7b 74 2b bc  |..HTd...8..z{t+.|
+00000170  ce 07 8b b6 04 1f 5b 4c  36 29 68 0c 8c c7 32 15  |......[L6)h...2.|
+00000180  93 e0 10 52 c2 27 23 96  c5 0c 9c e9 e2 a9 08 7d  |...R.'#........}|
+00000190  25 68 65 f5 4e 44 eb a9  85 78 13 e1 0d 86 5e dc  |%he.ND...x....^.|
+000001a0  fd e5 c6 dd 65 46 8e 2f  32 82 83 0b dd 67 f8 42  |....eF./2....g.B|
+000001b0  65 87 3b 08 fe b1 f5 12  e9 74 21 04 12 6d 75 35  |e.;......t!..mu5|
+000001c0  b2 eb 93 95 72 10 fa 56  96 77 c3 0c 17 8c 9e f6  |....r..V.w......|
+000001d0  77 19 28 37 96 3e 73 98  f4 d2 91 4f 40 db 76 56  |w.(7.>s....O@.vV|
+000001e0  ce b5 a8 7a b8 86 d0 9a  ba b5 8b 40 c2 63 e1 cf  |...z.......@.c..|
+000001f0  49 29 2c 5d 1a 9b 8b 56  cb 93 ca 2c c0 d0 15 b7  |I),]...V...,....|
+00000200  8a f1 6a d5 0a a8 81 57  b1 6e 10 cd a5 ff b1 4d  |..j....W.n.....M|
+00000210  47 c6 9b 35 f1 5f 83 91  22 f6 88 68 65 b3 b9 c9  |G..5._.."..he...|
+00000220  02 dc 4b f7 13 39 06 e6  3a ec 94 ef 51 15 05 72  |..K..9..:...Q..r|
+00000230  1d f4 9d 3b da ca 8d 2c  64 be 9b 45 99 2c 63 cc  |...;...,d..E.,c.|
+00000240  22 b3 8b 93 ad f6 2c f0  d2 d9 11 3f 5b c0 40 fa  |".....,....?[.@.|
+00000250  90 6e a0 76 b2 43 b9 4c  72 c4 24 28 a2 bf 56 d6  |.n.v.C.Lr.$(..V.|
+00000260  d2 a7 2a d1 8c 5e 1d eb  f8 be d0 43 da 7a c7 88  |..*..^.....C.z..|
+00000270  61 67 a2 69 85 23 43 3e  d4 88 f2 33 c3 5b 38 0a  |ag.i.#C>...3.[8.|
+00000280  1e de 28 3b 3b 19 de 95  2f 84 c0 37 88 80 59 2f  |..(;;.../..7..Y/|
+00000290  a6 ee 93 1a 69 08 c3 df  7c cf da c3 9b 96 70 d9  |....i...|.....p.|
+000002a0  60 c5 e9 0f 42 f6 1a f2  58 5e f2 32 61 6a b2 a3  |`...B...X^.2aj..|
+000002b0  1f 97 fa 08 6c 3f 4b 83  1f 04 66 80 8a 26 3a 7f  |....l?K...f..&:.|
+000002c0  24 30 ec 10 ae 7d 19 ff  39 91 ca 97 4e ed 0a d7  |$0...}..9...N...|
+000002d0  64 3b 6b 50 29 33 0d b2  10 bc 83 63 3c fb 9a 82  |d;kP)3.....c<...|
+000002e0  3b 7f bc 04 40 f1 33 64  4a 80 cd 01 f9 f4 c6 89  |;...@.3dJ.......|
+000002f0  65 27 25 f9 cf 4f 7e c8  6e d9 0e ec 47 4a 51 29  |e'%..O~.n...GJQ)|
+00000300  2f be 34 50 bd 9b d2 d8  b7 ea bb 0b a1 e0 20 1b  |/.4P.......... .|
+00000310  02 9c f2 17 03 03 00 99  61 dc 0b 3a 30 de 39 f6  |........a..:0.9.|
+00000320  f3 db f8 6c 3b fa 4e 1e  7e 62 a5 ae 73 ba e1 41  |...l;.N.~b..s..A|
+00000330  58 77 2a c1 7a 0c 50 bb  0c 57 b4 c4 25 bf 2f 9f  |Xw*.z.P..W..%./.|
+00000340  38 91 e2 65 22 9d ca ac  18 58 7e 81 2d fd 74 24  |8..e"....X~.-.t$|
+00000350  28 69 76 11 df 9d 23 b8  be ae 8b e0 93 8e 5d df  |(iv...#.......].|
+00000360  0a 64 d0 b7 02 68 aa 86  01 0d 55 11 3b 76 70 c6  |.d...h....U.;vp.|
+00000370  83 0c 5e 0a e3 37 a5 8b  ad 25 50 b9 e8 5c 6b 04  |..^..7...%P..\k.|
+00000380  b4 51 ec 9c d3 fa c6 b7  9c f0 46 aa 73 da 3c 0d  |.Q........F.s.<.|
+00000390  d3 bd 32 81 d4 d2 f1 1a  b0 92 f3 73 3e 54 2b 05  |..2........s>T+.|
+000003a0  92 24 34 75 df d6 18 a0  6a 82 95 4c 9b fc 7e b6  |.$4u....j..L..~.|
+000003b0  8e 17 03 03 00 35 8f 34  0e 3b 91 d8 e7 74 24 71  |.....5.4.;...t$q|
+000003c0  0e 7b f3 12 bb 76 2f 31  12 17 b8 9e 24 ce f9 2f  |.{...v/1....$../|
+000003d0  3f 5d f2 13 4b 2e 9b 1e  c4 78 03 a6 c8 07 11 a3  |?]..K....x......|
+000003e0  98 79 61 6e 4f 44 6e 18  ee c4 9b 17 03 03 00 93  |.yanODn.........|
+000003f0  64 dd 52 a9 d9 51 63 6a  a0 a3 c2 75 6b 5d 1d 54  |d.R..Qcj...uk].T|
+00000400  ce d4 53 7e 14 8e d9 26  93 28 78 65 16 1b 95 77  |..S~...&.(xe...w|
+00000410  68 0a 46 f1 82 36 bb 8a  fa 0d df 54 8c 3d 83 e0  |h.F..6.....T.=..|
+00000420  d7 de 2d 96 e9 c4 d7 22  d3 97 8e ae 90 f8 fc e6  |..-...."........|
+00000430  a6 4b 78 98 4c c5 28 87  91 46 fa f4 1c 8d 0e ec  |.Kx.L.(..F......|
+00000440  0d 71 40 9a 04 49 b4 e8  5b 62 6f cd 16 c1 d5 fb  |.q@..I..[bo.....|
+00000450  73 2a 96 8f e5 a2 f4 11  1e df 2d 40 45 6b d5 a9  |s*........-@Ek..|
+00000460  e4 e3 f7 93 fc fa d7 20  af d5 f7 b4 0e 09 ad d5  |....... ........|
+00000470  26 87 b8 6c e2 20 95 fb  c0 70 3e 38 be b7 b1 9f  |&..l. ...p>8....|
+00000480  70 da c1                                          |p..|
+>>> Flow 3 (client to server)
+00000000  14 03 03 00 01 01 17 03  03 00 35 29 d2 b9 bb 9b  |..........5)....|
+00000010  de 6c 5d 22 23 c1 fe 99  4c c5 33 bf fd 70 36 6b  |.l]"#...L.3..p6k|
+00000020  f1 a5 92 e8 bf 7c 3d 6e  ef 6a 44 73 bc cb 27 1c  |.....|=n.jDs..'.|
+00000030  09 5d bf 99 4c 19 24 c3  3b 30 91 b5 e3 b6 63 45  |.]..L.$.;0....cE|
+>>> Flow 4 (server to client)
+00000000  17 03 03 00 1e 52 55 85  7c b8 87 dd c7 b2 d9 5b  |.....RU.|......[|
+00000010  18 1d bb ac bf b6 ab 76  82 be 64 0e b2 7b 2c 0f  |.......v..d..{,.|
+00000020  aa 17 92 17 03 03 00 13  79 0a 60 b1 46 20 33 74  |........y.`.F 3t|
+00000030  ed 12 a0 23 de 68 88 fc  6f dd 8e                 |...#.h..o..|