This change adds support for the ChaCha20-Poly1305 AEAD to crypto/tls, as specified in https://tools.ietf.org/html/rfc7905. Fixes #15499. Change-Id: Iaa689be90e03f208c40b574eca399e56f3c7ecf1 Reviewed-on: https://go-review.googlesource.com/30957 Run-TryBot: Adam Langley <agl@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>v1.2.3
@@ -14,6 +14,8 @@ import ( | |||
"crypto/sha256" | |||
"crypto/x509" | |||
"hash" | |||
"golang_org/x/crypto/chacha20poly1305" | |||
) | |||
// a keyAgreement implements the client and server side of a TLS key agreement | |||
@@ -75,7 +77,9 @@ type cipherSuite struct { | |||
var cipherSuites = []*cipherSuite{ | |||
// Ciphersuite order is chosen so that ECDHE comes before plain RSA and | |||
// GCM is top preference. | |||
// AEADs are the top preference. | |||
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, nil, nil, aeadChaCha20Poly1305}, | |||
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff, nil, nil, aeadChaCha20Poly1305}, | |||
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, | |||
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, | |||
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, | |||
@@ -145,6 +149,15 @@ type macFunction interface { | |||
MAC(digestBuf, seq, header, data, extra []byte) []byte | |||
} | |||
type aead interface { | |||
cipher.AEAD | |||
// explicitIVLen returns the number of bytes used by the explicit nonce | |||
// that is included in the record. This is eight for older AEADs and | |||
// zero for modern ones. | |||
explicitNonceLen() int | |||
} | |||
// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to | |||
// each call. | |||
type fixedNonceAEAD struct { | |||
@@ -155,8 +168,9 @@ type fixedNonceAEAD struct { | |||
aead cipher.AEAD | |||
} | |||
func (f *fixedNonceAEAD) NonceSize() int { return 8 } | |||
func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } | |||
func (f *fixedNonceAEAD) NonceSize() int { return 8 } | |||
func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } | |||
func (f *fixedNonceAEAD) explicitNonceLen() int { return 8 } | |||
func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { | |||
copy(f.sealNonce[len(f.sealNonce)-8:], nonce) | |||
@@ -168,6 +182,41 @@ func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]b | |||
return f.aead.Open(out, f.openNonce, plaintext, additionalData) | |||
} | |||
// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce | |||
// before each call. | |||
type xorNonceAEAD struct { | |||
nonceMask [12]byte | |||
aead cipher.AEAD | |||
} | |||
func (f *xorNonceAEAD) NonceSize() int { return 8 } | |||
func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() } | |||
func (f *xorNonceAEAD) explicitNonceLen() int { return 0 } | |||
func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { | |||
for i, b := range nonce { | |||
f.nonceMask[4+i] ^= b | |||
} | |||
result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData) | |||
for i, b := range nonce { | |||
f.nonceMask[4+i] ^= b | |||
} | |||
return result | |||
} | |||
func (f *xorNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) { | |||
for i, b := range nonce { | |||
f.nonceMask[4+i] ^= b | |||
} | |||
result, err := f.aead.Open(out, f.nonceMask[:], plaintext, additionalData) | |||
for i, b := range nonce { | |||
f.nonceMask[4+i] ^= b | |||
} | |||
return result, err | |||
} | |||
func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { | |||
aes, err := aes.NewCipher(key) | |||
if err != nil { | |||
@@ -185,6 +234,17 @@ func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { | |||
return &fixedNonceAEAD{nonce1, nonce2, aead} | |||
} | |||
func aeadChaCha20Poly1305(key, fixedNonce []byte) cipher.AEAD { | |||
aead, err := chacha20poly1305.New(key) | |||
if err != nil { | |||
panic(err) | |||
} | |||
ret := &xorNonceAEAD{aead: aead} | |||
copy(ret.nonceMask[:], fixedNonce) | |||
return ret | |||
} | |||
// ssl30MAC implements the SSLv3 MAC function, as defined in | |||
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 | |||
type ssl30MAC struct { | |||
@@ -330,6 +390,8 @@ const ( | |||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b | |||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 | |||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c | |||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca8 | |||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca9 | |||
// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator | |||
// that the client is doing version fallback. See | |||
@@ -285,13 +285,17 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) | |||
switch c := hc.cipher.(type) { | |||
case cipher.Stream: | |||
c.XORKeyStream(payload, payload) | |||
case cipher.AEAD: | |||
explicitIVLen = 8 | |||
case aead: | |||
explicitIVLen = c.explicitNonceLen() | |||
if len(payload) < explicitIVLen { | |||
return false, 0, alertBadRecordMAC | |||
} | |||
nonce := payload[:8] | |||
payload = payload[8:] | |||
nonce := payload[:explicitIVLen] | |||
payload = payload[explicitIVLen:] | |||
if len(nonce) == 0 { | |||
nonce = hc.seq[:] | |||
} | |||
copy(hc.additionalData[:], hc.seq[:]) | |||
copy(hc.additionalData[8:], b.data[:3]) | |||
@@ -398,10 +402,13 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { | |||
switch c := hc.cipher.(type) { | |||
case cipher.Stream: | |||
c.XORKeyStream(payload, payload) | |||
case cipher.AEAD: | |||
case aead: | |||
payloadLen := len(b.data) - recordHeaderLen - explicitIVLen | |||
b.resize(len(b.data) + c.Overhead()) | |||
nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] | |||
if len(nonce) == 0 { | |||
nonce = hc.seq[:] | |||
} | |||
payload := b.data[recordHeaderLen+explicitIVLen:] | |||
payload = payload[:payloadLen] | |||
@@ -859,15 +866,16 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { | |||
} | |||
} | |||
if explicitIVLen == 0 { | |||
if _, ok := c.out.cipher.(cipher.AEAD); ok { | |||
explicitIVLen = 8 | |||
if c, ok := c.out.cipher.(aead); ok { | |||
explicitIVLen = c.explicitNonceLen() | |||
// The AES-GCM construction in TLS has an | |||
// explicit nonce so that the nonce can be | |||
// random. However, the nonce is only 8 bytes | |||
// which is too small for a secure, random | |||
// nonce. Therefore we use the sequence number | |||
// as the nonce. | |||
explicitIVIsSeq = true | |||
explicitIVIsSeq = explicitIVLen > 0 | |||
} | |||
} | |||
m := len(data) | |||
@@ -550,6 +550,34 @@ func TestHandshakeClientX25519(t *testing.T) { | |||
runClientTestTLS12(t, test) | |||
} | |||
func TestHandshakeClientECDHERSAChaCha20(t *testing.T) { | |||
config := testConfig.Clone() | |||
config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305} | |||
test := &clientTest{ | |||
name: "ECDHE-RSA-CHACHA20-POLY1305", | |||
command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305"}, | |||
config: config, | |||
} | |||
runClientTestTLS12(t, test) | |||
} | |||
func TestHandshakeClientECDHEECDSAChaCha20(t *testing.T) { | |||
config := testConfig.Clone() | |||
config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305} | |||
test := &clientTest{ | |||
name: "ECDHE-ECDSA-CHACHA20-POLY1305", | |||
command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-CHACHA20-POLY1305"}, | |||
config: config, | |||
cert: testECDSACertificate, | |||
key: testECDSAPrivateKey, | |||
} | |||
runClientTestTLS12(t, test) | |||
} | |||
func TestHandshakeClientCertRSA(t *testing.T) { | |||
config := testConfig.Clone() | |||
cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM)) | |||
@@ -40,6 +40,12 @@ var testConfig *Config | |||
func allCipherSuites() []uint16 { | |||
ids := make([]uint16, len(cipherSuites)) | |||
for i, suite := range cipherSuites { | |||
// Skip ChaCha20-Poly1305 cipher suites until they are enabled | |||
// by default. | |||
switch suite.id { | |||
case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: | |||
continue | |||
} | |||
ids[i] = suite.id | |||
} | |||
@@ -0,0 +1,77 @@ | |||
>>> Flow 1 (client to server) | |||
00000000 16 03 01 00 67 01 00 00 63 03 03 00 00 00 00 00 |....g...c.......| | |||
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 00 00 02 cc a9 |................| | |||
00000030 01 00 00 38 00 05 00 05 01 00 00 00 00 00 0a 00 |...8............| | |||
00000040 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................| | |||
00000050 00 00 0d 00 0e 00 0c 04 01 04 03 05 01 05 03 02 |................| | |||
00000060 01 02 03 ff 01 00 01 00 00 12 00 00 |............| | |||
>>> Flow 2 (server to client) | |||
00000000 16 03 03 00 59 02 00 00 55 03 03 d6 47 27 38 fc |....Y...U...G'8.| | |||
00000010 16 92 2c 1f a6 53 a9 31 85 65 a7 83 0a 8f cb 4d |..,..S.1.e.....M| | |||
00000020 7d 5b df c1 2e b9 b1 08 e3 b9 96 20 16 0c e5 07 |}[......... ....| | |||
00000030 27 cc 4f 7d 11 ef 1a 14 c6 42 bf e9 c1 b7 a5 89 |'.O}.....B......| | |||
00000040 ca 2b 4c 30 4f c7 c8 10 13 b0 b1 6b cc a9 00 00 |.+L0O......k....| | |||
00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| | |||
00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..| | |||
00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....| | |||
00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0| | |||
00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...| | |||
000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1| | |||
000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern| | |||
000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L| | |||
000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506| | |||
000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063| | |||
000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A| | |||
00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some| | |||
00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...| | |||
00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit| | |||
00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...| | |||
00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..| | |||
00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.| | |||
00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.| | |||
00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d| | |||
00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i| | |||
00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.| | |||
000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#| | |||
000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.| | |||
000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.| | |||
000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=| | |||
000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.| | |||
000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^| | |||
00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......| | |||
00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y| | |||
00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.| | |||
00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3| | |||
00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....| | |||
00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.| | |||
00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....| | |||
00000270 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 69 78 |*............ ix| | |||
00000280 7b e5 14 95 c8 d1 3c 7e c2 d7 38 33 c3 9f 8f dc |{.....<~..83....| | |||
00000290 25 8d 89 8a 99 a4 e4 8b 40 17 fc 80 43 67 04 03 |%.......@...Cg..| | |||
000002a0 00 8b 30 81 88 02 42 01 32 a8 dd d9 ec 11 d2 f2 |..0...B.2.......| | |||
000002b0 6d 86 da 31 00 8c bf ed 81 1d 8c c8 23 87 98 f7 |m..1........#...| | |||
000002c0 25 0c 1b 3d 9f 07 80 11 bc 07 b1 15 5f 3a 81 0e |%..=........_:..| | |||
000002d0 59 04 e8 09 be ea 21 97 34 a9 8a 2f ef 3a 47 ad |Y.....!.4../.:G.| | |||
000002e0 3b f9 9d f3 b8 b8 9a 93 03 02 42 01 bc 88 6b 99 |;.........B...k.| | |||
000002f0 d7 7a df de 5a 75 53 b0 3c 4c 1d 8b 15 c5 a7 9d |.z..ZuS.<L......| | |||
00000300 3d 00 c0 f7 19 47 88 30 00 29 24 80 23 45 88 2e |=....G.0.)$.#E..| | |||
00000310 11 60 3e 4b 6a 41 ad dc 3d 7d 3f 59 a0 0e fd d6 |.`>KjA..=}?Y....| | |||
00000320 f7 c7 7f 63 49 2f e4 4e d9 8f 2d e5 98 16 03 03 |...cI/.N..-.....| | |||
00000330 00 04 0e 00 00 00 |......| | |||
>>> Flow 3 (client to server) | |||
00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| | |||
00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| | |||
00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| | |||
00000030 16 03 03 00 20 7c 89 36 36 77 8c 09 31 e4 48 01 |.... |.66w..1.H.| | |||
00000040 6f 08 27 a8 bb 1b 1c a6 0c 09 ec 0b f6 a3 be bd |o.'.............| | |||
00000050 76 70 fb f8 e5 |vp...| | |||
>>> Flow 4 (server to client) | |||
00000000 14 03 03 00 01 01 16 03 03 00 20 a0 db 6c df b1 |.......... ..l..| | |||
00000010 87 77 78 ad 22 b2 98 77 e8 57 aa 13 a8 98 35 63 |.wx."..w.W....5c| | |||
00000020 00 c5 13 b9 88 5d ca bf bc c5 c3 |.....].....| | |||
>>> Flow 5 (client to server) | |||
00000000 17 03 03 00 16 16 00 c8 c6 25 ae 11 9d a5 10 75 |.........%.....u| | |||
00000010 e4 4c e3 69 12 2b d9 9e 8e 40 88 15 03 03 00 12 |.L.i.+...@......| | |||
00000020 cf ab ac d4 c4 8e 9c 92 c4 2f 1f c6 96 0b 36 c9 |........./....6.| | |||
00000030 f5 22 |."| |
@@ -0,0 +1,81 @@ | |||
>>> Flow 1 (client to server) | |||
00000000 16 03 01 00 67 01 00 00 63 03 03 00 00 00 00 00 |....g...c.......| | |||
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 00 00 02 cc a8 |................| | |||
00000030 01 00 00 38 00 05 00 05 01 00 00 00 00 00 0a 00 |...8............| | |||
00000040 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................| | |||
00000050 00 00 0d 00 0e 00 0c 04 01 04 03 05 01 05 03 02 |................| | |||
00000060 01 02 03 ff 01 00 01 00 00 12 00 00 |............| | |||
>>> Flow 2 (server to client) | |||
00000000 16 03 03 00 59 02 00 00 55 03 03 45 f5 61 06 a8 |....Y...U..E.a..| | |||
00000010 4e ce c0 32 d6 af fb 12 5e c8 6c 06 ac c9 d7 e4 |N..2....^.l.....| | |||
00000020 02 49 09 b9 42 ee ae fa e4 52 18 20 12 3a 53 7d |.I..B....R. .:S}| | |||
00000030 11 cf 13 13 a3 f8 42 c3 98 bb bc a6 10 3e f4 13 |......B......>..| | |||
00000040 a5 a2 fd ef aa b3 01 3c cb 8a 3a 2c cc a8 00 00 |.......<..:,....| | |||
00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| | |||
00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..| | |||
00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............| | |||
00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....| | |||
00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...| | |||
000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go| | |||
000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010| | |||
000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100| | |||
000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..| | |||
000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G| | |||
000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....| | |||
00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F| | |||
00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...| | |||
00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.| | |||
00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...| | |||
00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+| | |||
00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<| | |||
00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]| | |||
00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.| | |||
00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...| | |||
00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..| | |||
000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%| | |||
000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........| | |||
000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...| | |||
000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....| | |||
000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....| | |||
000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.| | |||
00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.| | |||
00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp| | |||
00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H| | |||
00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@| | |||
00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X| | |||
00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-| | |||
00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....| | |||
00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...| | |||
00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C| | |||
00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.| | |||
000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..| | |||
000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......| | |||
000002c0 ac 0c 00 00 a8 03 00 1d 20 57 53 06 53 e5 14 06 |........ WS.S...| | |||
000002d0 df 26 9d 3a 06 dc a9 d5 49 d3 3f 5f 7b c2 ab 77 |.&.:....I.?_{..w| | |||
000002e0 fd a1 fe 28 dc 54 36 06 22 04 01 00 80 da 23 f5 |...(.T6.".....#.| | |||
000002f0 19 de e8 d2 a9 79 b8 37 3d c0 8c ae f6 7c d5 d9 |.....y.7=....|..| | |||
00000300 87 ab 6b 3f 76 7c 5f 94 be 11 55 a3 78 66 1e e3 |..k?v|_...U.xf..| | |||
00000310 f3 11 3d 1a f7 02 26 a4 a6 cd 7c fe 87 0d 68 a1 |..=...&...|...h.| | |||
00000320 50 e8 7e 94 41 bd 5b 74 d0 6d 3b 6c ef ee 88 2d |P.~.A.[t.m;l...-| | |||
00000330 60 0a a9 53 cf 1f f4 03 a3 54 e5 91 36 50 62 54 |`..S.....T..6PbT| | |||
00000340 5f e6 e5 36 63 58 ba 7b bb 3a 79 59 58 08 a8 f2 |_..6cX.{.:yYX...| | |||
00000350 f5 1e 35 f8 f5 0f 7f 19 e7 7f 5f 56 e2 50 6d 8c |..5......._V.Pm.| | |||
00000360 da 45 70 60 0d 58 32 94 e7 a0 f7 da 93 16 03 03 |.Ep`.X2.........| | |||
00000370 00 04 0e 00 00 00 |......| | |||
>>> Flow 3 (client to server) | |||
00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| | |||
00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| | |||
00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| | |||
00000030 16 03 03 00 20 9d 2f a6 b7 21 56 ad 38 a8 31 20 |.... ./..!V.8.1 | | |||
00000040 0b 2e dc 3f 8a 34 64 de 81 0e d3 a5 b1 c1 fc 05 |...?.4d.........| | |||
00000050 18 d9 3e 77 35 |..>w5| | |||
>>> Flow 4 (server to client) | |||
00000000 14 03 03 00 01 01 16 03 03 00 20 a8 82 60 8a ef |.......... ..`..| | |||
00000010 31 55 42 e9 1d 33 0e d8 a9 b1 43 85 1c 04 7b 20 |1UB..3....C...{ | | |||
00000020 81 df 03 e9 fd c0 f7 32 b9 b3 31 |.......2..1| | |||
>>> Flow 5 (client to server) | |||
00000000 17 03 03 00 16 ef 72 f7 1b 26 1a 47 99 f9 4c e7 |......r..&.G..L.| | |||
00000010 be 8e ab c5 8e ea 8c c6 60 6c 10 15 03 03 00 12 |........`l......| | |||
00000020 2c f4 39 e3 3a 74 a4 3c 72 63 77 e8 82 cf a9 e2 |,.9.:t.<rcw.....| | |||
00000030 2b 04 |+.| |