Commit 67d8226b authored by Adam Langley's avatar Adam Langley

crypto/tls: support ChaCha20-Poly1305.

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent e7edc7e2
...@@ -14,6 +14,8 @@ import ( ...@@ -14,6 +14,8 @@ import (
"crypto/sha256" "crypto/sha256"
"crypto/x509" "crypto/x509"
"hash" "hash"
"golang_org/x/crypto/chacha20poly1305"
) )
// a keyAgreement implements the client and server side of a TLS key agreement // a keyAgreement implements the client and server side of a TLS key agreement
...@@ -75,7 +77,9 @@ type cipherSuite struct { ...@@ -75,7 +77,9 @@ type cipherSuite struct {
var cipherSuites = []*cipherSuite{ var cipherSuites = []*cipherSuite{
// Ciphersuite order is chosen so that ECDHE comes before plain RSA and // 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_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_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}, {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 { ...@@ -145,6 +149,15 @@ type macFunction interface {
MAC(digestBuf, seq, header, data, extra []byte) []byte 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 // fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
// each call. // each call.
type fixedNonceAEAD struct { type fixedNonceAEAD struct {
...@@ -157,6 +170,7 @@ type fixedNonceAEAD struct { ...@@ -157,6 +170,7 @@ type fixedNonceAEAD struct {
func (f *fixedNonceAEAD) NonceSize() int { return 8 } func (f *fixedNonceAEAD) NonceSize() int { return 8 }
func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } 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 { func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
copy(f.sealNonce[len(f.sealNonce)-8:], nonce) copy(f.sealNonce[len(f.sealNonce)-8:], nonce)
...@@ -168,6 +182,41 @@ func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]b ...@@ -168,6 +182,41 @@ func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]b
return f.aead.Open(out, f.openNonce, plaintext, additionalData) 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 { func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD {
aes, err := aes.NewCipher(key) aes, err := aes.NewCipher(key)
if err != nil { if err != nil {
...@@ -185,6 +234,17 @@ func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { ...@@ -185,6 +234,17 @@ func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD {
return &fixedNonceAEAD{nonce1, nonce2, 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 // ssl30MAC implements the SSLv3 MAC function, as defined in
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
type ssl30MAC struct { type ssl30MAC struct {
...@@ -330,6 +390,8 @@ const ( ...@@ -330,6 +390,8 @@ const (
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c 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 // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
// that the client is doing version fallback. See // that the client is doing version fallback. See
......
...@@ -285,13 +285,17 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) ...@@ -285,13 +285,17 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert)
switch c := hc.cipher.(type) { switch c := hc.cipher.(type) {
case cipher.Stream: case cipher.Stream:
c.XORKeyStream(payload, payload) c.XORKeyStream(payload, payload)
case cipher.AEAD: case aead:
explicitIVLen = 8 explicitIVLen = c.explicitNonceLen()
if len(payload) < explicitIVLen { if len(payload) < explicitIVLen {
return false, 0, alertBadRecordMAC return false, 0, alertBadRecordMAC
} }
nonce := payload[:8] nonce := payload[:explicitIVLen]
payload = payload[8:] payload = payload[explicitIVLen:]
if len(nonce) == 0 {
nonce = hc.seq[:]
}
copy(hc.additionalData[:], hc.seq[:]) copy(hc.additionalData[:], hc.seq[:])
copy(hc.additionalData[8:], b.data[:3]) copy(hc.additionalData[8:], b.data[:3])
...@@ -398,10 +402,13 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { ...@@ -398,10 +402,13 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
switch c := hc.cipher.(type) { switch c := hc.cipher.(type) {
case cipher.Stream: case cipher.Stream:
c.XORKeyStream(payload, payload) c.XORKeyStream(payload, payload)
case cipher.AEAD: case aead:
payloadLen := len(b.data) - recordHeaderLen - explicitIVLen payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
b.resize(len(b.data) + c.Overhead()) b.resize(len(b.data) + c.Overhead())
nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
if len(nonce) == 0 {
nonce = hc.seq[:]
}
payload := b.data[recordHeaderLen+explicitIVLen:] payload := b.data[recordHeaderLen+explicitIVLen:]
payload = payload[:payloadLen] payload = payload[:payloadLen]
...@@ -859,15 +866,16 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { ...@@ -859,15 +866,16 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
} }
} }
if explicitIVLen == 0 { if explicitIVLen == 0 {
if _, ok := c.out.cipher.(cipher.AEAD); ok { if c, ok := c.out.cipher.(aead); ok {
explicitIVLen = 8 explicitIVLen = c.explicitNonceLen()
// The AES-GCM construction in TLS has an // The AES-GCM construction in TLS has an
// explicit nonce so that the nonce can be // explicit nonce so that the nonce can be
// random. However, the nonce is only 8 bytes // random. However, the nonce is only 8 bytes
// which is too small for a secure, random // which is too small for a secure, random
// nonce. Therefore we use the sequence number // nonce. Therefore we use the sequence number
// as the nonce. // as the nonce.
explicitIVIsSeq = true explicitIVIsSeq = explicitIVLen > 0
} }
} }
m := len(data) m := len(data)
......
...@@ -550,6 +550,34 @@ func TestHandshakeClientX25519(t *testing.T) { ...@@ -550,6 +550,34 @@ func TestHandshakeClientX25519(t *testing.T) {
runClientTestTLS12(t, test) 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) { func TestHandshakeClientCertRSA(t *testing.T) {
config := testConfig.Clone() config := testConfig.Clone()
cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM)) cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
......
...@@ -40,6 +40,12 @@ var testConfig *Config ...@@ -40,6 +40,12 @@ var testConfig *Config
func allCipherSuites() []uint16 { func allCipherSuites() []uint16 {
ids := make([]uint16, len(cipherSuites)) ids := make([]uint16, len(cipherSuites))
for i, suite := range 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 ids[i] = suite.id
} }
......
>>> 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 |."|
>>> 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 |+.|
...@@ -333,7 +333,9 @@ var pkgDeps = map[string][]string{ ...@@ -333,7 +333,9 @@ var pkgDeps = map[string][]string{
"crypto/sha1", "crypto/sha1",
"crypto/sha256", "crypto/sha256",
"crypto/sha512", "crypto/sha512",
"golang_org/x/crypto/chacha20poly1305",
"golang_org/x/crypto/curve25519", "golang_org/x/crypto/curve25519",
"golang_org/x/crypto/poly1305",
}, },
// Random byte, number generation. // Random byte, number generation.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment