aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/crypto
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-07-22 18:15:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-07-22 18:15:38 +0000
commit22b955cca564a9a3a5b8c9d9dd1e295b7943c128 (patch)
treeabdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/crypto
parent9d04a3af4c6491536badf6bde9707c907e4d196b (diff)
downloadgcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.zip
gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.gz
gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.bz2
libgo: update to go1.7rc3
Reviewed-on: https://go-review.googlesource.com/25150 From-SVN: r238662
Diffstat (limited to 'libgo/go/crypto')
-rw-r--r--libgo/go/crypto/aes/aes_gcm.go5
-rw-r--r--libgo/go/crypto/aes/aes_test.go36
-rw-r--r--libgo/go/crypto/aes/block.go2
-rw-r--r--libgo/go/crypto/aes/cbc_s390x.go59
-rw-r--r--libgo/go/crypto/aes/cipher.go18
-rw-r--r--libgo/go/crypto/aes/cipher_amd64.go83
-rw-r--r--libgo/go/crypto/aes/cipher_asm.go48
-rw-r--r--libgo/go/crypto/aes/cipher_generic.go27
-rw-r--r--libgo/go/crypto/aes/cipher_s390x.go90
-rw-r--r--libgo/go/crypto/aes/ctr_s390x.go76
-rw-r--r--libgo/go/crypto/aes/modes.go37
-rw-r--r--libgo/go/crypto/aes/modes_test.go112
-rw-r--r--libgo/go/crypto/cipher/cbc.go22
-rw-r--r--libgo/go/crypto/cipher/cipher.go4
-rw-r--r--libgo/go/crypto/cipher/cipher_test.go2
-rw-r--r--libgo/go/crypto/cipher/ctr.go10
-rw-r--r--libgo/go/crypto/cipher/example_test.go7
-rw-r--r--libgo/go/crypto/cipher/xor.go2
-rw-r--r--libgo/go/crypto/cipher/xor_test.go2
-rw-r--r--libgo/go/crypto/des/block.go2
-rw-r--r--libgo/go/crypto/dsa/dsa.go14
-rw-r--r--libgo/go/crypto/ecdsa/ecdsa.go19
-rw-r--r--libgo/go/crypto/ecdsa/ecdsa_test.go25
-rw-r--r--libgo/go/crypto/elliptic/p224.go2
-rw-r--r--libgo/go/crypto/elliptic/p224_test.go2
-rw-r--r--libgo/go/crypto/elliptic/p256.go6
-rw-r--r--libgo/go/crypto/elliptic/p256_amd64.go10
-rw-r--r--libgo/go/crypto/hmac/hmac.go34
-rw-r--r--libgo/go/crypto/hmac/hmac_test.go26
-rw-r--r--libgo/go/crypto/md5/gen.go2
-rw-r--r--libgo/go/crypto/md5/md5.go2
-rw-r--r--libgo/go/crypto/md5/md5block_decl.go4
-rw-r--r--libgo/go/crypto/md5/md5block_generic.go2
-rw-r--r--libgo/go/crypto/rand/eagain.go2
-rw-r--r--libgo/go/crypto/rand/rand.go5
-rw-r--r--libgo/go/crypto/rand/rand_linux.go2
-rw-r--r--libgo/go/crypto/rand/rand_openbsd.go28
-rw-r--r--libgo/go/crypto/rand/rand_test.go2
-rw-r--r--libgo/go/crypto/rand/rand_unix.go4
-rw-r--r--libgo/go/crypto/rand/rand_windows.go2
-rw-r--r--libgo/go/crypto/rand/util.go4
-rw-r--r--libgo/go/crypto/rand/util_test.go2
-rw-r--r--libgo/go/crypto/rc4/rc4.go4
-rw-r--r--libgo/go/crypto/rsa/pkcs1v15.go73
-rw-r--r--libgo/go/crypto/rsa/pss.go8
-rw-r--r--libgo/go/crypto/rsa/rsa.go37
-rw-r--r--libgo/go/crypto/sha1/fallback_test.go34
-rw-r--r--libgo/go/crypto/sha1/issue15617_test.go28
-rw-r--r--libgo/go/crypto/sha1/sha1.go2
-rw-r--r--libgo/go/crypto/sha1/sha1_test.go25
-rw-r--r--libgo/go/crypto/sha1/sha1block_amd64.go34
-rw-r--r--libgo/go/crypto/sha1/sha1block_decl.go4
-rw-r--r--libgo/go/crypto/sha1/sha1block_generic.go2
-rw-r--r--libgo/go/crypto/sha1/sha1block_s390x.go12
-rw-r--r--libgo/go/crypto/sha256/fallback_test.go35
-rw-r--r--libgo/go/crypto/sha256/sha256.go2
-rw-r--r--libgo/go/crypto/sha256/sha256_test.go15
-rw-r--r--libgo/go/crypto/sha256/sha256block.go4
-rw-r--r--libgo/go/crypto/sha256/sha256block_decl.go4
-rw-r--r--libgo/go/crypto/sha256/sha256block_generic.go9
-rw-r--r--libgo/go/crypto/sha256/sha256block_s390x.go12
-rw-r--r--libgo/go/crypto/sha512/fallback_test.go37
-rw-r--r--libgo/go/crypto/sha512/sha512.go2
-rw-r--r--libgo/go/crypto/sha512/sha512_test.go15
-rw-r--r--libgo/go/crypto/sha512/sha512block.go4
-rw-r--r--libgo/go/crypto/sha512/sha512block_decl.go4
-rw-r--r--libgo/go/crypto/sha512/sha512block_generic.go9
-rw-r--r--libgo/go/crypto/sha512/sha512block_s390x.go12
-rw-r--r--libgo/go/crypto/subtle/constant_time.go2
-rw-r--r--libgo/go/crypto/tls/alert.go4
-rw-r--r--libgo/go/crypto/tls/cipher_suites.go10
-rw-r--r--libgo/go/crypto/tls/common.go76
-rw-r--r--libgo/go/crypto/tls/conn.go352
-rw-r--r--libgo/go/crypto/tls/conn_test.go125
-rw-r--r--libgo/go/crypto/tls/handshake_client.go243
-rw-r--r--libgo/go/crypto/tls/handshake_client_test.go433
-rw-r--r--libgo/go/crypto/tls/handshake_messages.go136
-rw-r--r--libgo/go/crypto/tls/handshake_server.go122
-rw-r--r--libgo/go/crypto/tls/handshake_server_test.go192
-rw-r--r--libgo/go/crypto/tls/key_agreement.go22
-rw-r--r--libgo/go/crypto/tls/prf.go2
-rw-r--r--libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce251
-rw-r--r--libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice409
-rw-r--r--libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected255
-rw-r--r--libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected97
-rw-r--r--libgo/go/crypto/tls/ticket.go6
-rw-r--r--libgo/go/crypto/tls/tls.go59
-rw-r--r--libgo/go/crypto/tls/tls_test.go257
-rw-r--r--libgo/go/crypto/x509/cert_pool.go24
-rw-r--r--libgo/go/crypto/x509/pem_decrypt.go2
-rw-r--r--libgo/go/crypto/x509/pkcs1.go11
-rw-r--r--libgo/go/crypto/x509/pkcs8.go6
-rw-r--r--libgo/go/crypto/x509/pkix/pkix.go2
-rw-r--r--libgo/go/crypto/x509/root.go9
-rw-r--r--libgo/go/crypto/x509/root_cgo_darwin.go88
-rw-r--r--libgo/go/crypto/x509/root_darwin_arm_gen.go7
-rw-r--r--libgo/go/crypto/x509/root_darwin_armx.go7
-rw-r--r--libgo/go/crypto/x509/root_nocgo_darwin.go4
-rw-r--r--libgo/go/crypto/x509/root_plan9.go18
-rw-r--r--libgo/go/crypto/x509/root_unix.go23
-rw-r--r--libgo/go/crypto/x509/root_windows.go5
-rw-r--r--libgo/go/crypto/x509/sec1.go6
-rw-r--r--libgo/go/crypto/x509/verify.go16
-rw-r--r--libgo/go/crypto/x509/verify_test.go46
-rw-r--r--libgo/go/crypto/x509/x509.go49
-rw-r--r--libgo/go/crypto/x509/x509_test.go107
106 files changed, 3866 insertions, 887 deletions
diff --git a/libgo/go/crypto/aes/aes_gcm.go b/libgo/go/crypto/aes/aes_gcm.go
index 1377578..a894a68 100644
--- a/libgo/go/crypto/aes/aes_gcm.go
+++ b/libgo/go/crypto/aes/aes_gcm.go
@@ -45,9 +45,12 @@ var errOpen = errors.New("cipher: message authentication failed")
// will use the optimised implementation in this file when possible. Instances
// of this type only exist when hasGCMAsm returns true.
type aesCipherGCM struct {
- aesCipher
+ aesCipherAsm
}
+// Assert that aesCipherGCM implements the gcmAble interface.
+var _ gcmAble = (*aesCipherGCM)(nil)
+
// NewGCM returns the AES cipher wrapped in Galois Counter Mode. This is only
// called by crypto/cipher.NewGCM via the gcmAble interface.
func (c *aesCipherGCM) NewGCM(nonceSize int) (cipher.AEAD, error) {
diff --git a/libgo/go/crypto/aes/aes_test.go b/libgo/go/crypto/aes/aes_test.go
index 3631809..2814496 100644
--- a/libgo/go/crypto/aes/aes_test.go
+++ b/libgo/go/crypto/aes/aes_test.go
@@ -280,42 +280,6 @@ var encryptTests = []CryptTest{
},
}
-// Test encryptBlock against FIPS 197 examples.
-func TestEncryptBlock(t *testing.T) {
- for i, tt := range encryptTests {
- n := len(tt.key) + 28
- enc := make([]uint32, n)
- dec := make([]uint32, n)
- expandKey(tt.key, enc, dec)
- out := make([]byte, len(tt.in))
- encryptBlock(enc, out, tt.in)
- for j, v := range out {
- if v != tt.out[j] {
- t.Errorf("encryptBlock %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
- break
- }
- }
- }
-}
-
-// Test decryptBlock against FIPS 197 examples.
-func TestDecryptBlock(t *testing.T) {
- for i, tt := range encryptTests {
- n := len(tt.key) + 28
- enc := make([]uint32, n)
- dec := make([]uint32, n)
- expandKey(tt.key, enc, dec)
- plain := make([]byte, len(tt.in))
- decryptBlock(dec, plain, tt.out)
- for j, v := range plain {
- if v != tt.in[j] {
- t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
- break
- }
- }
- }
-}
-
// Test Cipher Encrypt method against FIPS 197 examples.
func TestCipherEncrypt(t *testing.T) {
for i, tt := range encryptTests {
diff --git a/libgo/go/crypto/aes/block.go b/libgo/go/crypto/aes/block.go
index 57a7e9e..41ea9cf 100644
--- a/libgo/go/crypto/aes/block.go
+++ b/libgo/go/crypto/aes/block.go
@@ -137,7 +137,7 @@ func subw(w uint32) uint32 {
// Rotate
func rotw(w uint32) uint32 { return w<<8 | w>>24 }
-// Key expansion algorithm. See FIPS-197, Figure 11.
+// Key expansion algorithm. See FIPS-197, Figure 11.
// Their rcon[i] is our powx[i-1] << 24.
func expandKeyGo(key []byte, enc, dec []uint32) {
// Encryption key setup.
diff --git a/libgo/go/crypto/aes/cbc_s390x.go b/libgo/go/crypto/aes/cbc_s390x.go
new file mode 100644
index 0000000..427b30b
--- /dev/null
+++ b/libgo/go/crypto/aes/cbc_s390x.go
@@ -0,0 +1,59 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aes
+
+import (
+ "crypto/cipher"
+)
+
+// Assert that aesCipherAsm implements the cbcEncAble and cbcDecAble interfaces.
+var _ cbcEncAble = (*aesCipherAsm)(nil)
+var _ cbcDecAble = (*aesCipherAsm)(nil)
+
+type cbc struct {
+ b *aesCipherAsm
+ c code
+ iv [BlockSize]byte
+}
+
+func (b *aesCipherAsm) NewCBCEncrypter(iv []byte) cipher.BlockMode {
+ var c cbc
+ c.b = b
+ c.c = b.function
+ copy(c.iv[:], iv)
+ return &c
+}
+
+func (b *aesCipherAsm) NewCBCDecrypter(iv []byte) cipher.BlockMode {
+ var c cbc
+ c.b = b
+ c.c = b.function + 128 // decrypt function code is encrypt + 128
+ copy(c.iv[:], iv)
+ return &c
+}
+
+func (x *cbc) BlockSize() int { return BlockSize }
+
+// cryptBlocksChain invokes the cipher message with chaining (KMC) instruction
+// with the given function code. The length must be a multiple of BlockSize (16).
+//go:noescape
+func cryptBlocksChain(c code, iv, key, dst, src *byte, length int)
+
+func (x *cbc) CryptBlocks(dst, src []byte) {
+ if len(src)%BlockSize != 0 {
+ panic("crypto/cipher: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
+ cryptBlocksChain(x.c, &x.iv[0], &x.b.key[0], &dst[0], &src[0], len(src))
+}
+
+func (x *cbc) SetIV(iv []byte) {
+ if len(iv) != BlockSize {
+ panic("cipher: incorrect length IV")
+ }
+ copy(x.iv[:], iv)
+}
diff --git a/libgo/go/crypto/aes/cipher.go b/libgo/go/crypto/aes/cipher.go
index 04d2be1..c5a8e91 100644
--- a/libgo/go/crypto/aes/cipher.go
+++ b/libgo/go/crypto/aes/cipher.go
@@ -36,15 +36,15 @@ func NewCipher(key []byte) (cipher.Block, error) {
case 16, 24, 32:
break
}
+ return newCipher(key)
+}
- n := k + 28
+// newCipherGeneric creates and returns a new cipher.Block
+// implemented in pure Go.
+func newCipherGeneric(key []byte) (cipher.Block, error) {
+ n := len(key) + 28
c := aesCipher{make([]uint32, n), make([]uint32, n)}
- expandKey(key, c.enc, c.dec)
-
- if hasGCMAsm() {
- return &aesCipherGCM{c}, nil
- }
-
+ expandKeyGo(key, c.enc, c.dec)
return &c, nil
}
@@ -57,7 +57,7 @@ func (c *aesCipher) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
- encryptBlock(c.enc, dst, src)
+ encryptBlockGo(c.enc, dst, src)
}
func (c *aesCipher) Decrypt(dst, src []byte) {
@@ -67,5 +67,5 @@ func (c *aesCipher) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
- decryptBlock(c.dec, dst, src)
+ decryptBlockGo(c.dec, dst, src)
}
diff --git a/libgo/go/crypto/aes/cipher_amd64.go b/libgo/go/crypto/aes/cipher_amd64.go
new file mode 100644
index 0000000..b33c8ff
--- /dev/null
+++ b/libgo/go/crypto/aes/cipher_amd64.go
@@ -0,0 +1,83 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aes
+
+import (
+ "crypto/cipher"
+)
+
+// defined in asm_amd64.s
+func hasAsm() bool
+func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
+
+type aesCipherAsm struct {
+ aesCipher
+}
+
+var useAsm = hasAsm()
+
+func newCipher(key []byte) (cipher.Block, error) {
+ if !useAsm {
+ return newCipherGeneric(key)
+ }
+ n := len(key) + 28
+ c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
+ rounds := 10
+ switch len(key) {
+ case 128 / 8:
+ rounds = 10
+ case 192 / 8:
+ rounds = 12
+ case 256 / 8:
+ rounds = 14
+ }
+ expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
+ if hasGCMAsm() {
+ return &aesCipherGCM{c}, nil
+ }
+
+ return &c, nil
+}
+
+func (c *aesCipherAsm) BlockSize() int { return BlockSize }
+
+func (c *aesCipherAsm) Encrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/aes: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/aes: output not full block")
+ }
+ encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
+}
+
+func (c *aesCipherAsm) Decrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/aes: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/aes: output not full block")
+ }
+ decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0])
+}
+
+// expandKey is used by BenchmarkExpand to ensure that the asm implementation
+// of key expansion is used for the benchmark when it is available.
+func expandKey(key []byte, enc, dec []uint32) {
+ if useAsm {
+ rounds := 10 // rounds needed for AES128
+ switch len(key) {
+ case 192 / 8:
+ rounds = 12
+ case 256 / 8:
+ rounds = 14
+ }
+ expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
+ } else {
+ expandKeyGo(key, enc, dec)
+ }
+}
diff --git a/libgo/go/crypto/aes/cipher_asm.go b/libgo/go/crypto/aes/cipher_asm.go
deleted file mode 100644
index 964eaaa..0000000
--- a/libgo/go/crypto/aes/cipher_asm.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build amd64
-
-package aes
-
-// defined in asm_$GOARCH.s
-func hasAsm() bool
-func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
-func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
-func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
-
-var useAsm = hasAsm()
-
-func encryptBlock(xk []uint32, dst, src []byte) {
- if useAsm {
- encryptBlockAsm(len(xk)/4-1, &xk[0], &dst[0], &src[0])
- } else {
- encryptBlockGo(xk, dst, src)
- }
-}
-
-func decryptBlock(xk []uint32, dst, src []byte) {
- if useAsm {
- decryptBlockAsm(len(xk)/4-1, &xk[0], &dst[0], &src[0])
- } else {
- decryptBlockGo(xk, dst, src)
- }
-}
-
-func expandKey(key []byte, enc, dec []uint32) {
- if useAsm {
- rounds := 10
- switch len(key) {
- case 128 / 8:
- rounds = 10
- case 192 / 8:
- rounds = 12
- case 256 / 8:
- rounds = 14
- }
- expandKeyAsm(rounds, &key[0], &enc[0], &dec[0])
- } else {
- expandKeyGo(key, enc, dec)
- }
-}
diff --git a/libgo/go/crypto/aes/cipher_generic.go b/libgo/go/crypto/aes/cipher_generic.go
index 32b2b3c..f807034 100644
--- a/libgo/go/crypto/aes/cipher_generic.go
+++ b/libgo/go/crypto/aes/cipher_generic.go
@@ -2,26 +2,25 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64
+// +build !amd64,!s390x
package aes
-func encryptBlock(xk []uint32, dst, src []byte) {
- encryptBlockGo(xk, dst, src)
-}
+import (
+ "crypto/cipher"
+)
-func decryptBlock(xk []uint32, dst, src []byte) {
- decryptBlockGo(xk, dst, src)
+// newCipher calls the newCipherGeneric function
+// directly. Platforms with hardware accelerated
+// implementations of AES should implement their
+// own version of newCipher (which may then call
+// newCipherGeneric if needed).
+func newCipher(key []byte) (cipher.Block, error) {
+ return newCipherGeneric(key)
}
+// expandKey is used by BenchmarkExpand and should
+// call an assembly implementation if one is available.
func expandKey(key []byte, enc, dec []uint32) {
expandKeyGo(key, enc, dec)
}
-
-func hasGCMAsm() bool {
- return false
-}
-
-type aesCipherGCM struct {
- aesCipher
-}
diff --git a/libgo/go/crypto/aes/cipher_s390x.go b/libgo/go/crypto/aes/cipher_s390x.go
new file mode 100644
index 0000000..bec5933
--- /dev/null
+++ b/libgo/go/crypto/aes/cipher_s390x.go
@@ -0,0 +1,90 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aes
+
+import (
+ "crypto/cipher"
+)
+
+type code int
+
+// Function codes for the cipher message family of instructions.
+const (
+ aes128 code = 18
+ aes192 = 19
+ aes256 = 20
+)
+
+type aesCipherAsm struct {
+ function code // code for cipher message instruction
+ key []byte // key (128, 192 or 256 bytes)
+ storage [256]byte // array backing key slice
+}
+
+// hasAsm reports whether the AES-128, AES-192 and AES-256
+// cipher message (KM) function codes are supported.
+// Note: this function call is expensive.
+func hasAsm() bool
+
+// cryptBlocks invokes the cipher message (KM) instruction with
+// the given function code. This is equivalent to AES in ECB
+// mode. The length must be a multiple of BlockSize (16).
+//go:noesape
+func cryptBlocks(c code, key, dst, src *byte, length int)
+
+var useAsm = hasAsm()
+
+func newCipher(key []byte) (cipher.Block, error) {
+ if !useAsm {
+ return newCipherGeneric(key)
+ }
+
+ var function code
+ switch len(key) {
+ case 128 / 8:
+ function = aes128
+ case 192 / 8:
+ function = aes192
+ case 256 / 8:
+ function = aes256
+ default:
+ return nil, KeySizeError(len(key))
+ }
+
+ var c aesCipherAsm
+ c.function = function
+ c.key = c.storage[:len(key)]
+ copy(c.key, key)
+ return &c, nil
+}
+
+func (c *aesCipherAsm) BlockSize() int { return BlockSize }
+
+func (c *aesCipherAsm) Encrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/aes: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/aes: output not full block")
+ }
+ cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
+}
+
+func (c *aesCipherAsm) Decrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/aes: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/aes: output not full block")
+ }
+ // The decrypt function code is equal to the function code + 128.
+ cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
+}
+
+// expandKey is used by BenchmarkExpand. cipher message (KM) does not need key
+// expansion so there is no assembly equivalent.
+func expandKey(key []byte, enc, dec []uint32) {
+ expandKeyGo(key, enc, dec)
+}
diff --git a/libgo/go/crypto/aes/ctr_s390x.go b/libgo/go/crypto/aes/ctr_s390x.go
new file mode 100644
index 0000000..94dea5c
--- /dev/null
+++ b/libgo/go/crypto/aes/ctr_s390x.go
@@ -0,0 +1,76 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aes
+
+import (
+ "crypto/cipher"
+ "unsafe"
+)
+
+// Assert that aesCipherAsm implements the ctrAble interface.
+var _ ctrAble = (*aesCipherAsm)(nil)
+
+// xorBytes xors the contents of a and b and places the resulting values into
+// dst. If a and b are not the same length then the number of bytes processed
+// will be equal to the length of shorter of the two. Returns the number
+// of bytes processed.
+//go:noescape
+func xorBytes(dst, a, b []byte) int
+
+// streamBufferSize is the number of bytes of encrypted counter values to cache.
+const streamBufferSize = 32 * BlockSize
+
+type aesctr struct {
+ block *aesCipherAsm // block cipher
+ ctr [2]uint64 // next value of the counter (big endian)
+ buffer []byte // buffer for the encrypted counter values
+ storage [streamBufferSize]byte // array backing buffer slice
+}
+
+// NewCTR returns a Stream which encrypts/decrypts using the AES block
+// cipher in counter mode. The length of iv must be the same as BlockSize.
+func (c *aesCipherAsm) NewCTR(iv []byte) cipher.Stream {
+ if len(iv) != BlockSize {
+ panic("cipher.NewCTR: IV length must equal block size")
+ }
+ var ac aesctr
+ ac.block = c
+ ac.ctr[0] = *(*uint64)(unsafe.Pointer((&iv[0]))) // high bits
+ ac.ctr[1] = *(*uint64)(unsafe.Pointer((&iv[8]))) // low bits
+ ac.buffer = ac.storage[:0]
+ return &ac
+}
+
+func (c *aesctr) refill() {
+ // Fill up the buffer with an incrementing count.
+ c.buffer = c.storage[:streamBufferSize]
+ c0, c1 := c.ctr[0], c.ctr[1]
+ for i := 0; i < streamBufferSize; i += BlockSize {
+ b0 := (*uint64)(unsafe.Pointer(&c.buffer[i]))
+ b1 := (*uint64)(unsafe.Pointer(&c.buffer[i+BlockSize/2]))
+ *b0, *b1 = c0, c1
+ // Increment in big endian: c0 is high, c1 is low.
+ c1++
+ if c1 == 0 {
+ // add carry
+ c0++
+ }
+ }
+ c.ctr[0], c.ctr[1] = c0, c1
+ // Encrypt the buffer using AES in ECB mode.
+ cryptBlocks(c.block.function, &c.block.key[0], &c.buffer[0], &c.buffer[0], streamBufferSize)
+}
+
+func (c *aesctr) XORKeyStream(dst, src []byte) {
+ for len(src) > 0 {
+ if len(c.buffer) == 0 {
+ c.refill()
+ }
+ n := xorBytes(dst, src, c.buffer)
+ c.buffer = c.buffer[n:]
+ src = src[n:]
+ dst = dst[n:]
+ }
+}
diff --git a/libgo/go/crypto/aes/modes.go b/libgo/go/crypto/aes/modes.go
new file mode 100644
index 0000000..1623fc1
--- /dev/null
+++ b/libgo/go/crypto/aes/modes.go
@@ -0,0 +1,37 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aes
+
+import (
+ "crypto/cipher"
+)
+
+// gcmAble is implemented by cipher.Blocks that can provide an optimized
+// implementation of GCM through the AEAD interface.
+// See crypto/cipher/gcm.go.
+type gcmAble interface {
+ NewGCM(size int) (cipher.AEAD, error)
+}
+
+// cbcEncAble is implemented by cipher.Blocks that can provide an optimized
+// implementation of CBC encryption through the cipher.BlockMode interface.
+// See crypto/cipher/cbc.go.
+type cbcEncAble interface {
+ NewCBCEncrypter(iv []byte) cipher.BlockMode
+}
+
+// cbcDecAble is implemented by cipher.Blocks that can provide an optimized
+// implementation of CBC decryption through the cipher.BlockMode interface.
+// See crypto/cipher/cbc.go.
+type cbcDecAble interface {
+ NewCBCDecrypter(iv []byte) cipher.BlockMode
+}
+
+// ctrAble is implemented by cipher.Blocks that can provide an optimized
+// implementation of CTR through the cipher.Stream interface.
+// See crypto/cipher/ctr.go.
+type ctrAble interface {
+ NewCTR(iv []byte) cipher.Stream
+}
diff --git a/libgo/go/crypto/aes/modes_test.go b/libgo/go/crypto/aes/modes_test.go
new file mode 100644
index 0000000..8c2e5f0
--- /dev/null
+++ b/libgo/go/crypto/aes/modes_test.go
@@ -0,0 +1,112 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package aes
+
+import (
+ "crypto/cipher"
+ "testing"
+)
+
+// Check that the optimized implementations of cipher modes will
+// be picked up correctly.
+
+// testInterface can be asserted to check that a type originates
+// from this test group.
+type testInterface interface {
+ InAESPackage() bool
+}
+
+// testBlock implements the cipher.Block interface and any *Able
+// interfaces that need to be tested.
+type testBlock struct{}
+
+func (*testBlock) BlockSize() int { return 0 }
+func (*testBlock) Encrypt(a, b []byte) {}
+func (*testBlock) Decrypt(a, b []byte) {}
+func (*testBlock) NewGCM(int) (cipher.AEAD, error) {
+ return &testAEAD{}, nil
+}
+func (*testBlock) NewCBCEncrypter([]byte) cipher.BlockMode {
+ return &testBlockMode{}
+}
+func (*testBlock) NewCBCDecrypter([]byte) cipher.BlockMode {
+ return &testBlockMode{}
+}
+func (*testBlock) NewCTR([]byte) cipher.Stream {
+ return &testStream{}
+}
+
+// testAEAD implements the cipher.AEAD interface.
+type testAEAD struct{}
+
+func (*testAEAD) NonceSize() int { return 0 }
+func (*testAEAD) Overhead() int { return 0 }
+func (*testAEAD) Seal(a, b, c, d []byte) []byte { return []byte{} }
+func (*testAEAD) Open(a, b, c, d []byte) ([]byte, error) { return []byte{}, nil }
+func (*testAEAD) InAESPackage() bool { return true }
+
+// Test the gcmAble interface is detected correctly by the cipher package.
+func TestGCMAble(t *testing.T) {
+ b := cipher.Block(&testBlock{})
+ if _, ok := b.(gcmAble); !ok {
+ t.Fatalf("testBlock does not implement the gcmAble interface")
+ }
+ aead, err := cipher.NewGCM(b)
+ if err != nil {
+ t.Fatalf("%v", err)
+ }
+ if _, ok := aead.(testInterface); !ok {
+ t.Fatalf("cipher.NewGCM did not use gcmAble interface")
+ }
+}
+
+// testBlockMode implements the cipher.BlockMode interface.
+type testBlockMode struct{}
+
+func (*testBlockMode) BlockSize() int { return 0 }
+func (*testBlockMode) CryptBlocks(a, b []byte) {}
+func (*testBlockMode) InAESPackage() bool { return true }
+
+// Test the cbcEncAble interface is detected correctly by the cipher package.
+func TestCBCEncAble(t *testing.T) {
+ b := cipher.Block(&testBlock{})
+ if _, ok := b.(cbcEncAble); !ok {
+ t.Fatalf("testBlock does not implement the cbcEncAble interface")
+ }
+ bm := cipher.NewCBCEncrypter(b, []byte{})
+ if _, ok := bm.(testInterface); !ok {
+ t.Fatalf("cipher.NewCBCEncrypter did not use cbcEncAble interface")
+ }
+}
+
+// Test the cbcDecAble interface is detected correctly by the cipher package.
+func TestCBCDecAble(t *testing.T) {
+ b := cipher.Block(&testBlock{})
+ if _, ok := b.(cbcDecAble); !ok {
+ t.Fatalf("testBlock does not implement the cbcDecAble interface")
+ }
+ bm := cipher.NewCBCDecrypter(b, []byte{})
+ if _, ok := bm.(testInterface); !ok {
+ t.Fatalf("cipher.NewCBCDecrypter did not use cbcDecAble interface")
+ }
+}
+
+// testStream implements the cipher.Stream interface.
+type testStream struct{}
+
+func (*testStream) XORKeyStream(a, b []byte) {}
+func (*testStream) InAESPackage() bool { return true }
+
+// Test the ctrAble interface is detected correctly by the cipher package.
+func TestCTRAble(t *testing.T) {
+ b := cipher.Block(&testBlock{})
+ if _, ok := b.(ctrAble); !ok {
+ t.Fatalf("testBlock does not implement the ctrAble interface")
+ }
+ s := cipher.NewCTR(b, []byte{})
+ if _, ok := s.(testInterface); !ok {
+ t.Fatalf("cipher.NewCTR did not use ctrAble interface")
+ }
+}
diff --git a/libgo/go/crypto/cipher/cbc.go b/libgo/go/crypto/cipher/cbc.go
index 241e122..0367d59 100644
--- a/libgo/go/crypto/cipher/cbc.go
+++ b/libgo/go/crypto/cipher/cbc.go
@@ -29,6 +29,14 @@ func newCBC(b Block, iv []byte) *cbc {
type cbcEncrypter cbc
+// cbcEncAble is an interface implemented by ciphers that have a specific
+// optimized implementation of CBC encryption, like crypto/aes.
+// NewCBCEncrypter will check for this interface and return the specific
+// BlockMode if found.
+type cbcEncAble interface {
+ NewCBCEncrypter(iv []byte) BlockMode
+}
+
// NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining
// mode, using the given Block. The length of iv must be the same as the
// Block's block size.
@@ -36,6 +44,9 @@ func NewCBCEncrypter(b Block, iv []byte) BlockMode {
if len(iv) != b.BlockSize() {
panic("cipher.NewCBCEncrypter: IV length must equal block size")
}
+ if cbc, ok := b.(cbcEncAble); ok {
+ return cbc.NewCBCEncrypter(iv)
+ }
return (*cbcEncrypter)(newCBC(b, iv))
}
@@ -75,6 +86,14 @@ func (x *cbcEncrypter) SetIV(iv []byte) {
type cbcDecrypter cbc
+// cbcDecAble is an interface implemented by ciphers that have a specific
+// optimized implementation of CBC decryption, like crypto/aes.
+// NewCBCDecrypter will check for this interface and return the specific
+// BlockMode if found.
+type cbcDecAble interface {
+ NewCBCDecrypter(iv []byte) BlockMode
+}
+
// NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining
// mode, using the given Block. The length of iv must be the same as the
// Block's block size and must match the iv used to encrypt the data.
@@ -82,6 +101,9 @@ func NewCBCDecrypter(b Block, iv []byte) BlockMode {
if len(iv) != b.BlockSize() {
panic("cipher.NewCBCDecrypter: IV length must equal block size")
}
+ if cbc, ok := b.(cbcDecAble); ok {
+ return cbc.NewCBCDecrypter(iv)
+ }
return (*cbcDecrypter)(newCBC(b, iv))
}
diff --git a/libgo/go/crypto/cipher/cipher.go b/libgo/go/crypto/cipher/cipher.go
index 7d27fde..531ecad 100644
--- a/libgo/go/crypto/cipher/cipher.go
+++ b/libgo/go/crypto/cipher/cipher.go
@@ -9,8 +9,8 @@
package cipher
// A Block represents an implementation of block cipher
-// using a given key. It provides the capability to encrypt
-// or decrypt individual blocks. The mode implementations
+// using a given key. It provides the capability to encrypt
+// or decrypt individual blocks. The mode implementations
// extend that capability to streams of blocks.
type Block interface {
// BlockSize returns the cipher's block size.
diff --git a/libgo/go/crypto/cipher/cipher_test.go b/libgo/go/crypto/cipher/cipher_test.go
index 8da5bce..1faa7b8 100644
--- a/libgo/go/crypto/cipher/cipher_test.go
+++ b/libgo/go/crypto/cipher/cipher_test.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/cipher/ctr.go b/libgo/go/crypto/cipher/ctr.go
index 16baa6d..75f46cf 100644
--- a/libgo/go/crypto/cipher/ctr.go
+++ b/libgo/go/crypto/cipher/ctr.go
@@ -21,9 +21,19 @@ type ctr struct {
const streamBufferSize = 512
+// ctrAble is an interface implemented by ciphers that have a specific optimized
+// implementation of CTR, like crypto/aes. NewCTR will check for this interface
+// and return the specific Stream if found.
+type ctrAble interface {
+ NewCTR(iv []byte) Stream
+}
+
// NewCTR returns a Stream which encrypts/decrypts using the given Block in
// counter mode. The length of iv must be the same as the Block's block size.
func NewCTR(block Block, iv []byte) Stream {
+ if ctr, ok := block.(ctrAble); ok {
+ return ctr.NewCTR(iv)
+ }
if len(iv) != block.BlockSize() {
panic("cipher.NewCTR: IV length must equal block size")
}
diff --git a/libgo/go/crypto/cipher/example_test.go b/libgo/go/crypto/cipher/example_test.go
index f6cc386..9abe782 100644
--- a/libgo/go/crypto/cipher/example_test.go
+++ b/libgo/go/crypto/cipher/example_test.go
@@ -44,9 +44,9 @@ func ExampleNewGCMDecrypter() {
// The key argument should be the AES key, either 16 or 32 bytes
// to select AES-128 or AES-256.
key := []byte("AES256Key-32Characters1234567890")
- ciphertext, _ := hex.DecodeString("f90fbef747e7212ad7410d0eee2d965de7e890471695cddd2a5bc0ef5da1d04ad8147b62141ad6e4914aee8c512f64fba9037603d41de0d50b718bd665f019cdcd")
+ ciphertext, _ := hex.DecodeString("1019aa66cd7c024f9efd0038899dae1973ee69427f5a6579eba292ffe1b5a260")
- nonce, _ := hex.DecodeString("bb8ef84243d2ee95a41c6c57")
+ nonce, _ := hex.DecodeString("37b8e8a308c354048d245f6d")
block, err := aes.NewCipher(key)
if err != nil {
@@ -63,7 +63,8 @@ func ExampleNewGCMDecrypter() {
panic(err.Error())
}
- fmt.Printf("%s\n", string(plaintext))
+ fmt.Printf("%s\n", plaintext)
+ // Output: exampleplaintext
}
func ExampleNewCBCDecrypter() {
diff --git a/libgo/go/crypto/cipher/xor.go b/libgo/go/crypto/cipher/xor.go
index f88dc89..01ca0a9 100644
--- a/libgo/go/crypto/cipher/xor.go
+++ b/libgo/go/crypto/cipher/xor.go
@@ -10,7 +10,7 @@ import (
)
const wordSize = int(unsafe.Sizeof(uintptr(0)))
-const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64"
+const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x"
// fastXORBytes xors in bulk. It only works on architectures that
// support unaligned read/writes.
diff --git a/libgo/go/crypto/cipher/xor_test.go b/libgo/go/crypto/cipher/xor_test.go
index cc1c9d7..d9187eb 100644
--- a/libgo/go/crypto/cipher/xor_test.go
+++ b/libgo/go/crypto/cipher/xor_test.go
@@ -19,7 +19,7 @@ func TestXOR(t *testing.T) {
d2 := make([]byte, 1024+alignD)[alignD:]
xorBytes(d1, p, q)
safeXORBytes(d2, p, q)
- if bytes.Compare(d1, d2) != 0 {
+ if !bytes.Equal(d1, d2) {
t.Error("not equal")
}
}
diff --git a/libgo/go/crypto/des/block.go b/libgo/go/crypto/des/block.go
index 26355a2..99338d6 100644
--- a/libgo/go/crypto/des/block.go
+++ b/libgo/go/crypto/des/block.go
@@ -72,7 +72,7 @@ func init() {
for i := 0; i < 4; i++ {
for j := 0; j < 16; j++ {
f := uint64(sBoxes[s][i][j]) << (4 * (7 - uint(s)))
- f = permuteBlock(uint64(f), permutationFunction[:])
+ f = permuteBlock(f, permutationFunction[:])
feistelBox[s][16*i+j] = uint32(f)
}
}
diff --git a/libgo/go/crypto/dsa/dsa.go b/libgo/go/crypto/dsa/dsa.go
index 9f414a4..e9b6a0c 100644
--- a/libgo/go/crypto/dsa/dsa.go
+++ b/libgo/go/crypto/dsa/dsa.go
@@ -52,7 +52,7 @@ const numMRTests = 64
// GenerateParameters puts a random, valid set of DSA parameters into params.
// This function can take many seconds, even on fast machines.
-func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err error) {
+func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) error {
// This function doesn't follow FIPS 186-3 exactly in that it doesn't
// use a verification seed to generate the primes. The verification
// seed doesn't appear to be exported or used by other code and
@@ -87,9 +87,8 @@ func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes
GeneratePrimes:
for {
- _, err = io.ReadFull(rand, qBytes)
- if err != nil {
- return
+ if _, err := io.ReadFull(rand, qBytes); err != nil {
+ return err
}
qBytes[len(qBytes)-1] |= 1
@@ -101,9 +100,8 @@ GeneratePrimes:
}
for i := 0; i < 4*L; i++ {
- _, err = io.ReadFull(rand, pBytes)
- if err != nil {
- return
+ if _, err := io.ReadFull(rand, pBytes); err != nil {
+ return err
}
pBytes[len(pBytes)-1] |= 1
@@ -142,7 +140,7 @@ GeneratePrimes:
}
params.G = g
- return
+ return nil
}
}
diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go
index e54488c..72fb499 100644
--- a/libgo/go/crypto/ecdsa/ecdsa.go
+++ b/libgo/go/crypto/ecdsa/ecdsa.go
@@ -97,17 +97,17 @@ func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error)
}
// GenerateKey generates a public and private key pair.
-func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) {
+func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
k, err := randFieldElement(c, rand)
if err != nil {
- return
+ return nil, err
}
- priv = new(PrivateKey)
+ priv := new(PrivateKey)
priv.PublicKey.Curve = c
priv.D = k
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
- return
+ return priv, nil
}
// hashToInt converts a hash value to an integer. There is some disagreement
@@ -143,10 +143,11 @@ func fermatInverse(k, N *big.Int) *big.Int {
var errZeroParam = errors.New("zero parameter")
-// Sign signs an arbitrary length hash (which should be the result of hashing a
-// larger message) using the private key, priv. It returns the signature as a
-// pair of integers. The security of the private key depends on the entropy of
-// rand.
+// Sign signs a hash (which should be the result of hashing a larger message)
+// using the private key, priv. If the hash is longer than the bit-length of the
+// private key's curve order, the hash will be truncated to that length. It
+// returns the signature as a pair of integers. The security of the private key
+// depends on the entropy of rand.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
// Get max(log2(q) / 2, 256) bits of entropy from rand.
entropylen := (priv.Curve.Params().BitSize + 7) / 16
@@ -228,7 +229,7 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
c := pub.Curve
N := c.Params().N
- if r.Sign() == 0 || s.Sign() == 0 {
+ if r.Sign() <= 0 || s.Sign() <= 0 {
return false
}
if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
diff --git a/libgo/go/crypto/ecdsa/ecdsa_test.go b/libgo/go/crypto/ecdsa/ecdsa_test.go
index 62a3fcc..fc25fd7 100644
--- a/libgo/go/crypto/ecdsa/ecdsa_test.go
+++ b/libgo/go/crypto/ecdsa/ecdsa_test.go
@@ -130,7 +130,7 @@ func testNonceSafety(t *testing.T, c elliptic.Curve, tag string) {
}
if r0.Cmp(r1) == 0 {
- t.Errorf("%s: the nonce used for two diferent messages was the same", tag)
+ t.Errorf("%s: the nonce used for two different messages was the same", tag)
}
}
@@ -296,3 +296,26 @@ func TestVectors(t *testing.T) {
}
}
}
+
+func testNegativeInputs(t *testing.T, curve elliptic.Curve, tag string) {
+ key, err := GenerateKey(curve, rand.Reader)
+ if err != nil {
+ t.Errorf("failed to generate key for %q", tag)
+ }
+
+ var hash [32]byte
+ r := new(big.Int).SetInt64(1)
+ r.Lsh(r, 550 /* larger than any supported curve */)
+ r.Neg(r)
+
+ if Verify(&key.PublicKey, hash[:], r, r) {
+ t.Errorf("bogus signature accepted for %q", tag)
+ }
+}
+
+func TestNegativeInputs(t *testing.T) {
+ testNegativeInputs(t, elliptic.P224(), "p224")
+ testNegativeInputs(t, elliptic.P256(), "p256")
+ testNegativeInputs(t, elliptic.P384(), "p384")
+ testNegativeInputs(t, elliptic.P521(), "p521")
+}
diff --git a/libgo/go/crypto/elliptic/p224.go b/libgo/go/crypto/elliptic/p224.go
index 2d3fac7..de266ca 100644
--- a/libgo/go/crypto/elliptic/p224.go
+++ b/libgo/go/crypto/elliptic/p224.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/elliptic/p224_test.go b/libgo/go/crypto/elliptic/p224_test.go
index 4b26d16..8b4fa04 100644
--- a/libgo/go/crypto/elliptic/p224_test.go
+++ b/libgo/go/crypto/elliptic/p224_test.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/elliptic/p256.go b/libgo/go/crypto/elliptic/p256.go
index 5103e86..05a3311 100644
--- a/libgo/go/crypto/elliptic/p256.go
+++ b/libgo/go/crypto/elliptic/p256.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -1056,7 +1056,7 @@ func p256ScalarBaseMult(xOut, yOut, zOut *[p256Limbs]uint32, scalar *[32]uint8)
p256CopyConditional(yOut, &ty, mask)
p256CopyConditional(zOut, &tz, mask)
// If p was not zero, then n is now non-zero.
- nIsInfinityMask &= ^pIsNoninfiniteMask
+ nIsInfinityMask &^= pIsNoninfiniteMask
}
}
}
@@ -1136,7 +1136,7 @@ func p256ScalarMult(xOut, yOut, zOut, x, y *[p256Limbs]uint32, scalar *[32]uint8
p256CopyConditional(xOut, &tx, mask)
p256CopyConditional(yOut, &ty, mask)
p256CopyConditional(zOut, &tz, mask)
- nIsInfinityMask &= ^pIsNoninfiniteMask
+ nIsInfinityMask &^= pIsNoninfiniteMask
}
}
diff --git a/libgo/go/crypto/elliptic/p256_amd64.go b/libgo/go/crypto/elliptic/p256_amd64.go
index 586cd10..66b7cf8 100644
--- a/libgo/go/crypto/elliptic/p256_amd64.go
+++ b/libgo/go/crypto/elliptic/p256_amd64.go
@@ -66,7 +66,7 @@ func p256NegCond(val []uint64, cond int)
// if cond == 0 res <- b; else res <- a
func p256MovCond(res, a, b []uint64, cond int)
-// Endianess swap
+// Endianness swap
func p256BigToLittle(res []uint64, in []byte)
func p256LittleToBig(res []byte, in []uint64)
@@ -93,10 +93,14 @@ func p256PointAddAsm(res, in1, in2 []uint64)
func p256PointDoubleAsm(res, in []uint64)
func (curve p256Curve) Inverse(k *big.Int) *big.Int {
+ if k.Sign() < 0 {
+ // This should never happen.
+ k = new(big.Int).Neg(k)
+ }
+
if k.Cmp(p256.N) >= 0 {
// This should never happen.
- reducedK := new(big.Int).Mod(k, p256.N)
- k = reducedK
+ k = new(big.Int).Mod(k, p256.N)
}
// table will store precomputed powers of x. The four words at index
diff --git a/libgo/go/crypto/hmac/hmac.go b/libgo/go/crypto/hmac/hmac.go
index 3b41cde..a748107 100644
--- a/libgo/go/crypto/hmac/hmac.go
+++ b/libgo/go/crypto/hmac/hmac.go
@@ -37,26 +37,16 @@ import (
type hmac struct {
size int
blocksize int
- key, tmp []byte
+ opad, ipad []byte
outer, inner hash.Hash
}
-func (h *hmac) tmpPad(xor byte) {
- for i, k := range h.key {
- h.tmp[i] = xor ^ k
- }
- for i := len(h.key); i < h.blocksize; i++ {
- h.tmp[i] = xor
- }
-}
-
func (h *hmac) Sum(in []byte) []byte {
origLen := len(in)
in = h.inner.Sum(in)
- h.tmpPad(0x5c)
- copy(h.tmp[h.blocksize:], in[origLen:])
h.outer.Reset()
- h.outer.Write(h.tmp)
+ h.outer.Write(h.opad)
+ h.outer.Write(in[origLen:])
return h.outer.Sum(in[:origLen])
}
@@ -70,8 +60,7 @@ func (h *hmac) BlockSize() int { return h.blocksize }
func (h *hmac) Reset() {
h.inner.Reset()
- h.tmpPad(0x36)
- h.inner.Write(h.tmp[:h.blocksize])
+ h.inner.Write(h.ipad)
}
// New returns a new HMAC hash using the given hash.Hash type and key.
@@ -81,15 +70,22 @@ func New(h func() hash.Hash, key []byte) hash.Hash {
hm.inner = h()
hm.size = hm.inner.Size()
hm.blocksize = hm.inner.BlockSize()
- hm.tmp = make([]byte, hm.blocksize+hm.size)
+ hm.ipad = make([]byte, hm.blocksize)
+ hm.opad = make([]byte, hm.blocksize)
if len(key) > hm.blocksize {
// If key is too big, hash it.
hm.outer.Write(key)
key = hm.outer.Sum(nil)
}
- hm.key = make([]byte, len(key))
- copy(hm.key, key)
- hm.Reset()
+ copy(hm.ipad, key)
+ copy(hm.opad, key)
+ for i := range hm.ipad {
+ hm.ipad[i] ^= 0x36
+ }
+ for i := range hm.opad {
+ hm.opad[i] ^= 0x5c
+ }
+ hm.inner.Write(hm.ipad)
return hm
}
diff --git a/libgo/go/crypto/hmac/hmac_test.go b/libgo/go/crypto/hmac/hmac_test.go
index e80b7e0..aac9aa9 100644
--- a/libgo/go/crypto/hmac/hmac_test.go
+++ b/libgo/go/crypto/hmac/hmac_test.go
@@ -568,3 +568,29 @@ func TestEqual(t *testing.T) {
t.Error("Equal accepted unequal slices")
}
}
+
+func BenchmarkHMACSHA256_1K(b *testing.B) {
+ key := make([]byte, 32)
+ buf := make([]byte, 1024)
+ h := New(sha256.New, key)
+ b.SetBytes(int64(len(buf)))
+ for i := 0; i < b.N; i++ {
+ h.Write(buf)
+ h.Reset()
+ mac := h.Sum(nil)
+ buf[0] = mac[0]
+ }
+}
+
+func BenchmarkHMACSHA256_32(b *testing.B) {
+ key := make([]byte, 32)
+ buf := make([]byte, 32)
+ h := New(sha256.New, key)
+ b.SetBytes(int64(len(buf)))
+ for i := 0; i < b.N; i++ {
+ h.Write(buf)
+ h.Reset()
+ mac := h.Sum(nil)
+ buf[0] = mac[0]
+ }
+}
diff --git a/libgo/go/crypto/md5/gen.go b/libgo/go/crypto/md5/gen.go
index 8cd0a63..178fad1 100644
--- a/libgo/go/crypto/md5/gen.go
+++ b/libgo/go/crypto/md5/gen.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/md5/md5.go b/libgo/go/crypto/md5/md5.go
index a3550cb..ce58d5e 100644
--- a/libgo/go/crypto/md5/md5.go
+++ b/libgo/go/crypto/md5/md5.go
@@ -89,7 +89,7 @@ func (d0 *digest) Sum(in []byte) []byte {
}
func (d *digest) checkSum() [Size]byte {
- // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
+ // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
tmp[0] = 0x80
diff --git a/libgo/go/crypto/md5/md5block_decl.go b/libgo/go/crypto/md5/md5block_decl.go
index d7956a6..1e6f6e6 100644
--- a/libgo/go/crypto/md5/md5block_decl.go
+++ b/libgo/go/crypto/md5/md5block_decl.go
@@ -1,8 +1,8 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64 amd64p32 386 arm
+// +build amd64 amd64p32 386 arm ppc64le s390x
package md5
diff --git a/libgo/go/crypto/md5/md5block_generic.go b/libgo/go/crypto/md5/md5block_generic.go
index 263463e..726e09b 100644
--- a/libgo/go/crypto/md5/md5block_generic.go
+++ b/libgo/go/crypto/md5/md5block_generic.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64,!amd64p32,!386,!arm
+// +build !amd64,!amd64p32,!386,!arm,!ppc64le,!s390x
package md5
diff --git a/libgo/go/crypto/rand/eagain.go b/libgo/go/crypto/rand/eagain.go
index 2c853d0..7ed2f47 100644
--- a/libgo/go/crypto/rand/eagain.go
+++ b/libgo/go/crypto/rand/eagain.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The Go Authors. All rights reserved.
+// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/rand/rand.go b/libgo/go/crypto/rand/rand.go
index ee32fa0..6f7523d 100644
--- a/libgo/go/crypto/rand/rand.go
+++ b/libgo/go/crypto/rand/rand.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -11,8 +11,9 @@ import "io"
// Reader is a global, shared instance of a cryptographically
// strong pseudo-random generator.
//
-// On Unix-like systems, Reader reads from /dev/urandom.
// On Linux, Reader uses getrandom(2) if available, /dev/urandom otherwise.
+// On OpenBSD, Reader uses getentropy(2).
+// On other Unix-like systems, Reader reads from /dev/urandom.
// On Windows systems, Reader uses the CryptGenRandom API.
var Reader io.Reader
diff --git a/libgo/go/crypto/rand/rand_linux.go b/libgo/go/crypto/rand/rand_linux.go
index 7d6d9e8..472daa7 100644
--- a/libgo/go/crypto/rand/rand_linux.go
+++ b/libgo/go/crypto/rand/rand_linux.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The Go Authors. All rights reserved.
+// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/rand/rand_openbsd.go b/libgo/go/crypto/rand/rand_openbsd.go
new file mode 100644
index 0000000..9cc39f7
--- /dev/null
+++ b/libgo/go/crypto/rand/rand_openbsd.go
@@ -0,0 +1,28 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rand
+
+import (
+ "internal/syscall/unix"
+)
+
+func init() {
+ altGetRandom = getRandomOpenBSD
+}
+
+func getRandomOpenBSD(p []byte) (ok bool) {
+ // getentropy(2) returns a maximum of 256 bytes per call
+ for i := 0; i < len(p); i += 256 {
+ end := i + 256
+ if len(p) < end {
+ end = len(p)
+ }
+ err := unix.GetEntropy(p[i:end])
+ if err != nil {
+ return false
+ }
+ }
+ return true
+}
diff --git a/libgo/go/crypto/rand/rand_test.go b/libgo/go/crypto/rand/rand_test.go
index e46e61d..e45f58e 100644
--- a/libgo/go/crypto/rand/rand_test.go
+++ b/libgo/go/crypto/rand/rand_test.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go
index 75c36e0..631972b 100644
--- a/libgo/go/crypto/rand/rand_unix.go
+++ b/libgo/go/crypto/rand/rand_unix.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -84,7 +84,7 @@ func (hr hideAgainReader) Read(p []byte) (n int, err error) {
// systems without a reliable /dev/urandom.
// newReader returns a new pseudorandom generator that
-// seeds itself by reading from entropy. If entropy == nil,
+// seeds itself by reading from entropy. If entropy == nil,
// the generator seeds itself by reading from the system's
// random number generator, typically /dev/random.
// The Read method on the returned reader always returns
diff --git a/libgo/go/crypto/rand/rand_windows.go b/libgo/go/crypto/rand/rand_windows.go
index 82b39b6..4d7511a 100644
--- a/libgo/go/crypto/rand/rand_windows.go
+++ b/libgo/go/crypto/rand/rand_windows.go
@@ -1,4 +1,4 @@
-// Copyright 2010 The Go Authors. All rights reserved.
+// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/rand/util.go b/libgo/go/crypto/rand/util.go
index 5f74407..592c57e 100644
--- a/libgo/go/crypto/rand/util.go
+++ b/libgo/go/crypto/rand/util.go
@@ -1,4 +1,4 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -70,7 +70,7 @@ func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
p.SetBytes(bytes)
- // Calculate the value mod the product of smallPrimes. If it's
+ // Calculate the value mod the product of smallPrimes. If it's
// a multiple of any of these primes we add two until it isn't.
// The probability of overflowing is minimal and can be ignored
// because we still perform Miller-Rabin tests on the result.
diff --git a/libgo/go/crypto/rand/util_test.go b/libgo/go/crypto/rand/util_test.go
index 2f7cba8..7b07689 100644
--- a/libgo/go/crypto/rand/util_test.go
+++ b/libgo/go/crypto/rand/util_test.go
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/libgo/go/crypto/rc4/rc4.go b/libgo/go/crypto/rc4/rc4.go
index 9acb681..bd04aee 100644
--- a/libgo/go/crypto/rc4/rc4.go
+++ b/libgo/go/crypto/rc4/rc4.go
@@ -23,7 +23,7 @@ func (k KeySizeError) Error() string {
return "crypto/rc4: invalid key size " + strconv.Itoa(int(k))
}
-// NewCipher creates and returns a new Cipher. The key argument should be the
+// NewCipher creates and returns a new Cipher. The key argument should be the
// RC4 key, at least 1 byte and at most 256 bytes.
func NewCipher(key []byte) (*Cipher, error) {
k := len(key)
@@ -52,7 +52,7 @@ func (c *Cipher) Reset() {
}
// xorKeyStreamGeneric sets dst to the result of XORing src with the
-// key stream. Dst and src may be the same slice but otherwise should
+// key stream. Dst and src may be the same slice but otherwise should
// not overlap.
//
// This is the pure Go version. rc4_{amd64,386,arm}* contain assembly
diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go
index 5c5f415..3517a8c 100644
--- a/libgo/go/crypto/rsa/pkcs1v15.go
+++ b/libgo/go/crypto/rsa/pkcs1v15.go
@@ -24,31 +24,32 @@ type PKCS1v15DecryptOptions struct {
SessionKeyLen int
}
-// EncryptPKCS1v15 encrypts the given message with RSA and the padding scheme from PKCS#1 v1.5.
-// The message must be no longer than the length of the public modulus minus 11 bytes.
+// EncryptPKCS1v15 encrypts the given message with RSA and the padding
+// scheme from PKCS#1 v1.5. The message must be no longer than the
+// length of the public modulus minus 11 bytes.
//
-// The rand parameter is used as a source of entropy to ensure that encrypting
-// the same message twice doesn't result in the same ciphertext.
+// The rand parameter is used as a source of entropy to ensure that
+// encrypting the same message twice doesn't result in the same
+// ciphertext.
//
-// WARNING: use of this function to encrypt plaintexts other than session keys
-// is dangerous. Use RSA OAEP in new protocols.
-func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error) {
+// WARNING: use of this function to encrypt plaintexts other than
+// session keys is dangerous. Use RSA OAEP in new protocols.
+func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
if err := checkPub(pub); err != nil {
return nil, err
}
k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-11 {
- err = ErrMessageTooLong
- return
+ return nil, ErrMessageTooLong
}
// EM = 0x00 || 0x02 || PS || 0x00 || M
em := make([]byte, k)
em[1] = 2
ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
- err = nonZeroRandomBytes(ps, rand)
+ err := nonZeroRandomBytes(ps, rand)
if err != nil {
- return
+ return nil, err
}
em[len(em)-len(msg)-1] = 0
copy(mm, msg)
@@ -57,8 +58,7 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
c := encrypt(new(big.Int), pub, m)
copyWithLeftPad(em, c.Bytes())
- out = em
- return
+ return em, nil
}
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
@@ -69,19 +69,18 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
// learn whether each instance returned an error then they can decrypt and
// forge signatures as if they had the private key. See
// DecryptPKCS1v15SessionKey for a way of solving this problem.
-func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error) {
+func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
if err != nil {
- return
+ return nil, err
}
if valid == 0 {
return nil, ErrDecryption
}
- out = out[index:]
- return
+ return out[index:], nil
}
// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
@@ -103,7 +102,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [
// a random value was used (because it'll be different for the same ciphertext)
// and thus whether the padding was correct. This defeats the point of this
// function. Using at least a 16-byte key will protect against this attack.
-func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
+func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error {
if err := checkPub(&priv.PublicKey); err != nil {
return err
}
@@ -114,7 +113,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by
valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
if err != nil {
- return
+ return err
}
if len(em) != k {
@@ -125,7 +124,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by
valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
- return
+ return nil
}
// decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
@@ -213,21 +212,23 @@ var hashPrefixes = map[crypto.Hash][]byte{
crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
}
-// SignPKCS1v15 calculates the signature of hashed using RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5.
-// Note that hashed must be the result of hashing the input message using the
-// given hash function. If hash is zero, hashed is signed directly. This isn't
+// SignPKCS1v15 calculates the signature of hashed using
+// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS#1 v1.5. Note that hashed must
+// be the result of hashing the input message using the given hash
+// function. If hash is zero, hashed is signed directly. This isn't
// advisable except for interoperability.
//
-// If rand is not nil then RSA blinding will be used to avoid timing side-channel attacks.
+// If rand is not nil then RSA blinding will be used to avoid timing
+// side-channel attacks.
//
-// This function is deterministic. Thus, if the set of possible messages is
-// small, an attacker may be able to build a map from messages to signatures
-// and identify the signed messages. As ever, signatures provide authenticity,
-// not confidentiality.
-func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) (s []byte, err error) {
+// This function is deterministic. Thus, if the set of possible
+// messages is small, an attacker may be able to build a map from
+// messages to signatures and identify the signed messages. As ever,
+// signatures provide authenticity, not confidentiality.
+func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
- return
+ return nil, err
}
tLen := len(prefix) + hashLen
@@ -248,12 +249,11 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
m := new(big.Int).SetBytes(em)
c, err := decryptAndCheck(rand, priv, m)
if err != nil {
- return
+ return nil, err
}
copyWithLeftPad(em, c.Bytes())
- s = em
- return
+ return em, nil
}
// VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature.
@@ -261,17 +261,16 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
// function and sig is the signature. A valid signature is indicated by
// returning a nil error. If hash is zero then hashed is used directly. This
// isn't advisable except for interoperability.
-func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (err error) {
+func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
- return
+ return err
}
tLen := len(prefix) + hashLen
k := (pub.N.BitLen() + 7) / 8
if k < tLen+11 {
- err = ErrVerification
- return
+ return ErrVerification
}
c := new(big.Int).SetBytes(sig)
diff --git a/libgo/go/crypto/rsa/pss.go b/libgo/go/crypto/rsa/pss.go
index 8a94589..1ba194a 100644
--- a/libgo/go/crypto/rsa/pss.go
+++ b/libgo/go/crypto/rsa/pss.go
@@ -64,7 +64,7 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
hash.Reset()
// 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
- // zero octets. The length of PS may be 0.
+ // zero octets. The length of PS may be 0.
//
// 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
// emLen - hLen - 1.
@@ -246,7 +246,7 @@ func (opts *PSSOptions) saltLength() int {
// Note that hashed must be the result of hashing the input message using the
// given hash function. The opts argument may be nil, in which case sensible
// defaults are used.
-func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) (s []byte, err error) {
+func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) ([]byte, error) {
saltLength := opts.saltLength()
switch saltLength {
case PSSSaltLengthAuto:
@@ -260,8 +260,8 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte,
}
salt := make([]byte, saltLength)
- if _, err = io.ReadFull(rand, salt); err != nil {
- return
+ if _, err := io.ReadFull(rand, salt); err != nil {
+ return nil, err
}
return signPSSWithSalt(rand, priv, hash, hashed, salt)
}
diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go
index 0f487fe..5943056 100644
--- a/libgo/go/crypto/rsa/rsa.go
+++ b/libgo/go/crypto/rsa/rsa.go
@@ -14,7 +14,7 @@
// possible.
//
// Two sets of interfaces are included in this package. When a more abstract
-// interface isn't neccessary, there are functions for encrypting/decrypting
+// interface isn't necessary, there are functions for encrypting/decrypting
// with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract
// over the public-key primitive, the PrivateKey struct implements the
// Decrypter and Signer interfaces from the crypto package.
@@ -191,7 +191,7 @@ func (priv *PrivateKey) Validate() error {
// GenerateKey generates an RSA keypair of the given bit size using the
// random source random (for example, crypto/rand.Reader).
-func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
+func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
return GenerateMultiPrimeKey(random, 2, bits)
}
@@ -206,8 +206,8 @@ func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
//
// [1] US patent 4405829 (1972, expired)
// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
-func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (priv *PrivateKey, err error) {
- priv = new(PrivateKey)
+func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
+ priv := new(PrivateKey)
priv.E = 65537
if nprimes < 2 {
@@ -234,6 +234,7 @@ NextSetOfPrimes:
todo += (nprimes - 2) / 5
}
for i := 0; i < nprimes; i++ {
+ var err error
primes[i], err = rand.Prime(random, todo/(nprimes-i))
if err != nil {
return nil, err
@@ -283,7 +284,7 @@ NextSetOfPrimes:
}
priv.Precompute()
- return
+ return priv, nil
}
// incCounter increments a four byte, big-endian counter.
@@ -348,15 +349,14 @@ func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
//
// The message must be no longer than the length of the public modulus less
// twice the hash length plus 2.
-func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
+func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
if err := checkPub(pub); err != nil {
return nil, err
}
hash.Reset()
k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-2*hash.Size()-2 {
- err = ErrMessageTooLong
- return
+ return nil, ErrMessageTooLong
}
hash.Write(label)
@@ -371,9 +371,9 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
db[len(db)-len(msg)-1] = 1
copy(db[len(db)-len(msg):], msg)
- _, err = io.ReadFull(random, seed)
+ _, err := io.ReadFull(random, seed)
if err != nil {
- return
+ return nil, err
}
mgf1XOR(db, hash, seed)
@@ -382,7 +382,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
m := new(big.Int)
m.SetBytes(em)
c := encrypt(new(big.Int), pub, m)
- out = c.Bytes()
+ out := c.Bytes()
if len(out) < k {
// If the output is too small, we need to left-pad with zeros.
@@ -391,7 +391,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
out = t
}
- return
+ return out, nil
}
// ErrDecryption represents a failure to decrypt a message.
@@ -565,22 +565,21 @@ func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int
//
// The label parameter must match the value given when encrypting. See
// EncryptOAEP for details.
-func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err error) {
+func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
k := (priv.N.BitLen() + 7) / 8
if len(ciphertext) > k ||
k < hash.Size()*2+2 {
- err = ErrDecryption
- return
+ return nil, ErrDecryption
}
c := new(big.Int).SetBytes(ciphertext)
m, err := decrypt(random, priv, c)
if err != nil {
- return
+ return nil, err
}
hash.Write(label)
@@ -628,12 +627,10 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
}
if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
- err = ErrDecryption
- return
+ return nil, ErrDecryption
}
- msg = rest[index+1:]
- return
+ return rest[index+1:], nil
}
// leftPad returns a new slice of length size. The contents of input are right
diff --git a/libgo/go/crypto/sha1/fallback_test.go b/libgo/go/crypto/sha1/fallback_test.go
new file mode 100644
index 0000000..08acd04
--- /dev/null
+++ b/libgo/go/crypto/sha1/fallback_test.go
@@ -0,0 +1,34 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build s390x
+
+package sha1
+
+import (
+ "fmt"
+ "io"
+ "testing"
+)
+
+// Tests the fallback code path in case the optimized asm
+// implementation cannot be used.
+// See also TestBlockGeneric.
+func TestGenericPath(t *testing.T) {
+ if useAsm == false {
+ t.Skipf("assembly implementation unavailable")
+ }
+ useAsm = false
+ defer func() { useAsm = true }()
+ c := New()
+ in := "ΑΒΓΔΕϜΖΗΘΙΚΛΜΝΞΟΠϺϘΡΣΤΥΦΧΨΩ"
+ gold := "0f58c2bb130f8182375f325c18342215255387e5"
+ if _, err := io.WriteString(c, in); err != nil {
+ t.Fatalf("could not write to c: %v", err)
+ }
+ out := fmt.Sprintf("%x", c.Sum(nil))
+ if out != gold {
+ t.Fatalf("mismatch: got %s, wanted %s", out, gold)
+ }
+}
diff --git a/libgo/go/crypto/sha1/issue15617_test.go b/libgo/go/crypto/sha1/issue15617_test.go
new file mode 100644
index 0000000..98038e5
--- /dev/null
+++ b/libgo/go/crypto/sha1/issue15617_test.go
@@ -0,0 +1,28 @@
+// +build amd64
+// +build linux darwin
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha1_test
+
+import (
+ "crypto/sha1"
+ "syscall"
+ "testing"
+)
+
+func TestOutOfBoundsRead(t *testing.T) {
+ const pageSize = 4 << 10
+ data, err := syscall.Mmap(0, 0, 2*pageSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
+ if err != nil {
+ panic(err)
+ }
+ if err := syscall.Mprotect(data[pageSize:], syscall.PROT_NONE); err != nil {
+ panic(err)
+ }
+ for i := 0; i < pageSize; i++ {
+ sha1.Sum(data[pageSize-i : pageSize])
+ }
+}
diff --git a/libgo/go/crypto/sha1/sha1.go b/libgo/go/crypto/sha1/sha1.go
index 9f1a96e..ac593b1 100644
--- a/libgo/go/crypto/sha1/sha1.go
+++ b/libgo/go/crypto/sha1/sha1.go
@@ -90,7 +90,7 @@ func (d0 *digest) Sum(in []byte) []byte {
func (d *digest) checkSum() [Size]byte {
len := d.len
- // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
+ // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
var tmp [64]byte
tmp[0] = 0x80
if len%64 < 56 {
diff --git a/libgo/go/crypto/sha1/sha1_test.go b/libgo/go/crypto/sha1/sha1_test.go
index 4a62951..214afc5 100644
--- a/libgo/go/crypto/sha1/sha1_test.go
+++ b/libgo/go/crypto/sha1/sha1_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// SHA1 hash algorithm. See RFC 3174.
+// SHA1 hash algorithm. See RFC 3174.
package sha1
@@ -19,6 +19,7 @@ type sha1Test struct {
}
var golden = []sha1Test{
+ {"76245dbf96f661bd221046197ab8b9f063f11bad", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"},
{"da39a3ee5e6b4b0d3255bfef95601890afd80709", ""},
{"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a"},
{"da23614e02469a0d7c7bd1bdab5c9c474b1904dc", "ab"},
@@ -91,15 +92,17 @@ func TestBlockSize(t *testing.T) {
}
}
-// Tests that blockGeneric (pure Go) and block (in assembly for amd64, 386, arm) match.
+// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
func TestBlockGeneric(t *testing.T) {
- gen, asm := New().(*digest), New().(*digest)
- buf := make([]byte, BlockSize*20) // arbitrary factor
- rand.Read(buf)
- blockGeneric(gen, buf)
- block(asm, buf)
- if *gen != *asm {
- t.Error("block and blockGeneric resulted in different states")
+ for i := 1; i < 30; i++ { // arbitrary factor
+ gen, asm := New().(*digest), New().(*digest)
+ buf := make([]byte, BlockSize*i)
+ rand.Read(buf)
+ blockGeneric(gen, buf)
+ block(asm, buf)
+ if *gen != *asm {
+ t.Errorf("For %#v block and blockGeneric resulted in different states", buf)
+ }
}
}
@@ -120,6 +123,10 @@ func BenchmarkHash8Bytes(b *testing.B) {
benchmarkSize(b, 8)
}
+func BenchmarkHash320Bytes(b *testing.B) {
+ benchmarkSize(b, 320)
+}
+
func BenchmarkHash1K(b *testing.B) {
benchmarkSize(b, 1024)
}
diff --git a/libgo/go/crypto/sha1/sha1block_amd64.go b/libgo/go/crypto/sha1/sha1block_amd64.go
new file mode 100644
index 0000000..fd85a42
--- /dev/null
+++ b/libgo/go/crypto/sha1/sha1block_amd64.go
@@ -0,0 +1,34 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha1
+
+//go:noescape
+
+func blockAVX2(dig *digest, p []byte)
+
+//go:noescape
+func blockAMD64(dig *digest, p []byte)
+func checkAVX2() bool
+
+var hasAVX2 = checkAVX2()
+
+func block(dig *digest, p []byte) {
+ if hasAVX2 && len(p) >= 256 {
+ // blockAVX2 calculates sha1 for 2 block per iteration
+ // it also interleaves precalculation for next block.
+ // So it may read up-to 192 bytes past end of p
+ // We may add checks inside blockAVX2, but this will
+ // just turn it into a copy of blockAMD64,
+ // so call it directly, instead.
+ safeLen := len(p) - 128
+ if safeLen%128 != 0 {
+ safeLen -= 64
+ }
+ blockAVX2(dig, p[:safeLen])
+ blockAMD64(dig, p[safeLen:])
+ } else {
+ blockAMD64(dig, p)
+ }
+}
diff --git a/libgo/go/crypto/sha1/sha1block_decl.go b/libgo/go/crypto/sha1/sha1block_decl.go
index 24e521a..6d2d073 100644
--- a/libgo/go/crypto/sha1/sha1block_decl.go
+++ b/libgo/go/crypto/sha1/sha1block_decl.go
@@ -1,8 +1,8 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64 amd64p32 arm 386
+// +build amd64p32 arm 386 s390x
package sha1
diff --git a/libgo/go/crypto/sha1/sha1block_generic.go b/libgo/go/crypto/sha1/sha1block_generic.go
index 696e26b..f0194626 100644
--- a/libgo/go/crypto/sha1/sha1block_generic.go
+++ b/libgo/go/crypto/sha1/sha1block_generic.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64,!amd64p32,!386,!arm
+// +build !amd64,!amd64p32,!386,!arm,!s390x
package sha1
diff --git a/libgo/go/crypto/sha1/sha1block_s390x.go b/libgo/go/crypto/sha1/sha1block_s390x.go
new file mode 100644
index 0000000..aac7c11
--- /dev/null
+++ b/libgo/go/crypto/sha1/sha1block_s390x.go
@@ -0,0 +1,12 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha1
+
+// featureCheck reports whether the CPU supports the
+// SHA1 compute intermediate message digest (KIMD)
+// function code.
+func featureCheck() bool
+
+var useAsm = featureCheck()
diff --git a/libgo/go/crypto/sha256/fallback_test.go b/libgo/go/crypto/sha256/fallback_test.go
new file mode 100644
index 0000000..5917a48
--- /dev/null
+++ b/libgo/go/crypto/sha256/fallback_test.go
@@ -0,0 +1,35 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build s390x
+
+package sha256
+
+import (
+ "fmt"
+ "io"
+ "testing"
+)
+
+// Tests the fallback code path in case the optimized asm
+// implementation cannot be used.
+// See also TestBlockGeneric.
+func TestGenericPath(t *testing.T) {
+ if useAsm == false {
+ t.Skipf("assembly implementation unavailable")
+ }
+ useAsm = false
+ defer func() { useAsm = true }()
+ c := New()
+ in := "ΑΒΓΔΕϜΖΗΘΙΚΛΜΝΞΟΠϺϘΡΣΤΥΦΧΨΩ"
+ gold := "e93d84ec2b22383123be9f713697fb25" +
+ "338c86e2f7d8d1ddc2d89d332dd9d76c"
+ if _, err := io.WriteString(c, in); err != nil {
+ t.Fatalf("could not write to c: %v", err)
+ }
+ out := fmt.Sprintf("%x", c.Sum(nil))
+ if out != gold {
+ t.Fatalf("mismatch: got %s, wanted %s", out, gold)
+ }
+}
diff --git a/libgo/go/crypto/sha256/sha256.go b/libgo/go/crypto/sha256/sha256.go
index d84cebf..74b05b9 100644
--- a/libgo/go/crypto/sha256/sha256.go
+++ b/libgo/go/crypto/sha256/sha256.go
@@ -137,7 +137,7 @@ func (d0 *digest) Sum(in []byte) []byte {
func (d *digest) checkSum() [Size]byte {
len := d.len
- // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
+ // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
var tmp [64]byte
tmp[0] = 0x80
if len%64 < 56 {
diff --git a/libgo/go/crypto/sha256/sha256_test.go b/libgo/go/crypto/sha256/sha256_test.go
index 1d883d3..279cf5a 100644
--- a/libgo/go/crypto/sha256/sha256_test.go
+++ b/libgo/go/crypto/sha256/sha256_test.go
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// SHA256 hash algorithm. See FIPS 180-2.
+// SHA256 hash algorithm. See FIPS 180-2.
package sha256
import (
+ "crypto/rand"
"fmt"
"io"
"testing"
@@ -150,6 +151,18 @@ func TestBlockSize(t *testing.T) {
}
}
+// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
+func TestBlockGeneric(t *testing.T) {
+ gen, asm := New().(*digest), New().(*digest)
+ buf := make([]byte, BlockSize*20) // arbitrary factor
+ rand.Read(buf)
+ blockGeneric(gen, buf)
+ block(asm, buf)
+ if *gen != *asm {
+ t.Error("block and blockGeneric resulted in different states")
+ }
+}
+
var bench = New()
var buf = make([]byte, 8192)
diff --git a/libgo/go/crypto/sha256/sha256block.go b/libgo/go/crypto/sha256/sha256block.go
index ca5efd1..d43bbf0 100644
--- a/libgo/go/crypto/sha256/sha256block.go
+++ b/libgo/go/crypto/sha256/sha256block.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !386,!amd64
-
// SHA256 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
@@ -77,7 +75,7 @@ var _K = []uint32{
0xc67178f2,
}
-func block(dig *digest, p []byte) {
+func blockGeneric(dig *digest, p []byte) {
var w [64]uint32
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= chunk {
diff --git a/libgo/go/crypto/sha256/sha256block_decl.go b/libgo/go/crypto/sha256/sha256block_decl.go
index a50c978..e6caff9 100644
--- a/libgo/go/crypto/sha256/sha256block_decl.go
+++ b/libgo/go/crypto/sha256/sha256block_decl.go
@@ -1,8 +1,8 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build 386 amd64
+// +build 386 amd64 s390x
package sha256
diff --git a/libgo/go/crypto/sha256/sha256block_generic.go b/libgo/go/crypto/sha256/sha256block_generic.go
new file mode 100644
index 0000000..1a01969
--- /dev/null
+++ b/libgo/go/crypto/sha256/sha256block_generic.go
@@ -0,0 +1,9 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64,!386,!s390x
+
+package sha256
+
+var block = blockGeneric
diff --git a/libgo/go/crypto/sha256/sha256block_s390x.go b/libgo/go/crypto/sha256/sha256block_s390x.go
new file mode 100644
index 0000000..b7beefe
--- /dev/null
+++ b/libgo/go/crypto/sha256/sha256block_s390x.go
@@ -0,0 +1,12 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha256
+
+// featureCheck reports whether the CPU supports the
+// SHA256 compute intermediate message digest (KIMD)
+// function code.
+func featureCheck() bool
+
+var useAsm = featureCheck()
diff --git a/libgo/go/crypto/sha512/fallback_test.go b/libgo/go/crypto/sha512/fallback_test.go
new file mode 100644
index 0000000..9024ce6
--- /dev/null
+++ b/libgo/go/crypto/sha512/fallback_test.go
@@ -0,0 +1,37 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build s390x
+
+package sha512
+
+import (
+ "fmt"
+ "io"
+ "testing"
+)
+
+// Tests the fallback code path in case the optimized asm
+// implementation cannot be used.
+// See also TestBlockGeneric.
+func TestGenericPath(t *testing.T) {
+ if useAsm == false {
+ t.Skipf("assembly implementation unavailable")
+ }
+ useAsm = false
+ defer func() { useAsm = true }()
+ c := New()
+ in := "ΑΒΓΔΕϜΖΗΘΙΚΛΜΝΞΟΠϺϘΡΣΤΥΦΧΨΩ"
+ gold := "6922e319366d677f34c504af31bfcb29" +
+ "e531c125ecd08679362bffbd6b6ebfb9" +
+ "0dcc27dfc1f3d3b16a16c0763cf43b91" +
+ "40bbf9bbb7233724e9a0c6655b185d76"
+ if _, err := io.WriteString(c, in); err != nil {
+ t.Fatalf("could not write to c: %v", err)
+ }
+ out := fmt.Sprintf("%x", c.Sum(nil))
+ if out != gold {
+ t.Fatalf("mismatch: got %s, wanted %s", out, gold)
+ }
+}
diff --git a/libgo/go/crypto/sha512/sha512.go b/libgo/go/crypto/sha512/sha512.go
index e7781fd..5603c90 100644
--- a/libgo/go/crypto/sha512/sha512.go
+++ b/libgo/go/crypto/sha512/sha512.go
@@ -208,7 +208,7 @@ func (d0 *digest) Sum(in []byte) []byte {
}
func (d *digest) checkSum() [Size]byte {
- // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
+ // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
len := d.len
var tmp [128]byte
tmp[0] = 0x80
diff --git a/libgo/go/crypto/sha512/sha512_test.go b/libgo/go/crypto/sha512/sha512_test.go
index 04b3d4a..a3a136a 100644
--- a/libgo/go/crypto/sha512/sha512_test.go
+++ b/libgo/go/crypto/sha512/sha512_test.go
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// SHA512 hash algorithm. See FIPS 180-4.
+// SHA512 hash algorithm. See FIPS 180-4.
package sha512
import (
+ "crypto/rand"
"encoding/hex"
"hash"
"io"
@@ -304,6 +305,18 @@ func TestBlockSize(t *testing.T) {
}
}
+// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
+func TestBlockGeneric(t *testing.T) {
+ gen, asm := New().(*digest), New().(*digest)
+ buf := make([]byte, BlockSize*20) // arbitrary factor
+ rand.Read(buf)
+ blockGeneric(gen, buf)
+ block(asm, buf)
+ if *gen != *asm {
+ t.Error("block and blockGeneric resulted in different states")
+ }
+}
+
var bench = New()
var buf = make([]byte, 8192)
diff --git a/libgo/go/crypto/sha512/sha512block.go b/libgo/go/crypto/sha512/sha512block.go
index 648ae8f..42e8d19 100644
--- a/libgo/go/crypto/sha512/sha512block.go
+++ b/libgo/go/crypto/sha512/sha512block.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64
-
// SHA512 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
@@ -93,7 +91,7 @@ var _K = []uint64{
0x6c44198c4a475817,
}
-func block(dig *digest, p []byte) {
+func blockGeneric(dig *digest, p []byte) {
var w [80]uint64
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= chunk {
diff --git a/libgo/go/crypto/sha512/sha512block_decl.go b/libgo/go/crypto/sha512/sha512block_decl.go
index bef99de..47d656a 100644
--- a/libgo/go/crypto/sha512/sha512block_decl.go
+++ b/libgo/go/crypto/sha512/sha512block_decl.go
@@ -1,8 +1,8 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64
+// +build amd64 s390x
package sha512
diff --git a/libgo/go/crypto/sha512/sha512block_generic.go b/libgo/go/crypto/sha512/sha512block_generic.go
new file mode 100644
index 0000000..2c691ba
--- /dev/null
+++ b/libgo/go/crypto/sha512/sha512block_generic.go
@@ -0,0 +1,9 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64,!s390x
+
+package sha512
+
+var block = blockGeneric
diff --git a/libgo/go/crypto/sha512/sha512block_s390x.go b/libgo/go/crypto/sha512/sha512block_s390x.go
new file mode 100644
index 0000000..f05dc18
--- /dev/null
+++ b/libgo/go/crypto/sha512/sha512block_s390x.go
@@ -0,0 +1,12 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha512
+
+// featureCheck reports whether the CPU supports the
+// SHA512 compute intermediate message digest (KIMD)
+// function code.
+func featureCheck() bool
+
+var useAsm = featureCheck()
diff --git a/libgo/go/crypto/subtle/constant_time.go b/libgo/go/crypto/subtle/constant_time.go
index 6f80e7c..11312b8 100644
--- a/libgo/go/crypto/subtle/constant_time.go
+++ b/libgo/go/crypto/subtle/constant_time.go
@@ -6,7 +6,7 @@
// code but require careful thought to use correctly.
package subtle
-// ConstantTimeCompare returns 1 iff the two slices, x
+// ConstantTimeCompare returns 1 if and only if the two slices, x
// and y, have equal contents. The time taken is a function of the length of
// the slices and is independent of the contents.
func ConstantTimeCompare(x, y []byte) int {
diff --git a/libgo/go/crypto/tls/alert.go b/libgo/go/crypto/tls/alert.go
index 3de4834..9cf9922 100644
--- a/libgo/go/crypto/tls/alert.go
+++ b/libgo/go/crypto/tls/alert.go
@@ -69,9 +69,9 @@ var alertText = map[alert]string{
func (e alert) String() string {
s, ok := alertText[e]
if ok {
- return s
+ return "tls: " + s
}
- return "alert(" + strconv.Itoa(int(e)) + ")"
+ return "tls: alert(" + strconv.Itoa(int(e)) + ")"
}
func (e alert) Error() string {
diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go
index 869ffa5..e69f5f96 100644
--- a/libgo/go/crypto/tls/cipher_suites.go
+++ b/libgo/go/crypto/tls/cipher_suites.go
@@ -74,7 +74,7 @@ type cipherSuite struct {
var cipherSuites = []*cipherSuite{
// Ciphersuite order is chosen so that ECDHE comes before plain RSA
- // and RC4 comes before AES (because of the Lucky13 attack).
+ // and RC4 comes before AES-CBC (because of the Lucky13 attack).
{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},
@@ -261,8 +261,10 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
return nil
}
-// A list of the possible cipher suite ids. Taken from
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+// A list of cipher suite IDs that are, or have been, implemented by this
+// package.
+//
+// Taken from http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
const (
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
@@ -284,6 +286,6 @@ const (
// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
// that the client is doing version fallback. See
- // https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00.
+ // https://tools.ietf.org/html/rfc7507.
TLS_FALLBACK_SCSV uint16 = 0x5600
)
diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go
index c68ebfe..9fc7420 100644
--- a/libgo/go/crypto/tls/common.go
+++ b/libgo/go/crypto/tls/common.go
@@ -48,6 +48,7 @@ const (
// TLS handshake message types.
const (
+ typeHelloRequest uint8 = 0
typeClientHello uint8 = 1
typeServerHello uint8 = 2
typeNewSessionTicket uint8 = 4
@@ -114,7 +115,7 @@ const (
certTypeRSAFixedDH = 3 // A certificate containing a static DH key
certTypeDSSFixedDH = 4 // A certificate containing a static DH key
- // See RFC4492 sections 3 and 5.5.
+ // See RFC 4492 sections 3 and 5.5.
certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA.
certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA.
certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA.
@@ -238,6 +239,33 @@ type ClientHelloInfo struct {
SupportedPoints []uint8
}
+// RenegotiationSupport enumerates the different levels of support for TLS
+// renegotiation. TLS renegotiation is the act of performing subsequent
+// handshakes on a connection after the first. This significantly complicates
+// the state machine and has been the source of numerous, subtle security
+// issues. Initiating a renegotiation is not supported, but support for
+// accepting renegotiation requests may be enabled.
+//
+// Even when enabled, the server may not change its identity between handshakes
+// (i.e. the leaf certificate must be the same). Additionally, concurrent
+// handshake and application data flow is not permitted so renegotiation can
+// only be used with protocols that synchronise with the renegotiation, such as
+// HTTPS.
+type RenegotiationSupport int
+
+const (
+ // RenegotiateNever disables renegotiation.
+ RenegotiateNever RenegotiationSupport = iota
+
+ // RenegotiateOnceAsClient allows a remote server to request
+ // renegotiation once per connection.
+ RenegotiateOnceAsClient
+
+ // RenegotiateFreelyAsClient allows a remote server to repeatedly
+ // request renegotiation.
+ RenegotiateFreelyAsClient
+)
+
// A Config structure is used to configure a TLS client or server.
// After one has been passed to a TLS function it must not be
// modified. A Config may be reused; the tls package will also not
@@ -349,6 +377,16 @@ type Config struct {
// be used.
CurvePreferences []CurveID
+ // DynamicRecordSizingDisabled disables adaptive sizing of TLS records.
+ // When true, the largest possible TLS record size is always used. When
+ // false, the size of TLS records may be adjusted in an attempt to
+ // improve latency.
+ DynamicRecordSizingDisabled bool
+
+ // Renegotiation controls what types of renegotiation are supported.
+ // The default, none, is correct for the vast majority of applications.
+ Renegotiation RenegotiationSupport
+
serverInitOnce sync.Once // guards calling (*Config).serverInit
// mutex protects sessionTicketKeys
@@ -384,6 +422,33 @@ func ticketKeyFromBytes(b [32]byte) (key ticketKey) {
return key
}
+// clone returns a copy of c. Only the exported fields are copied.
+func (c *Config) clone() *Config {
+ return &Config{
+ Rand: c.Rand,
+ Time: c.Time,
+ Certificates: c.Certificates,
+ NameToCertificate: c.NameToCertificate,
+ GetCertificate: c.GetCertificate,
+ RootCAs: c.RootCAs,
+ NextProtos: c.NextProtos,
+ ServerName: c.ServerName,
+ ClientAuth: c.ClientAuth,
+ ClientCAs: c.ClientCAs,
+ InsecureSkipVerify: c.InsecureSkipVerify,
+ CipherSuites: c.CipherSuites,
+ PreferServerCipherSuites: c.PreferServerCipherSuites,
+ SessionTicketsDisabled: c.SessionTicketsDisabled,
+ SessionTicketKey: c.SessionTicketKey,
+ ClientSessionCache: c.ClientSessionCache,
+ MinVersion: c.MinVersion,
+ MaxVersion: c.MaxVersion,
+ CurvePreferences: c.CurvePreferences,
+ DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
+ Renegotiation: c.Renegotiation,
+ }
+}
+
func (c *Config) serverInit() {
if c.SessionTicketsDisabled {
return
@@ -510,7 +575,7 @@ func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, err
}
if len(c.Certificates) == 0 {
- return nil, errors.New("crypto/tls: no certificates configured")
+ return nil, errors.New("tls: no certificates configured")
}
if len(c.Certificates) == 1 || c.NameToCertificate == nil {
@@ -584,13 +649,6 @@ type Certificate struct {
Leaf *x509.Certificate
}
-// A TLS record.
-type record struct {
- contentType recordType
- major, minor uint8
- payload []byte
-}
-
type handshakeMessage interface {
marshal() []byte
unmarshal([]byte) bool
diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go
index 0377568..87bef23d 100644
--- a/libgo/go/crypto/tls/conn.go
+++ b/libgo/go/crypto/tls/conn.go
@@ -28,34 +28,60 @@ type Conn struct {
isClient bool
// constant after handshake; protected by handshakeMutex
- handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
- handshakeErr error // error resulting from handshake
- vers uint16 // TLS version
- haveVers bool // version has been negotiated
- config *Config // configuration passed to constructor
+ handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
+ handshakeErr error // error resulting from handshake
+ vers uint16 // TLS version
+ haveVers bool // version has been negotiated
+ config *Config // configuration passed to constructor
+ // handshakeComplete is true if the connection is currently transfering
+ // application data (i.e. is not currently processing a handshake).
handshakeComplete bool
- didResume bool // whether this connection was a session resumption
- cipherSuite uint16
- ocspResponse []byte // stapled OCSP response
- scts [][]byte // signed certificate timestamps from server
- peerCertificates []*x509.Certificate
+ // handshakes counts the number of handshakes performed on the
+ // connection so far. If renegotiation is disabled then this is either
+ // zero or one.
+ handshakes int
+ didResume bool // whether this connection was a session resumption
+ cipherSuite uint16
+ ocspResponse []byte // stapled OCSP response
+ scts [][]byte // signed certificate timestamps from server
+ peerCertificates []*x509.Certificate
// verifiedChains contains the certificate chains that we built, as
// opposed to the ones presented by the server.
verifiedChains [][]*x509.Certificate
// serverName contains the server name indicated by the client, if any.
serverName string
- // firstFinished contains the first Finished hash sent during the
- // handshake. This is the "tls-unique" channel binding value.
- firstFinished [12]byte
+ // secureRenegotiation is true if the server echoed the secure
+ // renegotiation extension. (This is meaningless as a server because
+ // renegotiation is not supported in that case.)
+ secureRenegotiation bool
+
+ // clientFinishedIsFirst is true if the client sent the first Finished
+ // message during the most recent handshake. This is recorded because
+ // the first transmitted Finished message is the tls-unique
+ // channel-binding value.
+ clientFinishedIsFirst bool
+ // clientFinished and serverFinished contain the Finished message sent
+ // by the client or server in the most recent handshake. This is
+ // retained to support the renegotiation extension and tls-unique
+ // channel-binding.
+ clientFinished [12]byte
+ serverFinished [12]byte
clientProtocol string
clientProtocolFallback bool
// input/output
- in, out halfConn // in.Mutex < out.Mutex
- rawInput *block // raw input, right off the wire
- input *block // application data waiting to be read
- hand bytes.Buffer // handshake data waiting to be read
+ in, out halfConn // in.Mutex < out.Mutex
+ rawInput *block // raw input, right off the wire
+ input *block // application data waiting to be read
+ hand bytes.Buffer // handshake data waiting to be read
+ buffering bool // whether records are buffered in sendBuf
+ sendBuf []byte // a buffer of records waiting to be sent
+
+ // bytesSent counts the bytes of application data sent.
+ // packetsSent counts packets.
+ bytesSent int64
+ packetsSent int64
// activeCall is an atomic int32; the low bit is whether Close has
// been called. the rest of the bits are the number of goroutines
@@ -124,13 +150,6 @@ func (hc *halfConn) setErrorLocked(err error) error {
return err
}
-func (hc *halfConn) error() error {
- hc.Lock()
- err := hc.err
- hc.Unlock()
- return err
-}
-
// prepareCipherSpec sets the encryption and MAC states
// that a subsequent changeCipherSpec will use.
func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
@@ -170,13 +189,6 @@ func (hc *halfConn) incSeq() {
panic("TLS: sequence number wraparound")
}
-// resetSeq resets the sequence number to zero.
-func (hc *halfConn) resetSeq() {
- for i := range hc.seq {
- hc.seq[i] = 0
- }
-}
-
// removePadding returns an unpadded slice, in constant time, which is a prefix
// of the input. It also returns a byte which is equal to 255 if the padding
// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
@@ -535,7 +547,7 @@ func (c *Conn) newRecordHeaderError(msg string) (err RecordHeaderError) {
func (c *Conn) readRecord(want recordType) error {
// Caller must be in sync with connection:
// handshake data if handshake not yet completed,
- // else application data. (We don't support renegotiation.)
+ // else application data.
switch want {
default:
c.sendAlert(alertInternalError)
@@ -543,12 +555,12 @@ func (c *Conn) readRecord(want recordType) error {
case recordTypeHandshake, recordTypeChangeCipherSpec:
if c.handshakeComplete {
c.sendAlert(alertInternalError)
- return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete"))
+ return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested while not in handshake"))
}
case recordTypeApplicationData:
if !c.handshakeComplete {
c.sendAlert(alertInternalError)
- return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
+ return c.in.setErrorLocked(errors.New("tls: application data record requested while in handshake"))
}
}
@@ -672,7 +684,7 @@ Again:
case recordTypeHandshake:
// TODO(rsc): Should at least pick off connection close.
- if typ != want {
+ if typ != want && !(c.isClient && c.config.Renegotiation != RenegotiateNever) {
return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
}
c.hand.Write(data)
@@ -694,12 +706,14 @@ func (c *Conn) sendAlertLocked(err alert) error {
c.tmp[0] = alertLevelError
}
c.tmp[1] = byte(err)
- c.writeRecord(recordTypeAlert, c.tmp[0:2])
- // closeNotify is a special case in that it isn't an error:
- if err != alertCloseNotify {
- return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+
+ _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2])
+ if err == alertCloseNotify {
+ // closeNotify is a special case in that it isn't an error.
+ return writeErr
}
- return nil
+
+ return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
}
// sendAlert sends a TLS alert message.
@@ -710,16 +724,120 @@ func (c *Conn) sendAlert(err alert) error {
return c.sendAlertLocked(err)
}
-// writeRecord writes a TLS record with the given type and payload
-// to the connection and updates the record layer state.
+const (
+ // tcpMSSEstimate is a conservative estimate of the TCP maximum segment
+ // size (MSS). A constant is used, rather than querying the kernel for
+ // the actual MSS, to avoid complexity. The value here is the IPv6
+ // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40
+ // bytes) and a TCP header with timestamps (32 bytes).
+ tcpMSSEstimate = 1208
+
+ // recordSizeBoostThreshold is the number of bytes of application data
+ // sent after which the TLS record size will be increased to the
+ // maximum.
+ recordSizeBoostThreshold = 128 * 1024
+)
+
+// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the
+// next application data record. There is the following trade-off:
+//
+// - For latency-sensitive applications, such as web browsing, each TLS
+// record should fit in one TCP segment.
+// - For throughput-sensitive applications, such as large file transfers,
+// larger TLS records better amortize framing and encryption overheads.
+//
+// A simple heuristic that works well in practice is to use small records for
+// the first 1MB of data, then use larger records for subsequent data, and
+// reset back to smaller records after the connection becomes idle. See "High
+// Performance Web Networking", Chapter 4, or:
+// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
+//
+// In the interests of simplicity and determinism, this code does not attempt
+// to reset the record size once the connection is idle, however.
+//
+// c.out.Mutex <= L.
+func (c *Conn) maxPayloadSizeForWrite(typ recordType, explicitIVLen int) int {
+ if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData {
+ return maxPlaintext
+ }
+
+ if c.bytesSent >= recordSizeBoostThreshold {
+ return maxPlaintext
+ }
+
+ // Subtract TLS overheads to get the maximum payload size.
+ macSize := 0
+ if c.out.mac != nil {
+ macSize = c.out.mac.Size()
+ }
+
+ payloadBytes := tcpMSSEstimate - recordHeaderLen - explicitIVLen
+ if c.out.cipher != nil {
+ switch ciph := c.out.cipher.(type) {
+ case cipher.Stream:
+ payloadBytes -= macSize
+ case cipher.AEAD:
+ payloadBytes -= ciph.Overhead()
+ case cbcMode:
+ blockSize := ciph.BlockSize()
+ // The payload must fit in a multiple of blockSize, with
+ // room for at least one padding byte.
+ payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1
+ // The MAC is appended before padding so affects the
+ // payload size directly.
+ payloadBytes -= macSize
+ default:
+ panic("unknown cipher type")
+ }
+ }
+
+ // Allow packet growth in arithmetic progression up to max.
+ pkt := c.packetsSent
+ c.packetsSent++
+ if pkt > 1000 {
+ return maxPlaintext // avoid overflow in multiply below
+ }
+
+ n := payloadBytes * int(pkt+1)
+ if n > maxPlaintext {
+ n = maxPlaintext
+ }
+ return n
+}
+
// c.out.Mutex <= L.
-func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
+func (c *Conn) write(data []byte) (int, error) {
+ if c.buffering {
+ c.sendBuf = append(c.sendBuf, data...)
+ return len(data), nil
+ }
+
+ n, err := c.conn.Write(data)
+ c.bytesSent += int64(n)
+ return n, err
+}
+
+func (c *Conn) flush() (int, error) {
+ if len(c.sendBuf) == 0 {
+ return 0, nil
+ }
+
+ n, err := c.conn.Write(c.sendBuf)
+ c.bytesSent += int64(n)
+ c.sendBuf = nil
+ c.buffering = false
+ return n, err
+}
+
+// writeRecordLocked writes a TLS record with the given type and payload to the
+// connection and updates the record layer state.
+// c.out.Mutex <= L.
+func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
b := c.out.newBlock()
+ defer c.out.freeBlock(b)
+
+ var n int
for len(data) > 0 {
- m := len(data)
- if m > maxPlaintext {
- m = maxPlaintext
- }
explicitIVLen := 0
explicitIVIsSeq := false
@@ -742,6 +860,10 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
explicitIVIsSeq = true
}
}
+ m := len(data)
+ if maxPayload := c.maxPayloadSizeForWrite(typ, explicitIVLen); m > maxPayload {
+ m = maxPayload
+ }
b.resize(recordHeaderLen + explicitIVLen + m)
b.data[0] = byte(typ)
vers := c.vers
@@ -759,34 +881,37 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
if explicitIVIsSeq {
copy(explicitIV, c.out.seq[:])
} else {
- if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
- break
+ if _, err := io.ReadFull(c.config.rand(), explicitIV); err != nil {
+ return n, err
}
}
}
copy(b.data[recordHeaderLen+explicitIVLen:], data)
c.out.encrypt(b, explicitIVLen)
- _, err = c.conn.Write(b.data)
- if err != nil {
- break
+ if _, err := c.write(b.data); err != nil {
+ return n, err
}
n += m
data = data[m:]
}
- c.out.freeBlock(b)
if typ == recordTypeChangeCipherSpec {
- err = c.out.changeCipherSpec()
- if err != nil {
- // Cannot call sendAlert directly,
- // because we already hold c.out.Mutex.
- c.tmp[0] = alertLevelError
- c.tmp[1] = byte(err.(alert))
- c.writeRecord(recordTypeAlert, c.tmp[0:2])
- return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+ if err := c.out.changeCipherSpec(); err != nil {
+ return n, c.sendAlertLocked(err.(alert))
}
}
- return
+
+ return n, nil
+}
+
+// writeRecord writes a TLS record with the given type and payload to the
+// connection and updates the record layer state.
+// L < c.out.Mutex.
+func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ return c.writeRecordLocked(typ, data)
}
// readHandshake reads the next handshake message from
@@ -805,7 +930,8 @@ func (c *Conn) readHandshake() (interface{}, error) {
data := c.hand.Bytes()
n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
if n > maxHandshake {
- return nil, c.in.setErrorLocked(c.sendAlert(alertInternalError))
+ c.sendAlertLocked(alertInternalError)
+ return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
}
for c.hand.Len() < 4+n {
if err := c.in.err; err != nil {
@@ -818,6 +944,8 @@ func (c *Conn) readHandshake() (interface{}, error) {
data = c.hand.Next(4 + n)
var m handshakeMessage
switch data[0] {
+ case typeHelloRequest:
+ m = new(helloRequestMsg)
case typeClientHello:
m = new(clientHelloMsg)
case typeServerHello:
@@ -861,7 +989,7 @@ func (c *Conn) readHandshake() (interface{}, error) {
return m, nil
}
-var errClosed = errors.New("crypto/tls: use of closed connection")
+var errClosed = errors.New("tls: use of closed connection")
// Write writes data to the connection.
func (c *Conn) Write(b []byte) (int, error) {
@@ -904,7 +1032,7 @@ func (c *Conn) Write(b []byte) (int, error) {
var m int
if len(b) > 1 && c.vers <= VersionTLS10 {
if _, ok := c.out.cipher.(cipher.BlockMode); ok {
- n, err := c.writeRecord(recordTypeApplicationData, b[:1])
+ n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])
if err != nil {
return n, c.out.setErrorLocked(err)
}
@@ -912,10 +1040,52 @@ func (c *Conn) Write(b []byte) (int, error) {
}
}
- n, err := c.writeRecord(recordTypeApplicationData, b)
+ n, err := c.writeRecordLocked(recordTypeApplicationData, b)
return n + m, c.out.setErrorLocked(err)
}
+// handleRenegotiation processes a HelloRequest handshake message.
+// c.in.Mutex <= L
+func (c *Conn) handleRenegotiation() error {
+ msg, err := c.readHandshake()
+ if err != nil {
+ return err
+ }
+
+ _, ok := msg.(*helloRequestMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return alertUnexpectedMessage
+ }
+
+ if !c.isClient {
+ return c.sendAlert(alertNoRenegotiation)
+ }
+
+ switch c.config.Renegotiation {
+ case RenegotiateNever:
+ return c.sendAlert(alertNoRenegotiation)
+ case RenegotiateOnceAsClient:
+ if c.handshakes > 1 {
+ return c.sendAlert(alertNoRenegotiation)
+ }
+ case RenegotiateFreelyAsClient:
+ // Ok.
+ default:
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: unknown Renegotiation value")
+ }
+
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ c.handshakeComplete = false
+ if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil {
+ c.handshakes++
+ }
+ return c.handshakeErr
+}
+
// Read can be made to time out and return a net.Error with Timeout() == true
// after a fixed time limit; see SetDeadline and SetReadDeadline.
func (c *Conn) Read(b []byte) (n int, err error) {
@@ -940,6 +1110,13 @@ func (c *Conn) Read(b []byte) (n int, err error) {
// Soft error, like EAGAIN
return 0, err
}
+ if c.hand.Len() > 0 {
+ // We received handshake bytes, indicating the
+ // start of a renegotiation.
+ if err := c.handleRenegotiation(); err != nil {
+ return 0, err
+ }
+ }
}
if err := c.in.err; err != nil {
return 0, err
@@ -1020,13 +1197,35 @@ func (c *Conn) Close() error {
// Most uses of this package need not call Handshake
// explicitly: the first Read or Write will call it automatically.
func (c *Conn) Handshake() error {
+ // c.handshakeErr and c.handshakeComplete are protected by
+ // c.handshakeMutex. In order to perform a handshake, we need to lock
+ // c.in also and c.handshakeMutex must be locked after c.in.
+ //
+ // However, if a Read() operation is hanging then it'll be holding the
+ // lock on c.in and so taking it here would cause all operations that
+ // need to check whether a handshake is pending (such as Write) to
+ // block.
+ //
+ // Thus we take c.handshakeMutex first and, if we find that a handshake
+ // is needed, then we unlock, acquire c.in and c.handshakeMutex in the
+ // correct order, and check again.
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
- if err := c.handshakeErr; err != nil {
- return err
- }
- if c.handshakeComplete {
- return nil
+
+ for i := 0; i < 2; i++ {
+ if i == 1 {
+ c.handshakeMutex.Unlock()
+ c.in.Lock()
+ defer c.in.Unlock()
+ c.handshakeMutex.Lock()
+ }
+
+ if err := c.handshakeErr; err != nil {
+ return err
+ }
+ if c.handshakeComplete {
+ return nil
+ }
}
if c.isClient {
@@ -1034,6 +1233,9 @@ func (c *Conn) Handshake() error {
} else {
c.handshakeErr = c.serverHandshake()
}
+ if c.handshakeErr == nil {
+ c.handshakes++
+ }
return c.handshakeErr
}
@@ -1056,7 +1258,11 @@ func (c *Conn) ConnectionState() ConnectionState {
state.SignedCertificateTimestamps = c.scts
state.OCSPResponse = c.ocspResponse
if !c.didResume {
- state.TLSUnique = c.firstFinished[:]
+ if c.clientFinishedIsFirst {
+ state.TLSUnique = c.clientFinished[:]
+ } else {
+ state.TLSUnique = c.serverFinished[:]
+ }
}
}
@@ -1073,7 +1279,7 @@ func (c *Conn) OCSPResponse() []byte {
}
// VerifyHostname checks that the peer certificate chain is valid for
-// connecting to host. If so, it returns nil; if not, it returns an error
+// connecting to host. If so, it returns nil; if not, it returns an error
// describing the problem.
func (c *Conn) VerifyHostname(host string) error {
c.handshakeMutex.Lock()
diff --git a/libgo/go/crypto/tls/conn_test.go b/libgo/go/crypto/tls/conn_test.go
index ec802ca..5cff7e7 100644
--- a/libgo/go/crypto/tls/conn_test.go
+++ b/libgo/go/crypto/tls/conn_test.go
@@ -5,6 +5,9 @@
package tls
import (
+ "bytes"
+ "io"
+ "net"
"testing"
)
@@ -116,3 +119,125 @@ func TestCertificateSelection(t *testing.T) {
t.Errorf("foo.bar.baz.example.com returned certificate %d, not 0", n)
}
}
+
+// Run with multiple crypto configs to test the logic for computing TLS record overheads.
+func runDynamicRecordSizingTest(t *testing.T, config *Config) {
+ clientConn, serverConn := net.Pipe()
+
+ serverConfig := config.clone()
+ serverConfig.DynamicRecordSizingDisabled = false
+ tlsConn := Server(serverConn, serverConfig)
+
+ recordSizesChan := make(chan []int, 1)
+ go func() {
+ // This goroutine performs a TLS handshake over clientConn and
+ // then reads TLS records until EOF. It writes a slice that
+ // contains all the record sizes to recordSizesChan.
+ defer close(recordSizesChan)
+ defer clientConn.Close()
+
+ tlsConn := Client(clientConn, config)
+ if err := tlsConn.Handshake(); err != nil {
+ t.Errorf("Error from client handshake: %s", err)
+ return
+ }
+
+ var recordHeader [recordHeaderLen]byte
+ var record []byte
+ var recordSizes []int
+
+ for {
+ n, err := clientConn.Read(recordHeader[:])
+ if err == io.EOF {
+ break
+ }
+ if err != nil || n != len(recordHeader) {
+ t.Errorf("Error from client read: %s", err)
+ return
+ }
+
+ length := int(recordHeader[3])<<8 | int(recordHeader[4])
+ if len(record) < length {
+ record = make([]byte, length)
+ }
+
+ n, err = clientConn.Read(record[:length])
+ if err != nil || n != length {
+ t.Errorf("Error from client read: %s", err)
+ return
+ }
+
+ // The last record will be a close_notify alert, which
+ // we don't wish to record.
+ if recordType(recordHeader[0]) == recordTypeApplicationData {
+ recordSizes = append(recordSizes, recordHeaderLen+length)
+ }
+ }
+
+ recordSizesChan <- recordSizes
+ }()
+
+ if err := tlsConn.Handshake(); err != nil {
+ t.Fatalf("Error from server handshake: %s", err)
+ }
+
+ // The server writes these plaintexts in order.
+ plaintext := bytes.Join([][]byte{
+ bytes.Repeat([]byte("x"), recordSizeBoostThreshold),
+ bytes.Repeat([]byte("y"), maxPlaintext*2),
+ bytes.Repeat([]byte("z"), maxPlaintext),
+ }, nil)
+
+ if _, err := tlsConn.Write(plaintext); err != nil {
+ t.Fatalf("Error from server write: %s", err)
+ }
+ if err := tlsConn.Close(); err != nil {
+ t.Fatalf("Error from server close: %s", err)
+ }
+
+ recordSizes := <-recordSizesChan
+ if recordSizes == nil {
+ t.Fatalf("Client encountered an error")
+ }
+
+ // Drop the size of last record, which is likely to be truncated.
+ recordSizes = recordSizes[:len(recordSizes)-1]
+
+ // recordSizes should contain a series of records smaller than
+ // tcpMSSEstimate followed by some larger than maxPlaintext.
+ seenLargeRecord := false
+ for i, size := range recordSizes {
+ if !seenLargeRecord {
+ if size > (i+1)*tcpMSSEstimate {
+ t.Fatalf("Record #%d has size %d, which is too large too soon", i, size)
+ }
+ if size >= maxPlaintext {
+ seenLargeRecord = true
+ }
+ } else if size <= maxPlaintext {
+ t.Fatalf("Record #%d has size %d but should be full sized", i, size)
+ }
+ }
+
+ if !seenLargeRecord {
+ t.Fatalf("No large records observed")
+ }
+}
+
+func TestDynamicRecordSizingWithStreamCipher(t *testing.T) {
+ config := testConfig.clone()
+ config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
+ runDynamicRecordSizingTest(t, config)
+}
+
+func TestDynamicRecordSizingWithCBC(t *testing.T) {
+ config := testConfig.clone()
+ config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA}
+ runDynamicRecordSizingTest(t, config)
+}
+
+func TestDynamicRecordSizingWithAEAD(t *testing.T) {
+ config := testConfig.clone()
+ config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
+ runDynamicRecordSizingTest(t, config)
+}
diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go
index 3c996ac..f789e6f 100644
--- a/libgo/go/crypto/tls/handshake_client.go
+++ b/libgo/go/crypto/tls/handshake_client.go
@@ -16,6 +16,7 @@ import (
"io"
"net"
"strconv"
+ "strings"
)
type clientHandshakeState struct {
@@ -28,11 +29,16 @@ type clientHandshakeState struct {
session *ClientSessionState
}
+// c.out.Mutex <= L; c.handshakeMutex <= L.
func (c *Conn) clientHandshake() error {
if c.config == nil {
c.config = defaultConfig()
}
+ // This may be a renegotiation handshake, in which case some fields
+ // need to be reset.
+ c.didResume = false
+
if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
}
@@ -49,25 +55,22 @@ func (c *Conn) clientHandshake() error {
return errors.New("tls: NextProtos values too large")
}
- sni := c.config.ServerName
- // IP address literals are not permitted as SNI values. See
- // https://tools.ietf.org/html/rfc6066#section-3.
- if net.ParseIP(sni) != nil {
- sni = ""
+ hello := &clientHelloMsg{
+ vers: c.config.maxVersion(),
+ compressionMethods: []uint8{compressionNone},
+ random: make([]byte, 32),
+ ocspStapling: true,
+ scts: true,
+ serverName: hostnameInSNI(c.config.ServerName),
+ supportedCurves: c.config.curvePreferences(),
+ supportedPoints: []uint8{pointFormatUncompressed},
+ nextProtoNeg: len(c.config.NextProtos) > 0,
+ secureRenegotiationSupported: true,
+ alpnProtocols: c.config.NextProtos,
}
- hello := &clientHelloMsg{
- vers: c.config.maxVersion(),
- compressionMethods: []uint8{compressionNone},
- random: make([]byte, 32),
- ocspStapling: true,
- scts: true,
- serverName: sni,
- supportedCurves: c.config.curvePreferences(),
- supportedPoints: []uint8{pointFormatUncompressed},
- nextProtoNeg: len(c.config.NextProtos) > 0,
- secureRenegotiation: true,
- alpnProtocols: c.config.NextProtos,
+ if c.handshakes > 0 {
+ hello.secureRenegotiation = c.clientFinished[:]
}
possibleCipherSuites := c.config.cipherSuites()
@@ -108,7 +111,12 @@ NextCipherSuite:
if sessionCache != nil {
hello.ticketSupported = true
+ }
+ // Session resumption is not allowed if renegotiating because
+ // renegotiation is primarily used to allow a client to send a client
+ // certificate, which would be skipped if session resumption occured.
+ if sessionCache != nil && c.handshakes == 0 {
// Try to resume a previously negotiated TLS session, if
// available.
cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
@@ -144,7 +152,9 @@ NextCipherSuite:
}
}
- c.writeRecord(recordTypeHandshake, hello.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {
+ return err
+ }
msg, err := c.readHandshake()
if err != nil {
@@ -196,6 +206,7 @@ NextCipherSuite:
hs.finishedHash.Write(hs.hello.marshal())
hs.finishedHash.Write(hs.serverHello.marshal())
+ c.buffering = true
if isResume {
if err := hs.establishKeys(); err != nil {
return err
@@ -203,10 +214,14 @@ NextCipherSuite:
if err := hs.readSessionTicket(); err != nil {
return err
}
- if err := hs.readFinished(c.firstFinished[:]); err != nil {
+ if err := hs.readFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = false
+ if err := hs.sendFinished(c.clientFinished[:]); err != nil {
return err
}
- if err := hs.sendFinished(nil); err != nil {
+ if _, err := c.flush(); err != nil {
return err
}
} else {
@@ -216,13 +231,17 @@ NextCipherSuite:
if err := hs.establishKeys(); err != nil {
return err
}
- if err := hs.sendFinished(c.firstFinished[:]); err != nil {
+ if err := hs.sendFinished(c.clientFinished[:]); err != nil {
return err
}
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = true
if err := hs.readSessionTicket(); err != nil {
return err
}
- if err := hs.readFinished(nil); err != nil {
+ if err := hs.readFinished(c.serverFinished[:]); err != nil {
return err
}
}
@@ -251,47 +270,62 @@ func (hs *clientHandshakeState) doFullHandshake() error {
}
hs.finishedHash.Write(certMsg.marshal())
- certs := make([]*x509.Certificate, len(certMsg.certificates))
- for i, asn1Data := range certMsg.certificates {
- cert, err := x509.ParseCertificate(asn1Data)
- if err != nil {
- c.sendAlert(alertBadCertificate)
- return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ if c.handshakes == 0 {
+ // If this is the first handshake on a connection, process and
+ // (optionally) verify the server's certificates.
+ certs := make([]*x509.Certificate, len(certMsg.certificates))
+ for i, asn1Data := range certMsg.certificates {
+ cert, err := x509.ParseCertificate(asn1Data)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ }
+ certs[i] = cert
}
- certs[i] = cert
- }
- if !c.config.InsecureSkipVerify {
- opts := x509.VerifyOptions{
- Roots: c.config.RootCAs,
- CurrentTime: c.config.time(),
- DNSName: c.config.ServerName,
- Intermediates: x509.NewCertPool(),
- }
+ if !c.config.InsecureSkipVerify {
+ opts := x509.VerifyOptions{
+ Roots: c.config.RootCAs,
+ CurrentTime: c.config.time(),
+ DNSName: c.config.ServerName,
+ Intermediates: x509.NewCertPool(),
+ }
- for i, cert := range certs {
- if i == 0 {
- continue
+ for i, cert := range certs {
+ if i == 0 {
+ continue
+ }
+ opts.Intermediates.AddCert(cert)
+ }
+ c.verifiedChains, err = certs[0].Verify(opts)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
}
- opts.Intermediates.AddCert(cert)
}
- c.verifiedChains, err = certs[0].Verify(opts)
- if err != nil {
- c.sendAlert(alertBadCertificate)
- return err
+
+ switch certs[0].PublicKey.(type) {
+ case *rsa.PublicKey, *ecdsa.PublicKey:
+ break
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
}
- }
- switch certs[0].PublicKey.(type) {
- case *rsa.PublicKey, *ecdsa.PublicKey:
- break
- default:
- c.sendAlert(alertUnsupportedCertificate)
- return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
+ c.peerCertificates = certs
+ } else {
+ // This is a renegotiation handshake. We require that the
+ // server's identity (i.e. leaf certificate) is unchanged and
+ // thus any previous trust decision is still valid.
+ //
+ // See https://mitls.org/pages/attacks/3SHAKE for the
+ // motivation behind this requirement.
+ if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: server's identity changed during renegotiation")
+ }
}
- c.peerCertificates = certs
-
if hs.serverHello.ocspStapling {
msg, err = c.readHandshake()
if err != nil {
@@ -319,7 +353,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
skx, ok := msg.(*serverKeyExchangeMsg)
if ok {
hs.finishedHash.Write(skx.marshal())
- err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
+ err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
if err != nil {
c.sendAlert(alertUnexpectedMessage)
return err
@@ -425,17 +459,21 @@ func (hs *clientHandshakeState) doFullHandshake() error {
certMsg.certificates = chainToSend.Certificate
}
hs.finishedHash.Write(certMsg.marshal())
- c.writeRecord(recordTypeHandshake, certMsg.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
+ return err
+ }
}
- preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
+ preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
if err != nil {
c.sendAlert(alertInternalError)
return err
}
if ckx != nil {
hs.finishedHash.Write(ckx.marshal())
- c.writeRecord(recordTypeHandshake, ckx.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
+ return err
+ }
}
if chainToSend != nil {
@@ -477,7 +515,9 @@ func (hs *clientHandshakeState) doFullHandshake() error {
}
hs.finishedHash.Write(certVerify.marshal())
- c.writeRecord(recordTypeHandshake, certVerify.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
+ return err
+ }
}
hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
@@ -524,6 +564,24 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
return false, errors.New("tls: server selected unsupported compression format")
}
+ if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
+ c.secureRenegotiation = true
+ if len(hs.serverHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+ }
+
+ if c.handshakes > 0 && c.secureRenegotiation {
+ var expectedSecureRenegotiation [24]byte
+ copy(expectedSecureRenegotiation[:], c.clientFinished[:])
+ copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
+ if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: incorrect renegotiation extension contents")
+ }
+ }
+
clientDidNPN := hs.hello.nextProtoNeg
clientDidALPN := len(hs.hello.alpnProtocols) > 0
serverHasNPN := hs.serverHello.nextProtoNeg
@@ -531,17 +589,17 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
if !clientDidNPN && serverHasNPN {
c.sendAlert(alertHandshakeFailure)
- return false, errors.New("server advertised unrequested NPN extension")
+ return false, errors.New("tls: server advertised unrequested NPN extension")
}
if !clientDidALPN && serverHasALPN {
c.sendAlert(alertHandshakeFailure)
- return false, errors.New("server advertised unrequested ALPN extension")
+ return false, errors.New("tls: server advertised unrequested ALPN extension")
}
if serverHasNPN && serverHasALPN {
c.sendAlert(alertHandshakeFailure)
- return false, errors.New("server advertised both NPN and ALPN extensions")
+ return false, errors.New("tls: server advertised both NPN and ALPN extensions")
}
if serverHasALPN {
@@ -550,22 +608,33 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
}
c.scts = hs.serverHello.scts
- if hs.serverResumedSession() {
- // Restore masterSecret and peerCerts from previous state
- hs.masterSecret = hs.session.masterSecret
- c.peerCertificates = hs.session.serverCertificates
- c.verifiedChains = hs.session.verifiedChains
- return true, nil
+ if !hs.serverResumedSession() {
+ return false, nil
+ }
+
+ if hs.session.vers != c.vers {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different version")
+ }
+
+ if hs.session.cipherSuite != hs.suite.id {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different cipher suite")
}
- return false, nil
+
+ // Restore masterSecret and peerCerts from previous state
+ hs.masterSecret = hs.session.masterSecret
+ c.peerCertificates = hs.session.serverCertificates
+ c.verifiedChains = hs.session.verifiedChains
+ return true, nil
}
func (hs *clientHandshakeState) readFinished(out []byte) error {
c := hs.c
c.readRecord(recordTypeChangeCipherSpec)
- if err := c.in.error(); err != nil {
- return err
+ if c.in.err != nil {
+ return c.in.err
}
msg, err := c.readHandshake()
@@ -621,7 +690,9 @@ func (hs *clientHandshakeState) readSessionTicket() error {
func (hs *clientHandshakeState) sendFinished(out []byte) error {
c := hs.c
- c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
+ return err
+ }
if hs.serverHello.nextProtoNeg {
nextProto := new(nextProtoMsg)
proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
@@ -630,13 +701,17 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
c.clientProtocolFallback = fallback
hs.finishedHash.Write(nextProto.marshal())
- c.writeRecord(recordTypeHandshake, nextProto.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
+ return err
+ }
}
finished := new(finishedMsg)
finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
hs.finishedHash.Write(finished.marshal())
- c.writeRecord(recordTypeHandshake, finished.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
+ return err
+ }
copy(out, finished.verifyData)
return nil
}
@@ -665,3 +740,23 @@ func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
return protos[0], true
}
+
+// hostnameInSNI converts name into an approriate hostname for SNI.
+// Literal IP addresses and absolute FQDNs are not permitted as SNI values.
+// See https://tools.ietf.org/html/rfc6066#section-3.
+func hostnameInSNI(name string) string {
+ host := name
+ if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
+ host = host[1 : len(host)-1]
+ }
+ if i := strings.LastIndex(host, "%"); i > 0 {
+ host = host[:i]
+ }
+ if net.ParseIP(host) != nil {
+ return ""
+ }
+ if len(name) > 0 && name[len(name)-1] == '.' {
+ name = name[:len(name)-1]
+ }
+ return name
+}
diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go
index f78cc46..ce987f1 100644
--- a/libgo/go/crypto/tls/handshake_client_test.go
+++ b/libgo/go/crypto/tls/handshake_client_test.go
@@ -12,6 +12,7 @@ import (
"encoding/base64"
"encoding/binary"
"encoding/pem"
+ "errors"
"fmt"
"io"
"net"
@@ -27,14 +28,80 @@ import (
// Note: see comment in handshake_test.go for details of how the reference
// tests work.
-// blockingSource is an io.Reader that blocks a Read call until it's closed.
-type blockingSource chan bool
+// opensslInputEvent enumerates possible inputs that can be sent to an `openssl
+// s_client` process.
+type opensslInputEvent int
+
+const (
+ // opensslRenegotiate causes OpenSSL to request a renegotiation of the
+ // connection.
+ opensslRenegotiate opensslInputEvent = iota
+
+ // opensslSendBanner causes OpenSSL to send the contents of
+ // opensslSentinel on the connection.
+ opensslSendSentinel
+)
+
+const opensslSentinel = "SENTINEL\n"
+
+type opensslInput chan opensslInputEvent
+
+func (i opensslInput) Read(buf []byte) (n int, err error) {
+ for event := range i {
+ switch event {
+ case opensslRenegotiate:
+ return copy(buf, []byte("R\n")), nil
+ case opensslSendSentinel:
+ return copy(buf, []byte(opensslSentinel)), nil
+ default:
+ panic("unknown event")
+ }
+ }
-func (b blockingSource) Read([]byte) (n int, err error) {
- <-b
return 0, io.EOF
}
+// opensslOutputSink is an io.Writer that receives the stdout and stderr from
+// an `openssl` process and sends a value to handshakeComplete when it sees a
+// log message from a completed server handshake.
+type opensslOutputSink struct {
+ handshakeComplete chan struct{}
+ all []byte
+ line []byte
+}
+
+func newOpensslOutputSink() *opensslOutputSink {
+ return &opensslOutputSink{make(chan struct{}), nil, nil}
+}
+
+// opensslEndOfHandshake is a message that the “openssl s_server” tool will
+// print when a handshake completes if run with “-state”.
+const opensslEndOfHandshake = "SSL_accept:SSLv3 write finished A"
+
+func (o *opensslOutputSink) Write(data []byte) (n int, err error) {
+ o.line = append(o.line, data...)
+ o.all = append(o.all, data...)
+
+ for {
+ i := bytes.Index(o.line, []byte{'\n'})
+ if i < 0 {
+ break
+ }
+
+ if bytes.Equal([]byte(opensslEndOfHandshake), o.line[:i]) {
+ o.handshakeComplete <- struct{}{}
+ }
+ o.line = o.line[i+1:]
+ }
+
+ return len(data), nil
+}
+
+func (o *opensslOutputSink) WriteTo(w io.Writer) (int64, error) {
+ n, err := w.Write(o.all)
+ return int64(n), err
+}
+
// clientTest represents a test of the TLS client handshake against a reference
// implementation.
type clientTest struct {
@@ -60,15 +127,25 @@ type clientTest struct {
// ConnectionState of the resulting connection. It returns a non-nil
// error if the ConnectionState is unacceptable.
validate func(ConnectionState) error
+ // numRenegotiations is the number of times that the connection will be
+ // renegotiated.
+ numRenegotiations int
+ // renegotiationExpectedToFail, if not zero, is the number of the
+ // renegotiation attempt that is expected to fail.
+ renegotiationExpectedToFail int
+ // checkRenegotiationError, if not nil, is called with any error
+ // arising from renegotiation. It can map expected errors to nil to
+ // ignore them.
+ checkRenegotiationError func(renegotiationNum int, err error) error
}
var defaultServerCommand = []string{"openssl", "s_server"}
// connFromCommand starts the reference server process, connects to it and
-// returns a recordingConn for the connection. The stdin return value is a
-// blockingSource for the stdin of the child process. It must be closed before
+// returns a recordingConn for the connection. The stdin return value is an
+// opensslInput for the stdin of the child process. It must be closed before
// Waiting for child.
-func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin blockingSource, err error) {
+func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin opensslInput, stdout *opensslOutputSink, err error) {
cert := testRSACertificate
if len(test.cert) > 0 {
cert = test.cert
@@ -131,14 +208,28 @@ func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd,
command = append(command, "-serverinfo", serverInfoPath)
}
+ if test.numRenegotiations > 0 {
+ found := false
+ for _, flag := range command[1:] {
+ if flag == "-state" {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ panic("-state flag missing to OpenSSL. You need this if testing renegotiation")
+ }
+ }
+
cmd := exec.Command(command[0], command[1:]...)
- stdin = blockingSource(make(chan bool))
+ stdin = opensslInput(make(chan opensslInputEvent))
cmd.Stdin = stdin
- var out bytes.Buffer
- cmd.Stdout = &out
- cmd.Stderr = &out
+ out := newOpensslOutputSink()
+ cmd.Stdout = out
+ cmd.Stderr = out
if err := cmd.Start(); err != nil {
- return nil, nil, nil, err
+ return nil, nil, nil, nil, err
}
// OpenSSL does print an "ACCEPT" banner, but it does so *before*
@@ -160,14 +251,14 @@ func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd,
close(stdin)
out.WriteTo(os.Stdout)
cmd.Process.Kill()
- return nil, nil, nil, cmd.Wait()
+ return nil, nil, nil, nil, cmd.Wait()
}
record := &recordingConn{
Conn: tcpConn,
}
- return record, cmd, stdin, nil
+ return record, cmd, stdin, out, nil
}
func (test *clientTest) dataPath() string {
@@ -187,11 +278,12 @@ func (test *clientTest) run(t *testing.T, write bool) {
var clientConn, serverConn net.Conn
var recordingConn *recordingConn
var childProcess *exec.Cmd
- var stdin blockingSource
+ var stdin opensslInput
+ var stdout *opensslOutputSink
if write {
var err error
- recordingConn, childProcess, stdin, err = test.connFromCommand()
+ recordingConn, childProcess, stdin, stdout, err = test.connFromCommand()
if err != nil {
t.Fatalf("Failed to start subcommand: %s", err)
}
@@ -208,17 +300,77 @@ func (test *clientTest) run(t *testing.T, write bool) {
doneChan := make(chan bool)
go func() {
+ defer func() { doneChan <- true }()
+ defer clientConn.Close()
+ defer client.Close()
+
if _, err := client.Write([]byte("hello\n")); err != nil {
t.Errorf("Client.Write failed: %s", err)
+ return
}
+
+ for i := 1; i <= test.numRenegotiations; i++ {
+ // The initial handshake will generate a
+ // handshakeComplete signal which needs to be quashed.
+ if i == 1 && write {
+ <-stdout.handshakeComplete
+ }
+
+ // OpenSSL will try to interleave application data and
+ // a renegotiation if we send both concurrently.
+ // Therefore: ask OpensSSL to start a renegotiation, run
+ // a goroutine to call client.Read and thus process the
+ // renegotiation request, watch for OpenSSL's stdout to
+ // indicate that the handshake is complete and,
+ // finally, have OpenSSL write something to cause
+ // client.Read to complete.
+ if write {
+ stdin <- opensslRenegotiate
+ }
+
+ signalChan := make(chan struct{})
+
+ go func() {
+ defer func() { signalChan <- struct{}{} }()
+
+ buf := make([]byte, 256)
+ n, err := client.Read(buf)
+
+ if test.checkRenegotiationError != nil {
+ newErr := test.checkRenegotiationError(i, err)
+ if err != nil && newErr == nil {
+ return
+ }
+ err = newErr
+ }
+
+ if err != nil {
+ t.Errorf("Client.Read failed after renegotiation #%d: %s", i, err)
+ return
+ }
+
+ buf = buf[:n]
+ if !bytes.Equal([]byte(opensslSentinel), buf) {
+ t.Errorf("Client.Read returned %q, but wanted %q", string(buf), opensslSentinel)
+ }
+
+ if expected := i + 1; client.handshakes != expected {
+ t.Errorf("client should have recorded %d handshakes, but believes that %d have occured", expected, client.handshakes)
+ }
+ }()
+
+ if write && test.renegotiationExpectedToFail != i {
+ <-stdout.handshakeComplete
+ stdin <- opensslSendSentinel
+ }
+ <-signalChan
+ }
+
if test.validate != nil {
if err := test.validate(client.ConnectionState()); err != nil {
t.Errorf("validate callback returned error: %s", err)
}
}
- client.Close()
- clientConn.Close()
- doneChan <- true
}()
if !write {
@@ -357,14 +509,14 @@ func TestHandshakeClientAES256GCMSHA384(t *testing.T) {
}
func TestHandshakeClientCertRSA(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
config.Certificates = []Certificate{cert}
test := &clientTest{
name: "ClientCert-RSA-RSA",
command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
- config: &config,
+ config: config,
}
runClientTestTLS10(t, test)
@@ -373,7 +525,7 @@ func TestHandshakeClientCertRSA(t *testing.T) {
test = &clientTest{
name: "ClientCert-RSA-ECDSA",
command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
- config: &config,
+ config: config,
cert: testECDSACertificate,
key: testECDSAPrivateKey,
}
@@ -384,7 +536,7 @@ func TestHandshakeClientCertRSA(t *testing.T) {
test = &clientTest{
name: "ClientCert-RSA-AES256-GCM-SHA384",
command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384", "-verify", "1"},
- config: &config,
+ config: config,
cert: testRSACertificate,
key: testRSAPrivateKey,
}
@@ -393,14 +545,14 @@ func TestHandshakeClientCertRSA(t *testing.T) {
}
func TestHandshakeClientCertECDSA(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM))
config.Certificates = []Certificate{cert}
test := &clientTest{
name: "ClientCert-ECDSA-RSA",
command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
- config: &config,
+ config: config,
}
runClientTestTLS10(t, test)
@@ -409,7 +561,7 @@ func TestHandshakeClientCertECDSA(t *testing.T) {
test = &clientTest{
name: "ClientCert-ECDSA-ECDSA",
command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
- config: &config,
+ config: config,
cert: testECDSACertificate,
key: testECDSAPrivateKey,
}
@@ -448,7 +600,7 @@ func TestClientResumption(t *testing.T) {
t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
}
if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) {
- t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains)
+ t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifiedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains)
}
}
@@ -539,7 +691,7 @@ func TestLRUClientSessionCache(t *testing.T) {
}
func TestHandshakeClientALPNMatch(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.NextProtos = []string{"proto2", "proto1"}
test := &clientTest{
@@ -547,7 +699,7 @@ func TestHandshakeClientALPNMatch(t *testing.T) {
// Note that this needs OpenSSL 1.0.2 because that is the first
// version that supports the -alpn flag.
command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
- config: &config,
+ config: config,
validate: func(state ConnectionState) error {
// The server's preferences should override the client.
if state.NegotiatedProtocol != "proto1" {
@@ -560,7 +712,7 @@ func TestHandshakeClientALPNMatch(t *testing.T) {
}
func TestHandshakeClientALPNNoMatch(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.NextProtos = []string{"proto3"}
test := &clientTest{
@@ -568,7 +720,7 @@ func TestHandshakeClientALPNNoMatch(t *testing.T) {
// Note that this needs OpenSSL 1.0.2 because that is the first
// version that supports the -alpn flag.
command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
- config: &config,
+ config: config,
validate: func(state ConnectionState) error {
// There's no overlap so OpenSSL will not select a protocol.
if state.NegotiatedProtocol != "" {
@@ -584,7 +736,7 @@ func TestHandshakeClientALPNNoMatch(t *testing.T) {
const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0="
func TestHandshakClientSCTs(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
scts, err := base64.StdEncoding.DecodeString(sctsBase64)
if err != nil {
@@ -596,7 +748,7 @@ func TestHandshakClientSCTs(t *testing.T) {
// Note that this needs OpenSSL 1.0.2 because that is the first
// version that supports the -serverinfo flag.
command: []string{"openssl", "s_server"},
- config: &config,
+ config: config,
extensions: [][]byte{scts},
validate: func(state ConnectionState) error {
expectedSCTs := [][]byte{
@@ -618,14 +770,113 @@ func TestHandshakClientSCTs(t *testing.T) {
runClientTestTLS12(t, test)
}
-func TestNoIPAddressesInSNI(t *testing.T) {
- for _, ipLiteral := range []string{"1.2.3.4", "::1"} {
+func TestRenegotiationRejected(t *testing.T) {
+ config := testConfig.clone()
+ test := &clientTest{
+ name: "RenegotiationRejected",
+ command: []string{"openssl", "s_server", "-state"},
+ config: config,
+ numRenegotiations: 1,
+ renegotiationExpectedToFail: 1,
+ checkRenegotiationError: func(renegotiationNum int, err error) error {
+ if err == nil {
+ return errors.New("expected error from renegotiation but got nil")
+ }
+ if !strings.Contains(err.Error(), "no renegotiation") {
+ return fmt.Errorf("expected renegotiation to be rejected but got %q", err)
+ }
+ return nil
+ },
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestRenegotiateOnce(t *testing.T) {
+ config := testConfig.clone()
+ config.Renegotiation = RenegotiateOnceAsClient
+
+ test := &clientTest{
+ name: "RenegotiateOnce",
+ command: []string{"openssl", "s_server", "-state"},
+ config: config,
+ numRenegotiations: 1,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestRenegotiateTwice(t *testing.T) {
+ config := testConfig.clone()
+ config.Renegotiation = RenegotiateFreelyAsClient
+
+ test := &clientTest{
+ name: "RenegotiateTwice",
+ command: []string{"openssl", "s_server", "-state"},
+ config: config,
+ numRenegotiations: 2,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestRenegotiateTwiceRejected(t *testing.T) {
+ config := testConfig.clone()
+ config.Renegotiation = RenegotiateOnceAsClient
+
+ test := &clientTest{
+ name: "RenegotiateTwiceRejected",
+ command: []string{"openssl", "s_server", "-state"},
+ config: config,
+ numRenegotiations: 2,
+ renegotiationExpectedToFail: 2,
+ checkRenegotiationError: func(renegotiationNum int, err error) error {
+ if renegotiationNum == 1 {
+ return err
+ }
+
+ if err == nil {
+ return errors.New("expected error from renegotiation but got nil")
+ }
+ if !strings.Contains(err.Error(), "no renegotiation") {
+ return fmt.Errorf("expected renegotiation to be rejected but got %q", err)
+ }
+ return nil
+ },
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+var hostnameInSNITests = []struct {
+ in, out string
+}{
+ // Opaque string
+ {"", ""},
+ {"localhost", "localhost"},
+ {"foo, bar, baz and qux", "foo, bar, baz and qux"},
+
+ // DNS hostname
+ {"golang.org", "golang.org"},
+ {"golang.org.", "golang.org"},
+
+ // Literal IPv4 address
+ {"1.2.3.4", ""},
+
+ // Literal IPv6 address
+ {"::1", ""},
+ {"::1%lo0", ""}, // with zone identifier
+ {"[::1]", ""}, // as per RFC 5952 we allow the [] style as IPv6 literal
+ {"[::1%lo0]", ""},
+}
+
+func TestHostnameInSNI(t *testing.T) {
+ for _, tt := range hostnameInSNITests {
c, s := net.Pipe()
- go func() {
- client := Client(c, &Config{ServerName: ipLiteral})
- client.Handshake()
- }()
+ go func(host string) {
+ Client(c, &Config{ServerName: host, InsecureSkipVerify: true}).Handshake()
+ }(tt.in)
var header [5]byte
if _, err := io.ReadFull(s, header[:]); err != nil {
@@ -637,10 +888,20 @@ func TestNoIPAddressesInSNI(t *testing.T) {
if _, err := io.ReadFull(s, record[:]); err != nil {
t.Fatal(err)
}
+
+ c.Close()
s.Close()
- if bytes.Index(record, []byte(ipLiteral)) != -1 {
- t.Errorf("IP literal %q found in ClientHello: %x", ipLiteral, record)
+ var m clientHelloMsg
+ if !m.unmarshal(record) {
+ t.Errorf("unmarshaling ClientHello for %q failed", tt.in)
+ continue
+ }
+ if tt.in != tt.out && m.serverName == tt.in {
+ t.Errorf("prohibited %q found in ClientHello: %x", tt.in, record)
+ }
+ if m.serverName != tt.out {
+ t.Errorf("expected %q not found in ClientHello: %x", tt.out, record)
}
}
}
@@ -694,3 +955,93 @@ func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) {
t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
}
}
+
+// brokenConn wraps a net.Conn and causes all Writes after a certain number to
+// fail with brokenConnErr.
+type brokenConn struct {
+ net.Conn
+
+ // breakAfter is the number of successful writes that will be allowed
+ // before all subsequent writes fail.
+ breakAfter int
+
+ // numWrites is the number of writes that have been done.
+ numWrites int
+}
+
+// brokenConnErr is the error that brokenConn returns once exhausted.
+var brokenConnErr = errors.New("too many writes to brokenConn")
+
+func (b *brokenConn) Write(data []byte) (int, error) {
+ if b.numWrites >= b.breakAfter {
+ return 0, brokenConnErr
+ }
+
+ b.numWrites++
+ return b.Conn.Write(data)
+}
+
+func TestFailedWrite(t *testing.T) {
+ // Test that a write error during the handshake is returned.
+ for _, breakAfter := range []int{0, 1} {
+ c, s := net.Pipe()
+ done := make(chan bool)
+
+ go func() {
+ Server(s, testConfig).Handshake()
+ s.Close()
+ done <- true
+ }()
+
+ brokenC := &brokenConn{Conn: c, breakAfter: breakAfter}
+ err := Client(brokenC, testConfig).Handshake()
+ if err != brokenConnErr {
+ t.Errorf("#%d: expected error from brokenConn but got %q", breakAfter, err)
+ }
+ brokenC.Close()
+
+ <-done
+ }
+}
+
+// writeCountingConn wraps a net.Conn and counts the number of Write calls.
+type writeCountingConn struct {
+ net.Conn
+
+ // numWrites is the number of writes that have been done.
+ numWrites int
+}
+
+func (wcc *writeCountingConn) Write(data []byte) (int, error) {
+ wcc.numWrites++
+ return wcc.Conn.Write(data)
+}
+
+func TestBuffering(t *testing.T) {
+ c, s := net.Pipe()
+ done := make(chan bool)
+
+ clientWCC := &writeCountingConn{Conn: c}
+ serverWCC := &writeCountingConn{Conn: s}
+
+ go func() {
+ Server(serverWCC, testConfig).Handshake()
+ serverWCC.Close()
+ done <- true
+ }()
+
+ err := Client(clientWCC, testConfig).Handshake()
+ if err != nil {
+ t.Fatal(err)
+ }
+ clientWCC.Close()
+ <-done
+
+ if n := clientWCC.numWrites; n != 2 {
+ t.Errorf("expected client handshake to complete with only two writes, but saw %d", n)
+ }
+
+ if n := serverWCC.numWrites; n != 2 {
+ t.Errorf("expected server handshake to complete with only two writes, but saw %d", n)
+ }
+}
diff --git a/libgo/go/crypto/tls/handshake_messages.go b/libgo/go/crypto/tls/handshake_messages.go
index 111ce53..ab8e60a 100644
--- a/libgo/go/crypto/tls/handshake_messages.go
+++ b/libgo/go/crypto/tls/handshake_messages.go
@@ -7,23 +7,24 @@ package tls
import "bytes"
type clientHelloMsg struct {
- raw []byte
- vers uint16
- random []byte
- sessionId []byte
- cipherSuites []uint16
- compressionMethods []uint8
- nextProtoNeg bool
- serverName string
- ocspStapling bool
- scts bool
- supportedCurves []CurveID
- supportedPoints []uint8
- ticketSupported bool
- sessionTicket []uint8
- signatureAndHashes []signatureAndHash
- secureRenegotiation bool
- alpnProtocols []string
+ raw []byte
+ vers uint16
+ random []byte
+ sessionId []byte
+ cipherSuites []uint16
+ compressionMethods []uint8
+ nextProtoNeg bool
+ serverName string
+ ocspStapling bool
+ scts bool
+ supportedCurves []CurveID
+ supportedPoints []uint8
+ ticketSupported bool
+ sessionTicket []uint8
+ signatureAndHashes []signatureAndHash
+ secureRenegotiation []byte
+ secureRenegotiationSupported bool
+ alpnProtocols []string
}
func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -47,7 +48,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
m.ticketSupported == m1.ticketSupported &&
bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
- m.secureRenegotiation == m1.secureRenegotiation &&
+ m.secureRenegotiationSupported == m1.secureRenegotiationSupported &&
+ bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
eqStrings(m.alpnProtocols, m1.alpnProtocols)
}
@@ -86,8 +88,8 @@ func (m *clientHelloMsg) marshal() []byte {
extensionsLength += 2 + 2*len(m.signatureAndHashes)
numExtensions++
}
- if m.secureRenegotiation {
- extensionsLength += 1
+ if m.secureRenegotiationSupported {
+ extensionsLength += 1 + len(m.secureRenegotiation)
numExtensions++
}
if len(m.alpnProtocols) > 0 {
@@ -214,7 +216,7 @@ func (m *clientHelloMsg) marshal() []byte {
z[4] = byte(l)
z = z[5:]
for _, pointFormat := range m.supportedPoints {
- z[0] = byte(pointFormat)
+ z[0] = pointFormat
z = z[1:]
}
}
@@ -248,12 +250,15 @@ func (m *clientHelloMsg) marshal() []byte {
z = z[2:]
}
}
- if m.secureRenegotiation {
+ if m.secureRenegotiationSupported {
z[0] = byte(extensionRenegotiationInfo >> 8)
z[1] = byte(extensionRenegotiationInfo & 0xff)
z[2] = 0
- z[3] = 1
+ z[3] = byte(len(m.secureRenegotiation) + 1)
+ z[4] = byte(len(m.secureRenegotiation))
z = z[5:]
+ copy(z, m.secureRenegotiation)
+ z = z[len(m.secureRenegotiation):]
}
if len(m.alpnProtocols) > 0 {
z[0] = byte(extensionALPN >> 8)
@@ -316,7 +321,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
for i := 0; i < numCipherSuites; i++ {
m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
if m.cipherSuites[i] == scsvRenegotiation {
- m.secureRenegotiation = true
+ m.secureRenegotiationSupported = true
}
}
data = data[2+cipherSuiteLen:]
@@ -448,10 +453,18 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
d = d[2:]
}
case extensionRenegotiationInfo:
- if length != 1 || data[0] != 0 {
+ if length == 0 {
+ return false
+ }
+ d := data[:length]
+ l := int(d[0])
+ d = d[1:]
+ if l != len(d) {
return false
}
- m.secureRenegotiation = true
+
+ m.secureRenegotiation = d
+ m.secureRenegotiationSupported = true
case extensionALPN:
if length < 2 {
return false
@@ -483,19 +496,20 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
}
type serverHelloMsg struct {
- raw []byte
- vers uint16
- random []byte
- sessionId []byte
- cipherSuite uint16
- compressionMethod uint8
- nextProtoNeg bool
- nextProtos []string
- ocspStapling bool
- scts [][]byte
- ticketSupported bool
- secureRenegotiation bool
- alpnProtocol string
+ raw []byte
+ vers uint16
+ random []byte
+ sessionId []byte
+ cipherSuite uint16
+ compressionMethod uint8
+ nextProtoNeg bool
+ nextProtos []string
+ ocspStapling bool
+ scts [][]byte
+ ticketSupported bool
+ secureRenegotiation []byte
+ secureRenegotiationSupported bool
+ alpnProtocol string
}
func (m *serverHelloMsg) equal(i interface{}) bool {
@@ -523,7 +537,8 @@ func (m *serverHelloMsg) equal(i interface{}) bool {
eqStrings(m.nextProtos, m1.nextProtos) &&
m.ocspStapling == m1.ocspStapling &&
m.ticketSupported == m1.ticketSupported &&
- m.secureRenegotiation == m1.secureRenegotiation &&
+ m.secureRenegotiationSupported == m1.secureRenegotiationSupported &&
+ bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
m.alpnProtocol == m1.alpnProtocol
}
@@ -551,8 +566,8 @@ func (m *serverHelloMsg) marshal() []byte {
if m.ticketSupported {
numExtensions++
}
- if m.secureRenegotiation {
- extensionsLength += 1
+ if m.secureRenegotiationSupported {
+ extensionsLength += 1 + len(m.secureRenegotiation)
numExtensions++
}
if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
@@ -589,7 +604,7 @@ func (m *serverHelloMsg) marshal() []byte {
z := x[39+len(m.sessionId):]
z[0] = uint8(m.cipherSuite >> 8)
z[1] = uint8(m.cipherSuite)
- z[2] = uint8(m.compressionMethod)
+ z[2] = m.compressionMethod
z = z[3:]
if numExtensions > 0 {
@@ -624,12 +639,15 @@ func (m *serverHelloMsg) marshal() []byte {
z[1] = byte(extensionSessionTicket)
z = z[4:]
}
- if m.secureRenegotiation {
+ if m.secureRenegotiationSupported {
z[0] = byte(extensionRenegotiationInfo >> 8)
z[1] = byte(extensionRenegotiationInfo & 0xff)
z[2] = 0
- z[3] = 1
+ z[3] = byte(len(m.secureRenegotiation) + 1)
+ z[4] = byte(len(m.secureRenegotiation))
z = z[5:]
+ copy(z, m.secureRenegotiation)
+ z = z[len(m.secureRenegotiation):]
}
if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
z[0] = byte(extensionALPN >> 8)
@@ -744,10 +762,18 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
}
m.ticketSupported = true
case extensionRenegotiationInfo:
- if length != 1 || data[0] != 0 {
+ if length == 0 {
+ return false
+ }
+ d := data[:length]
+ l := int(d[0])
+ d = d[1:]
+ if l != len(d) {
return false
}
- m.secureRenegotiation = true
+
+ m.secureRenegotiation = d
+ m.secureRenegotiationSupported = true
case extensionALPN:
d := data[:length]
if len(d) < 3 {
@@ -1316,11 +1342,8 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool {
m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
cas = cas[caLen:]
}
- if len(data) > 0 {
- return false
- }
- return true
+ return len(data) == 0
}
type certificateVerifyMsg struct {
@@ -1466,6 +1489,17 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
return true
}
+type helloRequestMsg struct {
+}
+
+func (*helloRequestMsg) marshal() []byte {
+ return []byte{typeHelloRequest, 0, 0, 0}
+}
+
+func (*helloRequestMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
func eqUint16s(x, y []uint16) bool {
if len(x) != len(y) {
return false
diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go
index e16cddcb..1aac729 100644
--- a/libgo/go/crypto/tls/handshake_server.go
+++ b/libgo/go/crypto/tls/handshake_server.go
@@ -35,6 +35,7 @@ type serverHandshakeState struct {
}
// serverHandshake performs a TLS handshake as a server.
+// c.out.Mutex <= L; c.handshakeMutex <= L.
func (c *Conn) serverHandshake() error {
config := c.config
@@ -51,6 +52,7 @@ func (c *Conn) serverHandshake() error {
}
// For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
+ c.buffering = true
if isResume {
// The client has included a session ticket and so we do an abbreviated handshake.
if err := hs.doResumeHandshake(); err != nil {
@@ -67,9 +69,13 @@ func (c *Conn) serverHandshake() error {
return err
}
}
- if err := hs.sendFinished(c.firstFinished[:]); err != nil {
+ if err := hs.sendFinished(c.serverFinished[:]); err != nil {
return err
}
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = false
if err := hs.readFinished(nil); err != nil {
return err
}
@@ -83,15 +89,20 @@ func (c *Conn) serverHandshake() error {
if err := hs.establishKeys(); err != nil {
return err
}
- if err := hs.readFinished(c.firstFinished[:]); err != nil {
+ if err := hs.readFinished(c.clientFinished[:]); err != nil {
return err
}
+ c.clientFinishedIsFirst = true
+ c.buffering = true
if err := hs.sendSessionTicket(); err != nil {
return err
}
if err := hs.sendFinished(nil); err != nil {
return err
}
+ if _, err := c.flush(); err != nil {
+ return err
+ }
}
c.handshakeComplete = true
@@ -165,7 +176,13 @@ Curves:
c.sendAlert(alertInternalError)
return false, err
}
- hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
+
+ if len(hs.clientHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+
+ hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
hs.hello.compressionMethod = compressionNone
if len(hs.clientHello.serverName) > 0 {
c.serverName = hs.clientHello.serverName
@@ -187,12 +204,13 @@ Curves:
}
}
- if hs.cert, err = config.getCertificate(&ClientHelloInfo{
+ hs.cert, err = config.getCertificate(&ClientHelloInfo{
CipherSuites: hs.clientHello.cipherSuites,
ServerName: hs.clientHello.serverName,
SupportedCurves: hs.clientHello.supportedCurves,
SupportedPoints: hs.clientHello.supportedPoints,
- }); err != nil {
+ })
+ if err != nil {
c.sendAlert(alertInternalError)
return false, err
}
@@ -208,7 +226,7 @@ Curves:
hs.rsaSignOk = true
default:
c.sendAlert(alertInternalError)
- return false, fmt.Errorf("crypto/tls: unsupported signing key type (%T)", priv.Public())
+ return false, fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
}
}
if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
@@ -217,7 +235,7 @@ Curves:
hs.rsaDecryptOk = true
default:
c.sendAlert(alertInternalError)
- return false, fmt.Errorf("crypto/tls: unsupported decryption key type (%T)", priv.Public())
+ return false, fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
}
}
@@ -245,7 +263,7 @@ Curves:
return false, errors.New("tls: no cipher suite supported by both client and server")
}
- // See https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00.
+ // See https://tools.ietf.org/html/rfc7507.
for _, id := range hs.clientHello.cipherSuites {
if id == TLS_FALLBACK_SCSV {
// The client is doing a fallback connection.
@@ -274,10 +292,8 @@ func (hs *serverHandshakeState) checkForResumption() bool {
return false
}
- if hs.sessionState.vers > hs.clientHello.vers {
- return false
- }
- if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers {
+ // Never resume a session for a different TLS version.
+ if c.vers != hs.sessionState.vers {
return false
}
@@ -322,7 +338,9 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
hs.finishedHash.discardHandshakeBuffer()
hs.finishedHash.Write(hs.clientHello.marshal())
hs.finishedHash.Write(hs.hello.marshal())
- c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
+ return err
+ }
if len(hs.sessionState.certificates) > 0 {
if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
@@ -354,19 +372,25 @@ func (hs *serverHandshakeState) doFullHandshake() error {
}
hs.finishedHash.Write(hs.clientHello.marshal())
hs.finishedHash.Write(hs.hello.marshal())
- c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
+ return err
+ }
certMsg := new(certificateMsg)
certMsg.certificates = hs.cert.Certificate
hs.finishedHash.Write(certMsg.marshal())
- c.writeRecord(recordTypeHandshake, certMsg.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
+ return err
+ }
if hs.hello.ocspStapling {
certStatus := new(certificateStatusMsg)
certStatus.statusType = statusTypeOCSP
certStatus.response = hs.cert.OCSPStaple
hs.finishedHash.Write(certStatus.marshal())
- c.writeRecord(recordTypeHandshake, certStatus.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
+ return err
+ }
}
keyAgreement := hs.suite.ka(c.vers)
@@ -377,7 +401,9 @@ func (hs *serverHandshakeState) doFullHandshake() error {
}
if skx != nil {
hs.finishedHash.Write(skx.marshal())
- c.writeRecord(recordTypeHandshake, skx.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
+ return err
+ }
}
if config.ClientAuth >= RequestClientCert {
@@ -401,12 +427,20 @@ func (hs *serverHandshakeState) doFullHandshake() error {
certReq.certificateAuthorities = config.ClientCAs.Subjects()
}
hs.finishedHash.Write(certReq.marshal())
- c.writeRecord(recordTypeHandshake, certReq.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
+ return err
+ }
}
helloDone := new(serverHelloDoneMsg)
hs.finishedHash.Write(helloDone.marshal())
- c.writeRecord(recordTypeHandshake, helloDone.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
+ return err
+ }
+
+ if _, err := c.flush(); err != nil {
+ return err
+ }
var pub crypto.PublicKey // public key for client auth, if any
@@ -462,7 +496,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
// If we received a client cert in response to our certificate request message,
// the client will send us a certificateVerifyMsg immediately after the
- // clientKeyExchangeMsg. This message is a digest of all preceding
+ // clientKeyExchangeMsg. This message is a digest of all preceding
// handshake-layer messages that is signed using the private key corresponding
// to the client's certificate. This allows us to verify that the client is in
// possession of the private key of the certificate.
@@ -499,7 +533,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
switch key := pub.(type) {
case *ecdsa.PublicKey:
if signatureAndHash.signature != signatureECDSA {
- err = errors.New("bad signature type for client's ECDSA certificate")
+ err = errors.New("tls: bad signature type for client's ECDSA certificate")
break
}
ecdsaSig := new(ecdsaSignature)
@@ -507,7 +541,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
break
}
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
- err = errors.New("ECDSA signature contained zero or negative values")
+ err = errors.New("tls: ECDSA signature contained zero or negative values")
break
}
var digest []byte
@@ -515,11 +549,11 @@ func (hs *serverHandshakeState) doFullHandshake() error {
break
}
if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
- err = errors.New("ECDSA verification failure")
+ err = errors.New("tls: ECDSA verification failure")
}
case *rsa.PublicKey:
if signatureAndHash.signature != signatureRSA {
- err = errors.New("bad signature type for client's RSA certificate")
+ err = errors.New("tls: bad signature type for client's RSA certificate")
break
}
var digest []byte
@@ -571,8 +605,8 @@ func (hs *serverHandshakeState) readFinished(out []byte) error {
c := hs.c
c.readRecord(recordTypeChangeCipherSpec)
- if err := c.in.error(); err != nil {
- return err
+ if c.in.err != nil {
+ return c.in.err
}
if hs.hello.nextProtoNeg {
@@ -632,7 +666,9 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
}
hs.finishedHash.Write(m.marshal())
- c.writeRecord(recordTypeHandshake, m.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
+ return err
+ }
return nil
}
@@ -640,12 +676,16 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
func (hs *serverHandshakeState) sendFinished(out []byte) error {
c := hs.c
- c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
+ return err
+ }
finished := new(finishedMsg)
finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
hs.finishedHash.Write(finished.marshal())
- c.writeRecord(recordTypeHandshake, finished.marshal())
+ if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
+ return err
+ }
c.cipherSuite = hs.suite.id
copy(out, finished.verifyData)
@@ -690,20 +730,20 @@ func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (c
c.verifiedChains = chains
}
- if len(certs) > 0 {
- var pub crypto.PublicKey
- switch key := certs[0].PublicKey.(type) {
- case *ecdsa.PublicKey, *rsa.PublicKey:
- pub = key
- default:
- c.sendAlert(alertUnsupportedCertificate)
- return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
- }
- c.peerCertificates = certs
- return pub, nil
+ if len(certs) == 0 {
+ return nil, nil
}
- return nil, nil
+ var pub crypto.PublicKey
+ switch key := certs[0].PublicKey.(type) {
+ case *ecdsa.PublicKey, *rsa.PublicKey:
+ pub = key
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
+ }
+ c.peerCertificates = certs
+ return pub, nil
}
// setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState
diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go
index 438fb314..9ae5d11fc 100644
--- a/libgo/go/crypto/tls/handshake_server_test.go
+++ b/libgo/go/crypto/tls/handshake_server_test.go
@@ -69,7 +69,7 @@ func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) {
// Create in-memory network connection,
- // send message to server. Should return
+ // send message to server. Should return
// expected error.
c, s := net.Pipe()
go func() {
@@ -80,7 +80,10 @@ func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessa
cli.writeRecord(recordTypeHandshake, m.marshal())
c.Close()
}()
- err := Server(s, serverConfig).Handshake()
+ hs := serverHandshakeState{
+ c: Server(s, serverConfig),
+ }
+ _, err := hs.readClientHello()
s.Close()
if len(expectedSubStr) == 0 {
if err != nil && err != io.EOF {
@@ -105,16 +108,16 @@ func TestRejectBadProtocolVersion(t *testing.T) {
func TestNoSuiteOverlap(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{0xff00},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
}
testClientHelloFailure(t, testConfig, clientHello, "no cipher suite supported by both client and server")
}
func TestNoCompressionOverlap(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
compressionMethods: []uint8{0xff},
}
@@ -123,56 +126,56 @@ func TestNoCompressionOverlap(t *testing.T) {
func TestNoRC4ByDefault(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
}
- serverConfig := *testConfig
+ serverConfig := testConfig.clone()
// Reset the enabled cipher suites to nil in order to test the
// defaults.
serverConfig.CipherSuites = nil
- testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
+ testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
}
func TestDontSelectECDSAWithRSAKey(t *testing.T) {
// Test that, even when both sides support an ECDSA cipher suite, it
// won't be selected if the server's private key doesn't support it.
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
supportedCurves: []CurveID{CurveP256},
supportedPoints: []uint8{pointFormatUncompressed},
}
- serverConfig := *testConfig
+ serverConfig := testConfig.clone()
serverConfig.CipherSuites = clientHello.cipherSuites
serverConfig.Certificates = make([]Certificate, 1)
serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
serverConfig.BuildNameToCertificate()
// First test that it *does* work when the server's key is ECDSA.
- testClientHello(t, &serverConfig, clientHello)
+ testClientHello(t, serverConfig, clientHello)
// Now test that switching to an RSA key causes the expected error (and
// not an internal error about a signing failure).
serverConfig.Certificates = testConfig.Certificates
- testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
+ testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
}
func TestDontSelectRSAWithECDSAKey(t *testing.T) {
// Test that, even when both sides support an RSA cipher suite, it
// won't be selected if the server's private key doesn't support it.
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
supportedCurves: []CurveID{CurveP256},
supportedPoints: []uint8{pointFormatUncompressed},
}
- serverConfig := *testConfig
+ serverConfig := testConfig.clone()
serverConfig.CipherSuites = clientHello.cipherSuites
// First test that it *does* work when the server's key is RSA.
- testClientHello(t, &serverConfig, clientHello)
+ testClientHello(t, serverConfig, clientHello)
// Now test that switching to an ECDSA key causes the expected error
// (and not an internal error about a signing failure).
@@ -180,16 +183,16 @@ func TestDontSelectRSAWithECDSAKey(t *testing.T) {
serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
serverConfig.BuildNameToCertificate()
- testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
+ testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
}
func TestRenegotiationExtension(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: VersionTLS12,
- compressionMethods: []uint8{compressionNone},
- random: make([]byte, 32),
- secureRenegotiation: true,
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ vers: VersionTLS12,
+ compressionMethods: []uint8{compressionNone},
+ random: make([]byte, 32),
+ secureRenegotiationSupported: true,
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
}
var buf []byte
@@ -226,7 +229,7 @@ func TestRenegotiationExtension(t *testing.T) {
t.Fatalf("Failed to parse ServerHello")
}
- if !serverHello.secureRenegotiation {
+ if !serverHello.secureRenegotiationSupported {
t.Errorf("Secure renegotiation extension was not echoed.")
}
}
@@ -262,9 +265,9 @@ func TestTLS12OnlyCipherSuites(t *testing.T) {
reply, clientErr = cli.readHandshake()
c.Close()
}()
- config := *testConfig
+ config := testConfig.clone()
config.CipherSuites = clientHello.cipherSuites
- Server(s, &config).Handshake()
+ Server(s, config).Handshake()
s.Close()
if clientErr != nil {
t.Fatal(clientErr)
@@ -396,6 +399,64 @@ func TestSCTHandshake(t *testing.T) {
}
}
+func TestCrossVersionResume(t *testing.T) {
+ serverConfig := &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ Certificates: testConfig.Certificates,
+ }
+ clientConfig := &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ InsecureSkipVerify: true,
+ ClientSessionCache: NewLRUClientSessionCache(1),
+ ServerName: "servername",
+ }
+
+ // Establish a session at TLS 1.1.
+ clientConfig.MaxVersion = VersionTLS11
+ _, _, err := testHandshake(clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+
+ // The client session cache now contains a TLS 1.1 session.
+ state, _, err := testHandshake(clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !state.DidResume {
+ t.Fatalf("handshake did not resume at the same version")
+ }
+
+ // Test that the server will decline to resume at a lower version.
+ clientConfig.MaxVersion = VersionTLS10
+ state, _, err = testHandshake(clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if state.DidResume {
+ t.Fatalf("handshake resumed at a lower version")
+ }
+
+ // The client session cache now contains a TLS 1.0 session.
+ state, _, err = testHandshake(clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !state.DidResume {
+ t.Fatalf("handshake did not resume at the same version")
+ }
+
+ // Test that the server will decline to resume at a higher version.
+ clientConfig.MaxVersion = VersionTLS11
+ state, _, err = testHandshake(clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if state.DidResume {
+ t.Fatalf("handshake resumed at a higher version")
+ }
+}
+
// Note: see comment in handshake_test.go for details of how the reference
// tests work.
@@ -518,16 +579,17 @@ func (test *serverTest) run(t *testing.T, write bool) {
server := Server(serverConn, config)
connStateChan := make(chan ConnectionState, 1)
go func() {
- var err error
- if _, err = server.Write([]byte("hello, world\n")); err != nil {
- t.Logf("Error from Server.Write: %s", err)
- }
+ _, err := server.Write([]byte("hello, world\n"))
if len(test.expectHandshakeErrorIncluding) > 0 {
if err == nil {
t.Errorf("Error expected, but no error returned")
} else if s := err.Error(); !strings.Contains(s, test.expectHandshakeErrorIncluding) {
t.Errorf("Error expected containing '%s' but got '%s'", test.expectHandshakeErrorIncluding, s)
}
+ } else {
+ if err != nil {
+ t.Logf("Error from Server.Write: '%s'", err)
+ }
}
server.Close()
serverConn.Close()
@@ -670,7 +732,7 @@ func TestHandshakeServerAES256GCMSHA384(t *testing.T) {
}
func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.Certificates = make([]Certificate, 1)
config.Certificates[0].Certificate = [][]byte{testECDSACertificate}
config.Certificates[0].PrivateKey = testECDSAPrivateKey
@@ -679,14 +741,14 @@ func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
test := &serverTest{
name: "ECDHE-ECDSA-AES",
command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA"},
- config: &config,
+ config: config,
}
runServerTestTLS10(t, test)
runServerTestTLS12(t, test)
}
func TestHandshakeServerALPN(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.NextProtos = []string{"proto1", "proto2"}
test := &serverTest{
@@ -694,7 +756,7 @@ func TestHandshakeServerALPN(t *testing.T) {
// 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", "proto2,proto1"},
- config: &config,
+ config: config,
validate: func(state ConnectionState) error {
// The server's preferences should override the client.
if state.NegotiatedProtocol != "proto1" {
@@ -707,7 +769,7 @@ func TestHandshakeServerALPN(t *testing.T) {
}
func TestHandshakeServerALPNNoMatch(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.NextProtos = []string{"proto3"}
test := &serverTest{
@@ -715,7 +777,7 @@ func TestHandshakeServerALPNNoMatch(t *testing.T) {
// 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", "proto2,proto1"},
- config: &config,
+ config: config,
validate: func(state ConnectionState) error {
// Rather than reject the connection, Go doesn't select
// a protocol when there is no overlap.
@@ -742,7 +804,7 @@ func TestHandshakeServerSNI(t *testing.T) {
// TestHandshakeServerSNICertForName is similar to TestHandshakeServerSNI, but
// tests the dynamic GetCertificate method
func TestHandshakeServerSNIGetCertificate(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
// Replace the NameToCertificate map with a GetCertificate function
nameToCert := config.NameToCertificate
@@ -754,7 +816,7 @@ func TestHandshakeServerSNIGetCertificate(t *testing.T) {
test := &serverTest{
name: "SNI-GetCertificate",
command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
}
@@ -764,7 +826,7 @@ func TestHandshakeServerSNIGetCertificate(t *testing.T) {
// GetCertificate method doesn't return a cert, we fall back to what's in
// the NameToCertificate map.
func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
return nil, nil
@@ -772,7 +834,7 @@ func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) {
test := &serverTest{
name: "SNI-GetCertificateNotFound",
command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
}
@@ -782,18 +844,18 @@ func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) {
func TestHandshakeServerSNIGetCertificateError(t *testing.T) {
const errMsg = "TestHandshakeServerSNIGetCertificateError error"
- serverConfig := *testConfig
+ serverConfig := testConfig.clone()
serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
return nil, errors.New(errMsg)
}
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
serverName: "test",
}
- testClientHelloFailure(t, &serverConfig, clientHello, errMsg)
+ testClientHelloFailure(t, serverConfig, clientHello, errMsg)
}
// TestHandshakeServerEmptyCertificates tests that GetCertificates is called in
@@ -801,45 +863,45 @@ func TestHandshakeServerSNIGetCertificateError(t *testing.T) {
func TestHandshakeServerEmptyCertificates(t *testing.T) {
const errMsg = "TestHandshakeServerEmptyCertificates error"
- serverConfig := *testConfig
+ serverConfig := testConfig.clone()
serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
return nil, errors.New(errMsg)
}
serverConfig.Certificates = nil
clientHello := &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
}
- testClientHelloFailure(t, &serverConfig, clientHello, errMsg)
+ testClientHelloFailure(t, serverConfig, clientHello, errMsg)
// With an empty Certificates and a nil GetCertificate, the server
// should always return a “no certificates” error.
serverConfig.GetCertificate = nil
clientHello = &clientHelloMsg{
- vers: 0x0301,
+ vers: VersionTLS10,
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- compressionMethods: []uint8{0},
+ compressionMethods: []uint8{compressionNone},
}
- testClientHelloFailure(t, &serverConfig, clientHello, "no certificates")
+ testClientHelloFailure(t, serverConfig, clientHello, "no certificates")
}
// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate.
func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
- config := *testConfig
+ config := testConfig.clone()
config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}
config.PreferServerCipherSuites = true
test := &serverTest{
name: "CipherSuiteCertPreferenceRSA",
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
- config = *testConfig
+ config = testConfig.clone()
config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}
config.Certificates = []Certificate{
{
@@ -852,7 +914,7 @@ func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
test = &serverTest{
name: "CipherSuiteCertPreferenceECDSA",
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
}
@@ -878,12 +940,12 @@ func TestResumptionDisabled(t *testing.T) {
sessionFilePath := tempFile("")
defer os.Remove(sessionFilePath)
- config := *testConfig
+ config := testConfig.clone()
test := &serverTest{
name: "IssueTicketPreDisable",
command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath},
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
@@ -892,7 +954,7 @@ func TestResumptionDisabled(t *testing.T) {
test = &serverTest{
name: "ResumeDisabled",
command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath},
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
@@ -901,12 +963,12 @@ func TestResumptionDisabled(t *testing.T) {
}
func TestFallbackSCSV(t *testing.T) {
- serverConfig := &Config{
+ serverConfig := Config{
Certificates: testConfig.Certificates,
}
test := &serverTest{
name: "FallbackSCSV",
- config: serverConfig,
+ config: &serverConfig,
// OpenSSL 1.0.1j is needed for the -fallback_scsv option.
command: []string{"openssl", "s_client", "-fallback_scsv"},
expectHandshakeErrorIncluding: "inappropriate protocol fallback",
@@ -991,20 +1053,20 @@ func TestClientAuth(t *testing.T) {
defer os.Remove(ecdsaKeyPath)
}
- config := *testConfig
+ config := testConfig.clone()
config.ClientAuth = RequestClientCert
test := &serverTest{
name: "ClientAuthRequestedNotGiven",
command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
- config: &config,
+ config: config,
}
runServerTestTLS12(t, test)
test = &serverTest{
name: "ClientAuthRequestedAndGiven",
command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", certPath, "-key", keyPath},
- config: &config,
+ config: config,
expectedPeerCerts: []string{clientCertificatePEM},
}
runServerTestTLS12(t, test)
@@ -1012,7 +1074,7 @@ func TestClientAuth(t *testing.T) {
test = &serverTest{
name: "ClientAuthRequestedAndECDSAGiven",
command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", ecdsaCertPath, "-key", ecdsaKeyPath},
- config: &config,
+ config: config,
expectedPeerCerts: []string{clientECDSACertificatePEM},
}
runServerTestTLS12(t, test)
diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go
index 0e6a7c2..467efb2 100644
--- a/libgo/go/crypto/tls/key_agreement.go
+++ b/libgo/go/crypto/tls/key_agreement.go
@@ -51,7 +51,7 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi
if err != nil {
return nil, err
}
- // We don't check the version number in the premaster secret. For one,
+ // We don't check the version number in the premaster secret. For one,
// by checking it, we would leak information about the validity of the
// encrypted pre-master secret. Secondly, it provides only a small
// benefit against a downgrade attack and some implementations send the
@@ -242,19 +242,19 @@ NextCandidate:
case signatureECDSA:
_, ok := priv.Public().(*ecdsa.PublicKey)
if !ok {
- return nil, errors.New("ECDHE ECDSA requires an ECDSA server key")
+ return nil, errors.New("tls: ECDHE ECDSA requires an ECDSA server key")
}
case signatureRSA:
_, ok := priv.Public().(*rsa.PublicKey)
if !ok {
- return nil, errors.New("ECDHE RSA requires a RSA server key")
+ return nil, errors.New("tls: ECDHE RSA requires a RSA server key")
}
default:
- return nil, errors.New("unknown ECDHE signature algorithm")
+ return nil, errors.New("tls: unknown ECDHE signature algorithm")
}
sig, err = priv.Sign(config.rand(), digest, hashFunc)
if err != nil {
- return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+ return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
}
skx := new(serverKeyExchangeMsg)
@@ -354,28 +354,28 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
case signatureECDSA:
pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
if !ok {
- return errors.New("ECDHE ECDSA requires a ECDSA server public key")
+ return errors.New("tls: ECDHE ECDSA requires a ECDSA server public key")
}
ecdsaSig := new(ecdsaSignature)
if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
return err
}
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
- return errors.New("ECDSA signature contained zero or negative values")
+ return errors.New("tls: ECDSA signature contained zero or negative values")
}
if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
- return errors.New("ECDSA verification failure")
+ return errors.New("tls: ECDSA verification failure")
}
case signatureRSA:
pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
if !ok {
- return errors.New("ECDHE RSA requires a RSA server public key")
+ return errors.New("tls: ECDHE RSA requires a RSA server public key")
}
if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
return err
}
default:
- return errors.New("unknown ECDHE signature algorithm")
+ return errors.New("tls: unknown ECDHE signature algorithm")
}
return nil
@@ -383,7 +383,7 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
if ka.curve == nil {
- return nil, nil, errors.New("missing ServerKeyExchange message")
+ return nil, nil, errors.New("tls: missing ServerKeyExchange message")
}
priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
if err != nil {
diff --git a/libgo/go/crypto/tls/prf.go b/libgo/go/crypto/tls/prf.go
index 747b817..5833fc1 100644
--- a/libgo/go/crypto/tls/prf.go
+++ b/libgo/go/crypto/tls/prf.go
@@ -85,7 +85,7 @@ func prf30(result, secret, label, seed []byte) {
done := 0
i := 0
- // RFC5246 section 6.3 says that the largest PRF output needed is 128
+ // RFC 5246 section 6.3 says that the largest PRF output needed is 128
// bytes. Since no more ciphersuites will be added to SSLv3, this will
// remain true. Each iteration gives us 16 bytes so 10 iterations will
// be sufficient.
diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
new file mode 100644
index 0000000..00d35f4
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
@@ -0,0 +1,251 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 00 00 00 00 00 |................|
+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 22 c0 2f |............."./|
+00000030 c0 2b c0 30 c0 2c c0 11 c0 07 c0 13 c0 09 c0 14 |.+.0.,..........|
+00000040 c0 0a 00 9c 00 9d 00 05 00 2f 00 35 c0 12 00 0a |........./.5....|
+00000050 01 00 00 36 00 05 00 05 01 00 00 00 00 00 0a 00 |...6............|
+00000060 08 00 06 00 17 00 18 00 19 00 0b 00 02 01 00 00 |................|
+00000070 0d 00 0e 00 0c 04 01 04 03 05 01 05 03 02 01 02 |................|
+00000080 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 fa 71 0e 3c 35 |....Y...U...q.<5|
+00000010 33 cc 51 25 19 cf fe c4 ef c8 2d ec 88 75 a9 1c |3.Q%......-..u..|
+00000020 6a e4 f3 b4 3d fd 74 cc e1 71 71 20 de 14 e5 21 |j...=.t..qq ...!|
+00000030 84 17 62 62 4f 44 e7 c2 d6 00 07 d2 63 f8 b0 32 |..bbOD......c..2|
+00000040 e0 12 d3 cb 69 1f d8 ed 5d 43 89 86 c0 2f 00 00 |....i...]C.../..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 71 0b 00 02 6d 00 02 6a 00 02 67 30 82 02 |..q...m..j..g0..|
+00000070 63 30 82 01 cc a0 03 02 01 02 02 09 00 a2 73 00 |c0............s.|
+00000080 0c 81 00 cb f3 30 0d 06 09 2a 86 48 86 f7 0d 01 |.....0...*.H....|
+00000090 01 0b 05 00 30 2b 31 17 30 15 06 03 55 04 0a 13 |....0+1.0...U...|
+000000a0 0e 47 6f 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 |.Google TESTING1|
+000000b0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000c0 74 30 1e 17 0d 31 35 30 31 30 31 30 30 30 30 30 |t0...15010100000|
+000000d0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000e0 5a 30 26 31 17 30 15 06 03 55 04 0a 13 0e 47 6f |Z0&1.0...U....Go|
+000000f0 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 0b 30 09 |ogle TESTING1.0.|
+00000100 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+00000110 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000120 81 89 02 81 81 00 af 87 88 f6 20 1b 95 65 6c 14 |.......... ..el.|
+00000130 ab 44 05 af 3b 45 14 e3 b7 6d fd 00 63 4d 95 7f |.D..;E...m..cM..|
+00000140 fe 6a 62 35 86 c0 4a f9 18 7c f6 aa 25 5e 7a 64 |.jb5..J..|..%^zd|
+00000150 31 66 00 ba f4 8e 92 af c7 6b d8 76 d4 f3 5f 41 |1f.......k.v.._A|
+00000160 cb 6e 56 15 97 1b 97 c1 3c 12 39 21 66 3d 2b 16 |.nV.....<.9!f=+.|
+00000170 d1 bc db 1c c0 a7 da b7 ca ad ba da cb d5 21 50 |..............!P|
+00000180 ec de 8d ab d1 6b 81 4b 89 02 f3 c4 be c1 6c 89 |.....k.K......l.|
+00000190 b1 44 84 bd 21 d1 04 7d 9d 16 4d f9 82 15 f6 ef |.D..!..}..M.....|
+000001a0 fa d6 09 47 f2 fb 02 03 01 00 01 a3 81 93 30 81 |...G..........0.|
+000001b0 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001c0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001d0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001e0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001f0 06 03 55 1d 0e 04 12 04 10 12 50 8d 89 6f 1b d1 |..U.......P..o..|
+00000200 dc 54 4d 6e cb 69 5e 06 f4 30 1b 06 03 55 1d 23 |.TMn.i^..0...U.#|
+00000210 04 14 30 12 80 10 bf 3d b6 a9 66 f2 b8 40 cf ea |..0....=..f..@..|
+00000220 b4 03 78 48 1a 41 30 19 06 03 55 1d 11 04 12 30 |..xH.A0...U....0|
+00000230 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000240 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000250 03 81 81 00 92 7c af 91 55 12 18 96 59 31 a6 48 |.....|..U...Y1.H|
+00000260 40 d5 2d d5 ee bb 02 a0 f5 c2 1e 7c 9b b3 30 7d |@.-........|..0}|
+00000270 3c dc 76 da 4f 3d c0 fa ae 2d 33 24 6b 03 7b 1b |<.v.O=...-3$k.{.|
+00000280 67 59 11 21 b5 11 bc 77 b9 d9 e0 6e a8 2d 2e 35 |gY.!...w...n.-.5|
+00000290 fa 64 5f 22 3e 63 10 6b be ff 14 86 6d 0d f0 15 |.d_">c.k....m...|
+000002a0 31 a8 14 38 1e 3b 84 87 2c cb 98 ed 51 76 b9 b1 |1..8.;..,...Qv..|
+000002b0 4f dd db 9b 84 04 86 40 fa 51 dd ba b4 8d eb e3 |O......@.Q......|
+000002c0 46 de 46 b9 4f 86 c7 f9 a4 c2 41 34 ac cc f6 ea |F.F.O.....A4....|
+000002d0 b0 ab 39 18 16 03 03 00 cd 0c 00 00 c9 03 00 17 |..9.............|
+000002e0 41 04 71 a0 a9 f0 31 52 0b a2 5f 44 b1 48 a6 dc |A.q...1R.._D.H..|
+000002f0 b7 b8 bb a3 59 13 06 46 73 37 b1 9d f6 5a 42 49 |....Y..Fs7...ZBI|
+00000300 a7 e4 3c 26 64 ed 26 41 f9 76 d5 88 ad b5 2f 12 |..<&d.&A.v..../.|
+00000310 ce 02 34 b8 85 36 ee cd a1 dc d9 d7 4b ed d2 81 |..4..6......K...|
+00000320 82 1e 04 01 00 80 86 91 0e 05 48 de 2b 45 0a 9d |..........H.+E..|
+00000330 72 33 44 73 98 f3 0e 0f 4c 0b aa c0 6b 02 34 83 |r3Ds....L...k.4.|
+00000340 0c e1 53 04 89 47 21 22 de 09 5e d0 b3 d9 8b 53 |..S..G!"..^....S|
+00000350 62 b0 bf c6 dd fe d3 ed d6 2e ac a0 64 9d a4 07 |b...........d...|
+00000360 1f a9 d5 89 5f 62 7f e0 b1 9b e2 ef 3e 36 89 70 |...._b......>6.p|
+00000370 3e 7c 0a e7 8c cb c3 a8 e0 91 d9 bd 6e 3d be 0e |>|..........n=..|
+00000380 a2 8c ab 46 1b 07 24 40 da a5 e3 0b b1 6a 9f 28 |...F..$@.....j.(|
+00000390 c7 4f e8 d0 a3 57 e1 5c f2 34 07 aa 77 28 91 a0 |.O...W.\.4..w(..|
+000003a0 7e d6 36 2c c3 1a 16 03 03 00 04 0e 00 00 00 |~.6,...........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1e 18 37 ef 0d |....F...BA...7..|
+00000010 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd |.Q.5uq..T[....g.|
+00000020 a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e |.$ >.V...(^.+-O.|
+00000030 f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 |...lK[.V.2B.X..I|
+00000040 a6 b5 68 1a 41 03 56 6b dc 5a 89 14 03 03 00 01 |..h.A.Vk.Z......|
+00000050 01 16 03 03 00 28 00 00 00 00 00 00 00 00 53 c5 |.....(........S.|
+00000060 60 30 29 1d 8a 38 57 f3 6d d1 f4 e1 ec 3e 79 d1 |`0)..8W.m....>y.|
+00000070 79 d3 b8 7f 4e 71 41 d6 72 fa c0 cd 53 92 |y...NqA.r...S.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 86 be df d2 27 |..........(....'|
+00000010 8b 37 77 eb 0b e4 6e 38 5c 27 56 48 bb b5 f2 be |.7w...n8\'VH....|
+00000020 43 e5 f7 32 d2 d3 a1 d7 4e 6a 3c 76 17 94 c1 b0 |C..2....Nj<v....|
+00000030 06 af 67 |..g|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 17 22 06 |..............".|
+00000010 f7 50 b5 6f 65 e0 dd f9 b6 bc 50 b7 91 c9 54 5c |.P.oe.....P...T\|
+00000020 4e 2f cc |N/.|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 1c 86 be df d2 27 8b 37 78 c8 e7 d6 |.........'.7x...|
+00000010 4b e4 60 9e 4c b0 28 79 d9 7a 78 58 d8 27 76 18 |K.`.L.(y.zxX.'v.|
+00000020 a3 |.|
+>>> Flow 7 (client to server)
+00000000 16 03 03 00 a9 00 00 00 00 00 00 00 02 a7 17 56 |...............V|
+00000010 8e ea 2e fc 76 06 40 b2 fa 10 71 62 68 b9 14 e6 |....v.@...qbh...|
+00000020 09 6d 63 86 d1 6b 87 3a c4 84 15 77 68 f8 85 ec |.mc..k.:...wh...|
+00000030 55 49 3c c5 c1 be 24 85 0c 38 4b 66 a8 5f 33 f9 |UI<...$..8Kf._3.|
+00000040 a3 e5 d1 36 fd 25 ba 9d 54 1f 4c df 66 09 a7 08 |...6.%..T.L.f...|
+00000050 8d 7c a4 7e d4 5d c2 11 77 7b 48 7a 32 f7 88 0a |.|.~.]..w{Hz2...|
+00000060 51 5f 6a 26 e2 11 88 01 5b b6 8e 6a aa 18 79 85 |Q_j&....[..j..y.|
+00000070 6a 0e 31 1f 33 5e 34 fd e9 1c 84 7c ea 6c 78 5d |j.1.3^4....|.lx]|
+00000080 0e d2 df c0 8c 92 3d 48 fc 9e 47 18 2a a7 1e e3 |......=H..G.*...|
+00000090 9b 89 6f 30 d0 fd 0a cd 4c b9 d9 89 b6 72 53 54 |..o0....L....rST|
+000000a0 3e 02 c3 d0 68 b0 4e 40 06 86 cd 8e 87 53 |>...h.N@.....S|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 89 86 be df d2 27 8b 37 79 29 01 95 |.........'.7y)..|
+00000010 8c 13 0f f0 6e 8b 00 0c 1e 1a 36 73 b6 96 ad e1 |....n.....6s....|
+00000020 40 80 6d 68 f3 41 a9 a1 85 ca 86 81 73 6c fc 49 |@.mh.A......sl.I|
+00000030 b4 61 76 27 0f cd 22 5f 7e a7 c1 e3 13 f6 2e da |.av'.."_~.......|
+00000040 1a 15 57 1a f1 b0 be 6d 55 44 78 95 62 82 ff 6e |..W....mUDx.b..n|
+00000050 bb 70 ea 24 2c bf e2 14 48 3a 07 9a 30 3a a8 88 |.p.$,...H:..0:..|
+00000060 8b d6 b4 62 28 cb 30 94 54 f6 9c 15 34 e9 c4 d2 |...b(.0.T...4...|
+00000070 e3 42 cf 79 1f 96 34 f3 4c 9f f2 df 6e 70 4f cd |.B.y..4.L...npO.|
+00000080 68 ae e2 2c d5 b7 f3 37 86 0a f5 7c af 32 16 03 |h..,...7...|.2..|
+00000090 03 02 89 86 be df d2 27 8b 37 7a 66 a9 20 cf 95 |.......'.7zf. ..|
+000000a0 d1 c9 3c c6 bc 53 16 01 e2 78 7e 2b 4d 45 20 d8 |..<..S...x~+ME .|
+000000b0 be da 93 9f 61 0b 34 25 f8 42 aa 0e b7 c5 a7 7a |....a.4%.B.....z|
+000000c0 99 23 b5 a5 0b 39 37 48 2d 66 21 8a bd 41 11 e5 |.#...97H-f!..A..|
+000000d0 79 5f 5d c1 9b 4f c2 0c fc a4 b9 ad 82 7e 7e 5b |y_]..O.......~~[|
+000000e0 f6 95 46 eb b2 9e 9c 2d 58 7e c7 90 2c c4 7f 1c |..F....-X~..,...|
+000000f0 cf 32 86 37 ec ab 60 71 ee 82 2b a2 95 61 8f 31 |.2.7..`q..+..a.1|
+00000100 99 2d c7 f4 5f 29 e8 b6 c3 f4 81 4f 2c b6 2c 67 |.-.._).....O,.,g|
+00000110 70 e5 cf d1 00 77 34 28 dc 61 cf e1 78 10 5e 64 |p....w4(.a..x.^d|
+00000120 17 f7 2b 3e 74 2c 8f 42 d5 a8 c2 4e 11 48 0f 0a |..+>t,.B...N.H..|
+00000130 3f 8a ea 0f 37 f5 da 8f 7f 7c 61 b3 98 d9 69 80 |?...7....|a...i.|
+00000140 b5 1e c6 5c 01 ff e3 8e 45 a1 7a cb ee ea 12 d3 |...\....E.z.....|
+00000150 d7 56 2e 33 8c 55 a5 94 84 f7 a1 a4 fa f3 71 f4 |.V.3.U........q.|
+00000160 a3 15 f0 7e 44 c7 32 65 86 39 93 b7 df ab 6b 94 |...~D.2e.9....k.|
+00000170 df 6d d8 31 72 ba d9 7b b6 8a 68 b1 c8 da e1 a0 |.m.1r..{..h.....|
+00000180 4f 0f 06 6a 52 78 6e a1 57 2f 2b 6b 10 5b c1 57 |O..jRxn.W/+k.[.W|
+00000190 d0 92 23 bf dc 95 f1 83 66 ce 6f ef c5 22 22 24 |..#.....f.o..""$|
+000001a0 80 bd 2f 38 ff de ec 86 8b ad 81 4e fe 31 65 54 |../8.......N.1eT|
+000001b0 19 94 ce 99 0f 6d 5b 1b 53 ba ad 65 a6 6a f6 27 |.....m[.S..e.j.'|
+000001c0 ba e0 b7 a9 8b 80 18 71 67 f7 6c 35 5f 69 c2 19 |.......qg.l5_i..|
+000001d0 08 27 03 45 5a 58 49 27 cf ec bf 18 e7 60 64 2b |.'.EZXI'.....`d+|
+000001e0 47 9e 07 1a 49 ef 90 20 c7 f7 69 5c 46 92 ae 65 |G...I.. ..i\F..e|
+000001f0 fa 45 9f 3b a3 4e ed cb d9 1f d9 26 18 1e bb 58 |.E.;.N.....&...X|
+00000200 16 cd a5 00 df 65 73 39 82 fd 98 29 de 45 8f 70 |.....es9...).E.p|
+00000210 56 e3 c6 0b 18 71 09 92 0e 69 4e b8 e7 23 4f 70 |V....q...iN..#Op|
+00000220 7a 89 06 c7 78 05 04 31 7f 77 5c 68 74 f0 45 76 |z...x..1.w\ht.Ev|
+00000230 e2 56 b2 de 34 e6 79 64 49 9a a8 3a b7 5b 4a d3 |.V..4.ydI..:.[J.|
+00000240 5e 6d 0b f3 fb 6d 0c 2f 61 d0 71 f4 0d ed 60 2f |^m...m./a.q...`/|
+00000250 61 80 c9 9b b9 e5 89 f2 64 88 52 d6 d3 aa 72 6b |a.......d.R...rk|
+00000260 66 18 ae e9 df 20 40 15 b5 73 ba ac 50 b1 27 99 |f.... @..s..P.'.|
+00000270 b3 17 97 56 0b 7d 25 8a 64 80 42 5c c8 b8 d5 98 |...V.}%.d.B\....|
+00000280 28 16 2b ce 45 65 3d fc d8 c6 91 31 c2 d4 09 a3 |(.+.Ee=....1....|
+00000290 cf 92 85 63 36 cb e2 da a3 66 fb 08 c9 bc 12 23 |...c6....f.....#|
+000002a0 c8 88 7d 46 22 98 40 01 bf fb 58 84 f2 8f ad 83 |..}F".@...X.....|
+000002b0 ed 79 b4 a8 3d e5 92 b7 b8 e1 d0 50 aa be 22 9c |.y..=......P..".|
+000002c0 9c cb dc bd 65 59 41 3e 6f 53 89 02 30 b1 88 ca |....eYA>oS..0...|
+000002d0 06 6d 8e b2 a6 75 6a d8 5a 19 65 de 27 c3 bf 70 |.m...uj.Z.e.'..p|
+000002e0 49 64 13 2d 19 5d 7a ec 91 a7 f6 82 92 7d e3 7e |Id.-.]z......}.~|
+000002f0 d6 65 5b d4 eb ed 58 d7 cd 41 a2 b9 d3 9e e4 a0 |.e[...X..A......|
+00000300 92 bf 88 4f 0e 59 74 66 86 db 72 11 18 ad 81 24 |...O.Ytf..r....$|
+00000310 6e 43 38 24 23 fb db af 92 d8 1a 2d 16 03 03 00 |nC8$#......-....|
+00000320 e5 86 be df d2 27 8b 37 7b ce 01 b6 78 47 7d 3a |.....'.7{...xG}:|
+00000330 ad 2e 03 8e 78 03 61 da 55 0e d4 fa 87 9d 20 25 |....x.a.U..... %|
+00000340 73 1f 3b 87 7b 02 c1 a3 af ce d5 b9 9e 29 91 1b |s.;.{........)..|
+00000350 58 13 c9 bc 96 95 88 f8 67 43 03 25 a3 be 5e a6 |X.......gC.%..^.|
+00000360 1d ee 6e 70 4c b5 66 48 3d 7d 1a 58 8e 10 c0 68 |..npL.fH=}.X...h|
+00000370 6b d8 f1 dd 83 c5 d3 c8 81 c5 6d 72 68 50 41 6f |k.........mrhPAo|
+00000380 f6 20 13 f8 72 fa 82 9a 25 e4 07 10 df b7 39 90 |. ..r...%.....9.|
+00000390 6a d7 d2 d7 a1 1c 31 4e b6 7c 00 bc 4d b1 a1 ff |j.....1N.|..M...|
+000003a0 d0 ae 42 b1 2d 3e 8b c9 43 f4 fa fc d4 71 8f 74 |..B.->..C....q.t|
+000003b0 37 23 1b bb 34 4e b6 e4 fe f1 1b ea da 08 e4 12 |7#..4N..........|
+000003c0 fd 50 23 f9 8a 2d 92 eb f5 2b fc b4 e1 35 87 74 |.P#..-...+...5.t|
+000003d0 44 79 0b df 6a 14 eb 20 17 ab 5b 12 a7 19 a4 4e |Dy..j.. ..[....N|
+000003e0 94 70 93 57 2d bd c2 54 88 fb 19 b7 82 28 ab db |.p.W-..T.....(..|
+000003f0 ca a9 19 5d 36 1b d6 fc 7d 41 2c 5b 76 ec 90 72 |...]6...}A,[v..r|
+00000400 47 5b c4 ae 59 a6 16 03 03 00 46 86 be df d2 27 |G[..Y.....F....'|
+00000410 8b 37 7c ed db 59 c6 0b 4e 52 c9 bc 7a 81 ed 20 |.7|..Y..NR..z.. |
+00000420 00 55 02 76 15 49 9b 0b f2 81 c2 f7 25 51 61 9d |.U.v.I......%Qa.|
+00000430 48 e3 d2 6f 08 ea 0c 9b 26 cc 3b 52 58 ef a0 1f |H..o....&.;RX...|
+00000440 09 c3 ca e8 c2 6c 13 86 b1 94 04 f1 65 e2 de 4c |.....l......e..L|
+00000450 7c |||
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 89 00 00 00 00 00 00 00 03 3c 0f 09 |.............<..|
+00000010 9e dc 39 b8 be ab ca 53 74 05 93 12 a4 e7 bb 56 |..9....St......V|
+00000020 9f e1 9f 2a 09 7d e1 74 89 ee b3 99 3c 91 c6 38 |...*.}.t....<..8|
+00000030 7e 0c 5e 2d 1f 7d bd cd 1a d1 16 ab af 94 08 c6 |~.^-.}..........|
+00000040 74 e3 16 12 0e 9b bc 91 95 6d 01 fd 10 00 12 c6 |t........m......|
+00000050 03 96 92 08 df 50 89 ba 5c 25 ce 31 d8 b1 84 8a |.....P..\%.1....|
+00000060 7d 6c cf 7f e6 9a e4 08 17 cc b8 f2 c9 8f e8 4b |}l.............K|
+00000070 ab 44 4f e9 63 8c 93 71 b1 70 4a f4 29 5f ef 45 |.DO.c..q.pJ.)_.E|
+00000080 68 e1 0e 31 a0 4c 96 8c 65 03 f3 48 24 48 d4 d7 |h..1.L..e..H$H..|
+00000090 93 d1 17 39 8d 97 e8 d8 59 08 4b 46 82 cf a3 99 |...9....Y.KF....|
+000000a0 55 36 65 a9 d8 df db d5 65 78 52 38 c2 2a 1e ec |U6e.....exR8.*..|
+000000b0 65 6a f5 d5 4c 81 0c f6 e6 77 b2 68 d4 6c 32 05 |ej..L....w.h.l2.|
+000000c0 ef f4 ee 0b e1 83 d0 3a cf a0 06 f2 cc 61 62 5e |.......:.....ab^|
+000000d0 fa b4 19 c7 e2 99 c1 cf 02 a1 01 3d 6a e0 be 9f |...........=j...|
+000000e0 82 cd e5 c8 ac e2 3e 6d 0f 60 a4 e9 9b ca cf c9 |......>m.`......|
+000000f0 c1 fe 2d ef 29 ed f9 c3 11 03 9f 76 66 71 ef 24 |..-.)......vfq.$|
+00000100 5f d3 29 aa 6a e1 0c b1 58 7a f3 df 92 e8 61 e2 |_.).j...Xz....a.|
+00000110 41 43 ad 9d 55 a0 b0 a3 20 8d 2c 8f 34 e6 ab d3 |AC..U... .,.4...|
+00000120 37 80 9e cb 27 91 69 0a ba 33 05 a1 7f 4d 7f 63 |7...'.i..3...M.c|
+00000130 ed 6a c1 72 43 ec 6a 6c ac b7 87 bb 81 6e 06 fa |.j.rC.jl.....n..|
+00000140 68 7a c9 33 28 59 ed 74 87 a1 6a 24 06 02 c0 21 |hz.3(Y.t..j$...!|
+00000150 71 b0 27 f9 6e b3 7e 30 e9 e0 df c2 5d 63 2a dd |q.'.n.~0....]c*.|
+00000160 9d e9 9c 4f 47 66 68 7e e4 8c 87 b7 f0 a8 3d b8 |...OGfh~......=.|
+00000170 36 39 3e 4c 9f 55 e7 bb c7 3e 34 36 54 19 41 33 |69>L.U...>46T.A3|
+00000180 61 e6 9a ae c6 91 1d fa 2d 8c 45 95 5f 95 36 79 |a.......-.E._.6y|
+00000190 e9 59 7e 81 cd 7e 9e 01 fe 85 eb c8 ed 4e 93 c6 |.Y~..~.......N..|
+000001a0 53 76 2d 5c 72 50 22 16 04 15 c2 cf 19 07 e6 73 |Sv-\rP"........s|
+000001b0 74 d0 7b bb 68 c3 29 39 bc ab 1b 4c c9 5a 36 73 |t.{.h.)9...L.Z6s|
+000001c0 55 47 7a c8 4a a7 45 fe f3 a9 94 6e ea ea cc 7d |UGz.J.E....n...}|
+000001d0 d1 de f4 82 4c 14 84 f0 58 09 56 25 83 7a 23 71 |....L...X.V%.z#q|
+000001e0 a1 63 e3 4e 13 78 68 41 a1 9a 55 ec 9e 37 ee c2 |.c.N.xhA..U..7..|
+000001f0 7d 3f 8f 91 00 30 f2 ca 7b 13 b7 e7 fe 85 c5 aa |}?...0..{.......|
+00000200 5e e3 97 2c cb d5 13 1e 83 3d c9 2a b1 21 f1 58 |^..,.....=.*.!.X|
+00000210 7d 09 32 31 d6 fd 89 26 ff 72 3c f7 c4 fe 99 33 |}.21...&.r<....3|
+00000220 41 82 76 05 b9 14 b1 b0 3c 41 02 74 a8 1d dd 80 |A.v.....<A.t....|
+00000230 38 67 25 01 39 f7 36 fa e4 1c 7d 2f c9 7e 21 0a |8g%.9.6...}/.~!.|
+00000240 30 77 1e ff fc 8a 31 ac ee 91 f0 2c b1 9a b7 5e |0w....1....,...^|
+00000250 26 d0 7a 9d b4 9e 53 6b dd a6 5e 7b f0 45 99 9b |&.z...Sk..^{.E..|
+00000260 2b 69 90 d4 dd 1a d0 b5 13 90 11 ac 01 f0 2f 94 |+i............/.|
+00000270 5b 59 7e 7a 40 22 3a b0 d4 24 92 7d 94 bf 34 91 |[Y~z@":..$.}..4.|
+00000280 f6 b9 cc c9 e5 de d3 67 6d 83 97 ee 8f 48 16 03 |.......gm....H..|
+00000290 03 00 5e 00 00 00 00 00 00 00 04 dc 6f 41 98 23 |..^.........oA.#|
+000002a0 d7 70 80 24 74 46 c8 45 e1 2f 43 1d b8 66 4d 0a |.p.$tF.E./C..fM.|
+000002b0 03 0e d6 01 8b 92 f7 76 c1 2c 32 6c 65 60 da ab |.......v.,2le`..|
+000002c0 0b 12 6d 30 1c cf de e7 ec a7 12 f9 df 6c b4 42 |..m0.........l.B|
+000002d0 e7 d9 6e 6e f3 1c 10 ee 39 47 7f ec 7c ec 68 68 |..nn....9G..|.hh|
+000002e0 e8 b2 70 a2 67 61 e0 b3 68 b5 91 9f 1a e0 c5 af |..p.ga..h.......|
+000002f0 e3 16 03 03 00 a0 00 00 00 00 00 00 00 05 6b 56 |..............kV|
+00000300 3d 5e 4e f1 2c 30 e2 91 24 5c b1 5f d3 7d 3e dc |=^N.,0..$\._.}>.|
+00000310 ba 98 e1 9f 72 98 2b 0e 11 07 d1 ea 14 d5 73 25 |....r.+.......s%|
+00000320 d2 cf 8e bc a5 ea 93 a7 32 ab 94 83 1e ea c5 62 |........2......b|
+00000330 06 79 bb ab 4c a0 cf fb 51 3b 7b f0 11 5e ae 50 |.y..L...Q;{..^.P|
+00000340 23 cb ff 86 03 3d a5 66 b9 c4 35 c2 12 f2 98 85 |#....=.f..5.....|
+00000350 77 ba af 3b d5 dd f2 cd 58 09 29 26 08 cd 4a ed |w..;....X.)&..J.|
+00000360 ac af 57 ab 27 1a 40 ef 10 57 d1 ad 06 34 be ed |..W.'.@..W...4..|
+00000370 fe 88 1d 09 4a 81 8a da e7 ef fa 27 71 ab 2b 3f |....J......'q.+?|
+00000380 21 91 5f 1a dc 50 a4 f0 58 bd aa af 75 4e 25 2a |!._..P..X...uN%*|
+00000390 2c 55 e5 57 c6 ab 14 03 03 00 19 00 00 00 00 00 |,U.W............|
+000003a0 00 00 06 5d 8a 3e 8e 55 e4 9d c0 6a de 91 c6 96 |...].>.U...j....|
+000003b0 6e 17 54 a5 16 03 03 00 28 00 00 00 00 00 00 00 |n.T.....(.......|
+000003c0 00 d5 45 5d 11 af e2 b6 f1 a8 e5 ed 58 80 54 ce |..E]........X.T.|
+000003d0 b3 db dc 97 b3 86 c0 83 f9 3b 7c b5 ad 21 f8 cf |.........;|..!..|
+000003e0 9a |.|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 19 86 be df d2 27 8b 37 7d 85 70 b7 |.........'.7}.p.|
+00000010 a7 98 89 36 01 b4 a8 6f cb 14 0f dd ac 08 16 03 |...6...o........|
+00000020 03 00 28 75 41 a9 ef 1c 88 59 4e 84 15 29 a4 75 |..(uA....YN..).u|
+00000030 e6 66 01 3f a1 b7 ff 69 04 b6 08 99 c9 5e 57 60 |.f.?...i.....^W`|
+00000040 ea 76 21 94 06 e4 32 95 e1 4c d7 17 03 03 00 21 |.v!...2..L.....!|
+00000050 75 41 a9 ef 1c 88 59 4f c8 5d 4e bd 42 52 ec 50 |uA....YO.]N.BR.P|
+00000060 2f 28 4f 87 da bc f0 df a8 93 14 b7 6f a0 7f a2 |/(O.........o...|
+00000070 c5 |.|
+>>> Flow 11 (client to server)
+00000000 15 03 03 00 1a 00 00 00 00 00 00 00 01 92 8a f2 |................|
+00000010 9a d1 c9 1e 68 15 2d 6b 9a a7 f8 21 78 87 89 |....h.-k...!x..|
diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
new file mode 100644
index 0000000..185dc65
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
@@ -0,0 +1,409 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 00 00 00 00 00 |................|
+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 22 c0 2f |............."./|
+00000030 c0 2b c0 30 c0 2c c0 11 c0 07 c0 13 c0 09 c0 14 |.+.0.,..........|
+00000040 c0 0a 00 9c 00 9d 00 05 00 2f 00 35 c0 12 00 0a |........./.5....|
+00000050 01 00 00 36 00 05 00 05 01 00 00 00 00 00 0a 00 |...6............|
+00000060 08 00 06 00 17 00 18 00 19 00 0b 00 02 01 00 00 |................|
+00000070 0d 00 0e 00 0c 04 01 04 03 05 01 05 03 02 01 02 |................|
+00000080 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 bb b7 b5 ee 8b |....Y...U.......|
+00000010 b7 92 40 96 01 65 93 09 a0 63 77 b3 35 74 0a 73 |..@..e...cw.5t.s|
+00000020 db e8 4a 9c d4 95 4b 2a f9 43 1e 20 d6 5a ed d1 |..J...K*.C. .Z..|
+00000030 05 f0 61 aa 45 ae 0e 92 03 87 1b a6 0a 1a 83 a1 |..a.E...........|
+00000040 bd 4f c3 81 79 e8 56 10 5d 08 7b 6d c0 2f 00 00 |.O..y.V.].{m./..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 71 0b 00 02 6d 00 02 6a 00 02 67 30 82 02 |..q...m..j..g0..|
+00000070 63 30 82 01 cc a0 03 02 01 02 02 09 00 a2 73 00 |c0............s.|
+00000080 0c 81 00 cb f3 30 0d 06 09 2a 86 48 86 f7 0d 01 |.....0...*.H....|
+00000090 01 0b 05 00 30 2b 31 17 30 15 06 03 55 04 0a 13 |....0+1.0...U...|
+000000a0 0e 47 6f 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 |.Google TESTING1|
+000000b0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000c0 74 30 1e 17 0d 31 35 30 31 30 31 30 30 30 30 30 |t0...15010100000|
+000000d0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000e0 5a 30 26 31 17 30 15 06 03 55 04 0a 13 0e 47 6f |Z0&1.0...U....Go|
+000000f0 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 0b 30 09 |ogle TESTING1.0.|
+00000100 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+00000110 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000120 81 89 02 81 81 00 af 87 88 f6 20 1b 95 65 6c 14 |.......... ..el.|
+00000130 ab 44 05 af 3b 45 14 e3 b7 6d fd 00 63 4d 95 7f |.D..;E...m..cM..|
+00000140 fe 6a 62 35 86 c0 4a f9 18 7c f6 aa 25 5e 7a 64 |.jb5..J..|..%^zd|
+00000150 31 66 00 ba f4 8e 92 af c7 6b d8 76 d4 f3 5f 41 |1f.......k.v.._A|
+00000160 cb 6e 56 15 97 1b 97 c1 3c 12 39 21 66 3d 2b 16 |.nV.....<.9!f=+.|
+00000170 d1 bc db 1c c0 a7 da b7 ca ad ba da cb d5 21 50 |..............!P|
+00000180 ec de 8d ab d1 6b 81 4b 89 02 f3 c4 be c1 6c 89 |.....k.K......l.|
+00000190 b1 44 84 bd 21 d1 04 7d 9d 16 4d f9 82 15 f6 ef |.D..!..}..M.....|
+000001a0 fa d6 09 47 f2 fb 02 03 01 00 01 a3 81 93 30 81 |...G..........0.|
+000001b0 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001c0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001d0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001e0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001f0 06 03 55 1d 0e 04 12 04 10 12 50 8d 89 6f 1b d1 |..U.......P..o..|
+00000200 dc 54 4d 6e cb 69 5e 06 f4 30 1b 06 03 55 1d 23 |.TMn.i^..0...U.#|
+00000210 04 14 30 12 80 10 bf 3d b6 a9 66 f2 b8 40 cf ea |..0....=..f..@..|
+00000220 b4 03 78 48 1a 41 30 19 06 03 55 1d 11 04 12 30 |..xH.A0...U....0|
+00000230 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000240 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000250 03 81 81 00 92 7c af 91 55 12 18 96 59 31 a6 48 |.....|..U...Y1.H|
+00000260 40 d5 2d d5 ee bb 02 a0 f5 c2 1e 7c 9b b3 30 7d |@.-........|..0}|
+00000270 3c dc 76 da 4f 3d c0 fa ae 2d 33 24 6b 03 7b 1b |<.v.O=...-3$k.{.|
+00000280 67 59 11 21 b5 11 bc 77 b9 d9 e0 6e a8 2d 2e 35 |gY.!...w...n.-.5|
+00000290 fa 64 5f 22 3e 63 10 6b be ff 14 86 6d 0d f0 15 |.d_">c.k....m...|
+000002a0 31 a8 14 38 1e 3b 84 87 2c cb 98 ed 51 76 b9 b1 |1..8.;..,...Qv..|
+000002b0 4f dd db 9b 84 04 86 40 fa 51 dd ba b4 8d eb e3 |O......@.Q......|
+000002c0 46 de 46 b9 4f 86 c7 f9 a4 c2 41 34 ac cc f6 ea |F.F.O.....A4....|
+000002d0 b0 ab 39 18 16 03 03 00 cd 0c 00 00 c9 03 00 17 |..9.............|
+000002e0 41 04 b5 fe 7d 68 cd 5a b7 bf 61 10 81 dc 92 23 |A...}h.Z..a....#|
+000002f0 d0 82 13 fb 71 6f 39 48 f9 87 f8 f7 a0 3a cd 18 |....qo9H.....:..|
+00000300 85 d7 4d 66 88 9d 39 8d 6d 53 a1 a3 0d 00 b0 0f |..Mf..9.mS......|
+00000310 14 64 1b 72 2d 89 5c 93 6f 3c ed c9 82 20 3d 2f |.d.r-.\.o<... =/|
+00000320 d0 7f 04 01 00 80 42 24 14 6e cf 78 ea 30 90 1e |......B$.n.x.0..|
+00000330 4e 99 bf ca 98 9c 2f 24 98 c2 a2 b3 f8 34 49 22 |N...../$.....4I"|
+00000340 35 16 11 03 79 3b a8 10 a3 fa d8 5e 17 9d f9 50 |5...y;.....^...P|
+00000350 0a 3b 0b b5 b2 0f 90 18 c1 f5 6f 89 84 04 e2 f0 |.;........o.....|
+00000360 b0 04 2f 3e 78 d3 de 31 9e 6e 3b b8 c7 f5 cc 4f |../>x..1.n;....O|
+00000370 4e ad fe 76 d2 6d 23 31 94 56 b1 d8 df 0d 9b c5 |N..v.m#1.V......|
+00000380 f7 9e 9c a7 2a 47 e4 c8 20 08 fc 6c d5 29 cd 36 |....*G.. ..l.).6|
+00000390 88 83 c5 59 33 6d 1f 0b f9 98 65 fa cb f7 89 2d |...Y3m....e....-|
+000003a0 90 3a 40 8a 31 7e 16 03 03 00 04 0e 00 00 00 |.:@.1~.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1e 18 37 ef 0d |....F...BA...7..|
+00000010 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd |.Q.5uq..T[....g.|
+00000020 a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e |.$ >.V...(^.+-O.|
+00000030 f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 |...lK[.V.2B.X..I|
+00000040 a6 b5 68 1a 41 03 56 6b dc 5a 89 14 03 03 00 01 |..h.A.Vk.Z......|
+00000050 01 16 03 03 00 28 00 00 00 00 00 00 00 00 fa e7 |.....(..........|
+00000060 ff 47 50 7a 68 0d 20 f6 9f 2a b5 bc f4 21 c1 72 |.GPzh. ..*...!.r|
+00000070 07 4c e5 07 2c 07 e5 1e d7 fa 07 01 83 68 |.L..,........h|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 b7 93 18 5b 36 |..........(...[6|
+00000010 18 ce 97 17 75 40 15 17 1f 0e 0d 99 fd 66 fa 89 |....u@.......f..|
+00000020 db b7 97 95 a9 45 90 07 6e 82 0e 67 4f 01 58 ec |.....E..n..gO.X.|
+00000030 94 d7 ad |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 21 2b 7b |.............!+{|
+00000010 62 ac e4 37 d6 77 19 89 77 1c 6a ce 40 c1 9d 71 |b..7.w..w.j.@..q|
+00000020 5a 23 f0 |Z#.|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 1c b7 93 18 5b 36 18 ce 98 4a 49 69 |........[6...JIi|
+00000010 f4 dd 35 f2 93 3b c6 4e d5 25 51 34 38 23 ea 74 |..5..;.N.%Q48#.t|
+00000020 84 |.|
+>>> Flow 7 (client to server)
+00000000 16 03 03 00 a9 00 00 00 00 00 00 00 02 65 09 7a |.............e.z|
+00000010 d5 9b 32 0b cd 10 ea 2c b6 d8 be ce db 3f a4 38 |..2....,.....?.8|
+00000020 a7 37 a3 95 ed 05 a7 c1 28 69 7a 13 50 07 ab 19 |.7......(iz.P...|
+00000030 52 d7 29 fe 49 80 f0 ef ea 17 ac 20 f9 62 51 72 |R.).I...... .bQr|
+00000040 8d c0 17 62 03 cf bb 80 f8 6f 1b 74 f1 85 45 96 |...b.....o.t..E.|
+00000050 49 55 56 b0 7a dd 9b 5a f1 3f 1a e7 96 cd 21 ec |IUV.z..Z.?....!.|
+00000060 85 6f b9 9d 0f e3 f6 55 9b b8 a7 e1 77 ad 53 0b |.o.....U....w.S.|
+00000070 98 90 ac 5d cf 31 0f 86 69 04 d8 e9 5e fc ea a8 |...].1..i...^...|
+00000080 a8 b7 a2 d8 0f ea 4f e5 ac f2 b2 c0 59 29 ba 53 |......O.....Y).S|
+00000090 af 1e 81 08 be 02 46 a7 b8 6f 2a b4 86 47 5d 8e |......F..o*..G].|
+000000a0 72 a6 64 84 7e 76 31 9c 31 fb 59 b7 da 15 |r.d.~v1.1.Y...|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 89 b7 93 18 5b 36 18 ce 99 4a 72 26 |........[6...Jr&|
+00000010 ab cb a4 70 60 0f 7a 02 62 28 f3 10 54 77 a7 33 |...p`.z.b(..Tw.3|
+00000020 32 a6 29 c8 8d 18 48 8f 9d 45 6e 7e 06 07 ca b3 |2.)...H..En~....|
+00000030 b6 45 eb ac f2 41 f1 d9 19 9e 30 1f c0 18 40 1c |.E...A....0...@.|
+00000040 55 09 4d f2 23 75 2f 2f c8 b7 46 63 05 d1 73 c0 |U.M.#u//..Fc..s.|
+00000050 02 71 de 5e 4a 84 92 3d 9a b9 68 62 31 91 7d 23 |.q.^J..=..hb1.}#|
+00000060 43 e3 4b 00 98 2e 01 12 f4 1f fa 4c aa 91 a0 ca |C.K........L....|
+00000070 9c a0 d9 6b 7f 5c b3 f4 8d e2 3a 54 eb e9 82 44 |...k.\....:T...D|
+00000080 21 54 ac 85 86 39 b8 df 23 64 2a 0c 3e 1d 16 03 |!T...9..#d*.>...|
+00000090 03 02 89 b7 93 18 5b 36 18 ce 9a 1c ae 99 12 58 |......[6.......X|
+000000a0 12 fa ef da 77 04 7f b5 42 68 b1 59 64 50 92 2b |....w...Bh.YdP.+|
+000000b0 a0 21 b7 b3 4c f8 c2 cc 75 5a d0 85 50 95 f4 1b |.!..L...uZ..P...|
+000000c0 c9 b2 1f 53 94 4c fd 6d 18 ad 1a 0d 24 9f fb 4c |...S.L.m....$..L|
+000000d0 19 13 5a 74 f2 e2 59 dd 1b d8 67 bc d9 d0 da ab |..Zt..Y...g.....|
+000000e0 a7 7f 8e ca e0 09 28 59 18 8d a1 8a c9 c3 2e 76 |......(Y.......v|
+000000f0 b9 0d 2f 56 5f c4 77 07 17 ac 62 26 a1 91 50 ee |../V_.w...b&..P.|
+00000100 60 45 aa a0 8a d9 1a 13 65 68 c8 cf ca 0c 50 3e |`E......eh....P>|
+00000110 9f 39 62 02 12 ea b4 ed e2 6c 0e 28 32 d7 fb ec |.9b......l.(2...|
+00000120 fc 6d e4 0a 14 1d 88 00 a8 c0 57 1e be 78 fd 18 |.m........W..x..|
+00000130 6e 40 70 37 2e f5 3b 52 59 03 02 bf 27 18 c8 00 |n@p7..;RY...'...|
+00000140 58 8f 5e d8 a8 7c 4c 54 83 4a fe f3 dc f8 19 2a |X.^..|LT.J.....*|
+00000150 00 ed 96 93 0e e4 45 58 8f 41 99 0d 93 f5 6c a4 |......EX.A....l.|
+00000160 4e 62 f2 4b 9a cb 69 30 5a 4b 36 45 f2 d2 c1 62 |Nb.K..i0ZK6E...b|
+00000170 f9 1c c4 c3 b2 94 b3 17 1a ed d8 57 ba b7 79 a1 |...........W..y.|
+00000180 a2 2e 5a 18 79 36 0b 54 ee 2c 2c 3b 62 96 5d e5 |..Z.y6.T.,,;b.].|
+00000190 3c 74 0e be 52 6f 06 7c 93 05 86 0f d6 1d d0 ee |<t..Ro.|........|
+000001a0 f9 ac 67 50 a6 d3 36 f7 5f 0b 3f 44 3b fc 4b 79 |..gP..6._.?D;.Ky|
+000001b0 b7 29 04 6c 37 18 2a 04 bf f4 3e 1a 53 f3 93 e5 |.).l7.*...>.S...|
+000001c0 f2 b7 b1 4b ed 19 5a 2f 40 d1 f2 91 49 0b 8b f6 |...K..Z/@...I...|
+000001d0 21 0b 20 01 ce 0f a8 f1 44 3f 5e b1 89 1a 15 9f |!. .....D?^.....|
+000001e0 4c c5 93 6b 68 93 ab 67 b5 1d 10 fa 22 53 e3 0f |L..kh..g...."S..|
+000001f0 c7 63 d0 32 b7 52 c6 2e b7 47 a4 1a b4 ab 35 a9 |.c.2.R...G....5.|
+00000200 b0 0e cd f6 8c e7 54 6c 77 7b 5c 6c c2 b3 02 89 |......Tlw{\l....|
+00000210 74 f7 b1 61 91 dc 01 3a 68 d9 81 78 21 95 b1 67 |t..a...:h..x!..g|
+00000220 36 2d 2a d6 c4 96 0d 7b e0 44 83 cd 52 e4 05 36 |6-*....{.D..R..6|
+00000230 a4 1d 2a 24 e8 cc 76 d7 66 2f 32 ef 8f 70 ef 26 |..*$..v.f/2..p.&|
+00000240 90 73 2e e6 b4 53 91 13 5b 5e 15 51 15 56 e9 43 |.s...S..[^.Q.V.C|
+00000250 22 9a b6 55 3d 94 00 35 73 41 12 fc 8a 0b fd 89 |"..U=..5sA......|
+00000260 7c 00 14 0d b8 f6 76 d0 ac 33 1d e4 73 49 e9 a2 ||.....v..3..sI..|
+00000270 09 69 e1 f1 a7 92 48 ee 2e fc ef 13 09 7c a7 72 |.i....H......|.r|
+00000280 eb 4c 15 39 17 6e cd 71 c0 e9 48 06 43 09 19 39 |.L.9.n.q..H.C..9|
+00000290 72 b0 9c f8 0e 75 af a8 eb 25 96 36 75 68 16 8f |r....u...%.6uh..|
+000002a0 e8 f6 66 56 66 63 b0 52 47 74 55 af c8 7a 07 dc |..fVfc.RGtU..z..|
+000002b0 d0 8b bf 51 6e bc 77 fa 8a 03 43 0c 5a 47 fb c7 |...Qn.w...C.ZG..|
+000002c0 be b3 ef b5 ad 24 48 40 6c 4b 03 41 dd 7c 3e 6e |.....$H@lK.A.|>n|
+000002d0 25 01 4b 45 ce ad d7 23 3a 6c 33 0b f1 7a 44 07 |%.KE...#:l3..zD.|
+000002e0 7e c8 bd 52 a5 a8 30 91 95 3e 4d 42 07 67 57 fb |~..R..0..>MB.gW.|
+000002f0 c0 4a ed 9f 76 21 8e df fb f6 a4 0a 08 1e 5b c6 |.J..v!........[.|
+00000300 3e a3 8c 47 a4 4d 41 2b e6 8f 42 43 cd ef a8 f1 |>..G.MA+..BC....|
+00000310 88 f2 b3 46 eb 8a 24 a3 98 a2 d7 d2 16 03 03 00 |...F..$.........|
+00000320 e5 b7 93 18 5b 36 18 ce 9b 62 57 ae 22 62 34 88 |....[6...bW."b4.|
+00000330 41 e1 7e 2a 4a 07 b4 b8 aa 80 32 f5 93 4c 58 79 |A.~*J.....2..LXy|
+00000340 82 51 d4 b8 c8 5b d2 99 a3 18 43 aa c2 14 bf 65 |.Q...[....C....e|
+00000350 e8 90 8d 46 69 d5 fa 34 e4 1a 47 06 dc 1a ae e9 |...Fi..4..G.....|
+00000360 40 b2 2e 7e 5e 74 f7 72 4d a9 e2 b7 52 b4 bb dc |@..~^t.rM...R...|
+00000370 06 e6 50 7e ef 42 8f 72 08 63 f9 ec 9e 13 36 0f |..P~.B.r.c....6.|
+00000380 d4 95 72 2b ff a5 6d 4b 1b db d6 b3 25 50 f0 dd |..r+..mK....%P..|
+00000390 e3 89 f5 c1 c0 3f aa 6c f0 a7 30 5d 56 76 77 b6 |.....?.l..0]Vvw.|
+000003a0 24 8f 93 fd 49 8c 73 1e f7 5c 5c 3a f3 0d 5e 89 |$...I.s..\\:..^.|
+000003b0 a4 bb 48 8a 82 ed 01 a6 2d eb b1 fe d2 6e 4e 88 |..H.....-....nN.|
+000003c0 1d 06 b6 f5 d8 41 86 40 fe 45 3e ef 35 9b 88 df |.....A.@.E>.5...|
+000003d0 48 af e0 05 33 4e 13 15 8b b6 5a 8e 5c f8 2a 59 |H...3N....Z.\.*Y|
+000003e0 14 6d 4a 79 75 48 e4 9d 16 4f 6f 65 9c c3 40 1e |.mJyuH...Ooe..@.|
+000003f0 7c 72 60 ce b9 f8 61 3b ff 34 81 94 01 aa b3 59 ||r`...a;.4.....Y|
+00000400 72 d2 1e 5f fe 7f 16 03 03 00 46 b7 93 18 5b 36 |r.._......F...[6|
+00000410 18 ce 9c c8 c9 b2 10 f1 39 bb f0 80 a9 0b 68 76 |........9.....hv|
+00000420 2b 60 0b c5 f3 eb 16 72 b5 4c c9 42 96 39 bf c1 |+`.....r.L.B.9..|
+00000430 94 87 f0 47 80 34 11 e2 1c 4c fc 26 d6 4b 00 49 |...G.4...L.&.K.I|
+00000440 ef 73 00 4e ab 61 d6 1f 89 2c 7e f2 5c ea 6b 5c |.s.N.a...,~.\.k\|
+00000450 50 |P|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 89 00 00 00 00 00 00 00 03 c2 d4 9b |................|
+00000010 19 c8 b6 76 fb ef e4 b2 f7 97 c7 80 f5 e2 b4 3c |...v...........<|
+00000020 bd b7 b8 25 da 54 52 a7 f8 38 0d 48 c0 13 19 82 |...%.TR..8.H....|
+00000030 17 3c ff d2 c0 8f bd 76 5d 16 39 db a7 51 3f b1 |.<.....v].9..Q?.|
+00000040 72 b6 59 e4 8c 6c f5 33 de 78 15 8d 64 cf 55 c6 |r.Y..l.3.x..d.U.|
+00000050 47 e3 0b 30 06 e1 6c 2d e1 e0 7a e1 0a da dd 0d |G..0..l-..z.....|
+00000060 60 5b 06 28 a8 94 14 a3 cc 91 96 8d 2b 71 af ff |`[.(........+q..|
+00000070 c2 32 e2 19 77 96 f3 5b 53 3a d3 29 51 c2 54 98 |.2..w..[S:.)Q.T.|
+00000080 f3 00 8e 9a fe ef bb ea 06 27 58 54 3c c8 67 dc |.........'XT<.g.|
+00000090 f3 41 01 77 de 25 b4 54 53 67 64 41 b3 ae 2b c2 |.A.w.%.TSgdA..+.|
+000000a0 57 cd 74 14 3c 46 a7 70 ec a8 bc 0e 05 46 ce fc |W.t.<F.p.....F..|
+000000b0 c8 54 4d 23 25 b9 e0 45 fa 1e 1b 2c f1 d0 da 66 |.TM#%..E...,...f|
+000000c0 3c 00 e5 b3 f5 f9 ff 64 75 82 f9 dd c2 3f 42 46 |<......du....?BF|
+000000d0 27 ca 72 a2 f7 6c 4e bf 98 05 e6 99 b5 7b 60 33 |'.r..lN......{`3|
+000000e0 99 e8 7a 7c 91 41 64 cd 96 60 f2 f6 c8 bd 4f 35 |..z|.Ad..`....O5|
+000000f0 5f 6f 43 11 b0 94 3c 98 bc 58 15 7e 52 01 ba cf |_oC...<..X.~R...|
+00000100 71 f4 0a fb 85 0a 24 13 0c 4a 53 55 77 92 91 cd |q.....$..JSUw...|
+00000110 ce 39 7e 07 2f 4f ba 47 ca bd 67 5b ce 5a 04 03 |.9~./O.G..g[.Z..|
+00000120 ff 86 0a 82 80 b9 42 b8 4c e3 ce 73 b2 4a 5a 4b |......B.L..s.JZK|
+00000130 f5 f2 44 d8 e5 01 30 c8 2e ce 4f 62 2d 34 9c d6 |..D...0...Ob-4..|
+00000140 57 20 db 37 20 66 03 b6 4d a7 0f 75 30 d8 ad 2f |W .7 f..M..u0../|
+00000150 63 f7 4e 24 ec 68 e0 a2 a9 b1 3d 68 e5 c1 8b d8 |c.N$.h....=h....|
+00000160 19 dd 40 33 c6 5c 57 3b 22 5a 9c 24 fe 2f 92 54 |..@3.\W;"Z.$./.T|
+00000170 0f e8 85 74 06 72 59 ab 1d b8 5d 31 91 ed 05 51 |...t.rY...]1...Q|
+00000180 61 c6 43 3d 81 f4 47 c3 80 17 4d 1b 08 c4 85 1b |a.C=..G...M.....|
+00000190 b7 37 b0 cf 5c 73 5f 56 0f 5a b5 21 21 46 e3 df |.7..\s_V.Z.!!F..|
+000001a0 e6 cb 9d ac ab 16 c0 b1 b8 2a 4a 5b a7 2d 7a 00 |.........*J[.-z.|
+000001b0 9f 9d 76 57 ab 20 ea 80 8a 7a ca 14 45 d7 4e 1b |..vW. ...z..E.N.|
+000001c0 c8 7c b8 c6 82 fc 40 b2 b4 7d f1 74 7d b5 2a 90 |.|....@..}.t}.*.|
+000001d0 01 83 d4 d1 26 63 d7 39 69 b1 33 5f 7e 54 de f7 |....&c.9i.3_~T..|
+000001e0 08 3d 62 3b da 57 0d d4 48 99 9a 3e 99 e5 b0 6b |.=b;.W..H..>...k|
+000001f0 25 45 38 36 aa 7a bb 81 7d 0b dd 1d 50 c4 17 68 |%E86.z..}...P..h|
+00000200 4b a7 f7 2f d8 cd 97 a6 ea 24 9b 34 69 9e 7d ad |K../.....$.4i.}.|
+00000210 6a 17 23 d8 36 61 cf 85 74 47 18 5b fd cd 72 ac |j.#.6a..tG.[..r.|
+00000220 c2 a2 b4 53 e3 5d 25 f7 bb b6 95 99 a0 e5 05 38 |...S.]%........8|
+00000230 0a 52 32 f6 7d a6 30 5c 11 6b 8a 7b af ec a2 9b |.R2.}.0\.k.{....|
+00000240 b8 f1 85 6d a8 b7 79 61 42 60 4a 35 73 fb d5 2c |...m..yaB`J5s..,|
+00000250 1f 84 5c d9 c9 23 10 e8 a4 2c 56 fd f4 22 1a 7a |..\..#...,V..".z|
+00000260 f3 b2 c5 69 8b c9 d1 d5 45 c8 65 59 fc ab d9 d3 |...i....E.eY....|
+00000270 7d ab c3 fe bc da 6d a3 cd 0c 83 32 70 65 c7 7f |}.....m....2pe..|
+00000280 8c 83 c8 97 3e 7f 89 fc 11 7d 1c a5 fd 99 16 03 |....>....}......|
+00000290 03 00 5e 00 00 00 00 00 00 00 04 64 60 91 c0 fd |..^........d`...|
+000002a0 3a 96 5a ac 5a 13 a9 9a 41 eb a0 6d 51 98 ee a8 |:.Z.Z...A..mQ...|
+000002b0 4d ee 90 c9 3e a5 15 ac f3 6a c8 56 f3 20 c3 10 |M...>....j.V. ..|
+000002c0 e3 3a d1 ea b0 7d a7 21 ae 2c b1 fa 5c b8 c1 fa |.:...}.!.,..\...|
+000002d0 d7 97 6e ea fd 09 53 46 db aa e4 39 31 00 c2 bb |..n...SF...91...|
+000002e0 ad 36 10 cd e9 cb 46 31 7b 66 ee ce 0c a8 f9 c2 |.6....F1{f......|
+000002f0 0a 16 03 03 00 a0 00 00 00 00 00 00 00 05 6d a0 |..............m.|
+00000300 03 60 12 bb 06 89 0c 03 ad f7 36 f3 5c e4 c1 65 |.`........6.\..e|
+00000310 b2 26 c9 f5 87 85 f9 8f 2d 05 43 35 32 d7 0a a0 |.&......-.C52...|
+00000320 e5 16 7a 94 62 15 ed cc 8e 9f e3 10 8d e7 83 a2 |..z.b...........|
+00000330 ea e4 07 49 c9 df 1d 2b 6f b8 0f 67 31 22 44 9b |...I...+o..g1"D.|
+00000340 65 77 99 78 f9 3e 14 67 3a 90 e5 5a c2 b5 1b ee |ew.x.>.g:..Z....|
+00000350 db 20 73 8d 85 22 4d 79 6e e9 17 d0 b1 03 58 f3 |. s.."Myn.....X.|
+00000360 cf 1b f5 03 9a 75 1f 7a 3b 49 ee 67 04 da c4 fc |.....u.z;I.g....|
+00000370 7a 62 a9 ff 26 4f 71 b2 7e e9 c7 78 96 74 1e 63 |zb..&Oq.~..x.t.c|
+00000380 eb 2b 2f 18 1f 19 cf 1e 89 73 39 9e f6 02 3d 31 |.+/......s9...=1|
+00000390 50 65 1f 80 19 26 14 03 03 00 19 00 00 00 00 00 |Pe...&..........|
+000003a0 00 00 06 82 62 df fd 51 9e be 21 0b 22 b6 c1 6d |....b..Q..!."..m|
+000003b0 5c 90 ea c5 16 03 03 00 28 00 00 00 00 00 00 00 |\.......(.......|
+000003c0 00 d6 5f a7 05 2b 99 cc 7d fb d7 38 5e e3 31 a7 |.._..+..}..8^.1.|
+000003d0 c9 1c bd 7b c7 89 d0 e5 b5 93 78 d1 63 57 d2 76 |...{......x.cW.v|
+000003e0 38 |8|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 19 b7 93 18 5b 36 18 ce 9d 68 22 e1 |........[6...h".|
+00000010 d0 06 aa e5 87 f8 49 bc 38 d7 b9 38 85 97 16 03 |......I.8..8....|
+00000020 03 00 28 24 71 bf 67 14 d6 5e 29 1b de e6 f4 e0 |..($q.g..^).....|
+00000030 33 76 dc 66 c6 95 c0 3a 15 49 99 09 2f cf 6b 6b |3v.f...:.I../.kk|
+00000040 a1 8f 1a e4 af 8d 1e 7f 02 b1 87 17 03 03 00 21 |...............!|
+00000050 24 71 bf 67 14 d6 5e 2a 61 7b 98 dd e8 52 b0 1e |$q.g..^*a{...R..|
+00000060 28 46 28 de e2 22 65 6c 66 85 3a 1d bb 9e 76 a2 |(F(.."elf.:...v.|
+00000070 55 16 03 03 00 1c 24 71 bf 67 14 d6 5e 2b bb 84 |U.....$q.g..^+..|
+00000080 6d f0 1c d0 46 89 bb b2 09 96 dd 95 53 bf ac d7 |m...F.......S...|
+00000090 80 f1 |..|
+>>> Flow 11 (client to server)
+00000000 16 03 03 00 a9 00 00 00 00 00 00 00 01 61 12 ee |.............a..|
+00000010 0a f2 5e e2 3d 3d 36 4c 14 10 20 aa 4d 8a 91 e4 |..^.==6L.. .M...|
+00000020 c2 b0 63 68 9e f5 71 b7 a4 ee 75 27 20 8c 2e 21 |..ch..q...u' ..!|
+00000030 f5 57 3d e9 9a 05 da 7b a5 af 6a 17 10 8b eb 25 |.W=....{..j....%|
+00000040 8a 79 75 07 dc fe f5 7f a5 e2 63 31 ee 55 ba c0 |.yu.......c1.U..|
+00000050 e6 3d de 03 36 2b 64 19 b1 1a b8 80 09 25 8c dd |.=..6+d......%..|
+00000060 dd 59 c7 1d e7 40 20 ae ca a9 b5 14 a7 57 f0 62 |.Y...@ ......W.b|
+00000070 71 88 a3 2c fc a4 50 dc 8b 85 22 20 38 c5 74 ea |q..,..P..." 8.t.|
+00000080 ac 33 1d a3 c5 5c cc 10 62 fd c5 70 22 fa e3 73 |.3...\..b..p"..s|
+00000090 f3 bf 24 14 0d cb 7c 25 e4 74 6c fe c0 70 5e a0 |..$...|%.tl..p^.|
+000000a0 63 a7 e5 f2 6e d8 71 bd 7d b9 f0 b6 0b 70 |c...n.q.}....p|
+>>> Flow 12 (server to client)
+00000000 16 03 03 00 89 24 71 bf 67 14 d6 5e 2c 55 62 31 |.....$q.g..^,Ub1|
+00000010 5c a3 53 1a c3 2f 89 47 62 33 7e 24 cd ad a9 5b |\.S../.Gb3~$...[|
+00000020 51 79 d8 08 08 ff 09 3c 41 c7 80 ed ec 5a 7a e4 |Qy.....<A....Zz.|
+00000030 71 e1 17 91 5e c1 80 58 35 c7 27 ca 62 74 cc d8 |q...^..X5.'.bt..|
+00000040 e8 35 86 97 bf 05 73 b9 3f ae 5b af 9a 14 88 4b |.5....s.?.[....K|
+00000050 f9 6f a4 de 3d 45 c8 7b 0a b1 7a 81 3e 7c 02 b5 |.o..=E.{..z.>|..|
+00000060 e9 43 a5 64 88 59 f6 55 20 d1 09 39 cd 01 46 0f |.C.d.Y.U ..9..F.|
+00000070 a2 06 f3 2b 45 14 b2 57 21 2c 2f a0 e5 db 02 99 |...+E..W!,/.....|
+00000080 e4 6b 1e 22 99 c9 ae 93 e4 67 89 d1 c6 6d 16 03 |.k.".....g...m..|
+00000090 03 02 89 24 71 bf 67 14 d6 5e 2d ce 6a 42 6b ce |...$q.g..^-.jBk.|
+000000a0 07 4e ff 40 39 4b 00 c8 14 4c 76 e0 4d 09 41 c3 |.N.@9K...Lv.M.A.|
+000000b0 41 3a ca ac 28 06 01 80 e4 b8 73 a2 fc ea 8d 92 |A:..(.....s.....|
+000000c0 44 0e 43 3e d8 cb 8a 0c a0 c1 5e 88 6d 6d 80 be |D.C>......^.mm..|
+000000d0 9c 9f cc 20 7c fa 6f e4 1a a1 39 c2 a8 7d 04 85 |... |.o...9..}..|
+000000e0 75 5d c4 d3 6f df d7 3a 9d 83 c3 74 aa 49 df 34 |u]..o..:...t.I.4|
+000000f0 e0 41 ad a3 80 80 c3 29 44 b9 5f a1 7b 67 89 30 |.A.....)D._.{g.0|
+00000100 04 b0 90 78 6b 82 fe ae 0c eb e1 5a 64 e2 6f de |...xk......Zd.o.|
+00000110 de 12 db 4f 1f eb 1d a9 66 a1 62 11 ab 54 1f 5d |...O....f.b..T.]|
+00000120 c2 ce 1e a8 b3 8b 29 08 76 13 a0 67 5b e6 1b 2c |......).v..g[..,|
+00000130 bd 1b 42 80 a5 09 b0 03 28 df 77 6f a7 d5 2f 85 |..B.....(.wo../.|
+00000140 2b b1 69 81 5c a0 16 16 1c eb b4 61 f1 f7 70 55 |+.i.\......a..pU|
+00000150 ee 64 9d 8f 1a 0b af af 18 f5 da e6 32 ab b2 28 |.d..........2..(|
+00000160 0d a0 ea b4 44 3d a9 f7 1a 84 c1 8f 30 09 41 13 |....D=......0.A.|
+00000170 a3 34 79 a7 6f da 76 59 62 9f d6 82 0f 48 21 64 |.4y.o.vYb....H!d|
+00000180 11 49 53 cd 3a 44 5a dc 8b 97 8a 84 d2 f9 12 77 |.IS.:DZ........w|
+00000190 b3 5b b0 37 58 7a a3 5a 47 9d c7 e4 83 f5 0a 32 |.[.7Xz.ZG......2|
+000001a0 10 39 aa d6 7c 8e 44 eb a9 fd 0f c0 6a 80 82 21 |.9..|.D.....j..!|
+000001b0 30 d1 36 31 73 38 c5 bd 16 99 71 b5 49 8e 7f df |0.61s8....q.I...|
+000001c0 f9 64 7f ff 16 3b 68 7c b5 7c 1f 41 19 36 dd ef |.d...;h|.|.A.6..|
+000001d0 65 11 b9 91 c4 d4 40 eb 37 94 69 8b 3b 10 56 45 |e.....@.7.i.;.VE|
+000001e0 ee 56 a8 a7 3d 94 17 5c fe f2 88 c7 fb 78 8e 51 |.V..=..\.....x.Q|
+000001f0 53 a8 bc b3 88 ee 75 42 1d 41 b8 c5 34 d5 9e bc |S.....uB.A..4...|
+00000200 b4 b7 1c 97 8b 83 d6 3d 97 4b 43 7a 40 3d 63 6e |.......=.KCz@=cn|
+00000210 cf 57 9a d3 71 6d 54 fe 38 ec 6f d7 c3 aa 1c a8 |.W..qmT.8.o.....|
+00000220 2b f6 34 96 cb 16 da 3e 2d 74 dd f6 1c 33 3c 4e |+.4....>-t...3<N|
+00000230 25 d9 e3 c5 85 52 c3 ea 22 ea 86 16 84 31 05 a4 |%....R.."....1..|
+00000240 7d 41 00 bd 4a b3 79 93 18 1c a1 e4 78 1c 90 49 |}A..J.y.....x..I|
+00000250 b4 9f bc d3 2d d0 f9 46 da 13 7c f6 88 5e e1 b2 |....-..F..|..^..|
+00000260 5c 41 12 bf 2f 1f b4 c3 13 8c 2f a6 83 c5 86 ba |\A../...../.....|
+00000270 20 42 21 57 e1 78 82 0e 4b 55 32 c1 f2 6e 4c a2 | B!W.x..KU2..nL.|
+00000280 a7 c7 63 b3 b5 30 49 9d 7a 51 5e 67 38 52 89 ee |..c..0I.zQ^g8R..|
+00000290 51 16 34 5c f6 b1 04 30 7b f4 b0 f8 88 6c 9d bc |Q.4\...0{....l..|
+000002a0 32 5d 8b 73 b0 df f6 a2 dd e7 62 94 d7 b7 68 92 |2].s......b...h.|
+000002b0 d6 a6 6a b2 53 75 d8 a7 43 1f 1e a2 c0 4e 6a 84 |..j.Su..C....Nj.|
+000002c0 e7 6d ae 81 82 dc 43 bd 8c 44 6a db ec 37 34 70 |.m....C..Dj..74p|
+000002d0 a0 e3 39 a1 17 d2 b7 53 bc 06 0e 33 3f 91 b3 a6 |..9....S...3?...|
+000002e0 0a d1 43 b0 94 54 bc b9 07 52 40 6e 49 99 ab 09 |..C..T...R@nI...|
+000002f0 3f dc 5d 5f c9 33 59 03 3f cf 7b 47 54 2d 05 4b |?.]_.3Y.?.{GT-.K|
+00000300 c2 e6 81 f5 2f 58 5d 84 ad 9d 72 cc 3b 09 70 50 |..../X]...r.;.pP|
+00000310 75 f8 c8 b7 9a 3f b7 3e aa 6a 75 5d 16 03 03 00 |u....?.>.ju]....|
+00000320 e5 24 71 bf 67 14 d6 5e 2e 0b f5 20 45 e5 51 07 |.$q.g..^... E.Q.|
+00000330 98 f0 75 3c 5c f3 16 88 ba e7 76 fe 10 18 41 38 |..u<\.....v...A8|
+00000340 d5 df 7f 8b d3 2e 1c 0a 4c 83 57 fc e5 63 35 68 |........L.W..c5h|
+00000350 6e 23 5b c3 0c 9d f9 ab f8 3c 86 b6 ec 54 ec 52 |n#[......<...T.R|
+00000360 a4 45 cf 7b 31 a7 04 ef 5b 0b b1 11 50 8c 95 25 |.E.{1...[...P..%|
+00000370 9a 17 9b 4d 65 9c 0b d3 bb 0d 98 10 d9 34 52 7a |...Me........4Rz|
+00000380 f8 1e 9e 78 cb 41 27 47 31 cb 25 42 90 e9 3c 02 |...x.A'G1.%B..<.|
+00000390 49 17 01 5f 06 d2 f4 58 35 75 d5 9d 54 65 15 0d |I.._...X5u..Te..|
+000003a0 02 7e 94 fd c8 ac b8 c4 97 1c 9a 1c 9a 23 d5 d3 |.~...........#..|
+000003b0 44 c6 9a dd f9 b4 d1 48 e9 3d a0 5b d4 66 b3 d9 |D......H.=.[.f..|
+000003c0 11 0c d5 6d 0e 06 9c 00 90 30 d7 97 06 dc 0e e2 |...m.....0......|
+000003d0 59 51 7f b5 2e b8 f7 eb be 66 56 fa 9d a4 92 db |YQ.......fV.....|
+000003e0 82 3a d9 fc bd da c5 23 f6 2c 7b 36 2f a8 57 8e |.:.....#.,{6/.W.|
+000003f0 c6 0a 48 50 e3 f4 e7 07 95 48 9b 45 a9 ba cb e0 |..HP.....H.E....|
+00000400 3e ee 10 f9 0e cc 16 03 03 00 46 24 71 bf 67 14 |>.........F$q.g.|
+00000410 d6 5e 2f 97 87 ae b8 b4 fb f1 67 2b e7 0f f4 be |.^/.......g+....|
+00000420 24 0a f8 4a c0 42 4b 40 d3 ea e7 e0 f7 2a 9b 80 |$..J.BK@.....*..|
+00000430 bb 62 c0 2d d5 f8 52 19 49 d4 4c 45 1d c2 28 e7 |.b.-..R.I.LE..(.|
+00000440 8f fd b2 47 0e 22 d1 e1 b1 33 c1 26 6a fd 3f 9f |...G."...3.&j.?.|
+00000450 d8 |.|
+>>> Flow 13 (client to server)
+00000000 16 03 03 02 89 00 00 00 00 00 00 00 02 32 20 c7 |.............2 .|
+00000010 66 2d 3f e5 9b f9 e0 1c 7c 1f 3e 21 d9 51 af 9a |f-?.....|.>!.Q..|
+00000020 60 65 99 c7 3e 0b 48 f2 a3 8f eb ea 75 da af 60 |`e..>.H.....u..`|
+00000030 2e 5b ac 7f 9f d1 1f 69 86 18 49 3b 18 a2 e5 c5 |.[.....i..I;....|
+00000040 d0 c7 fe 3e c6 15 3d 5d 04 4d aa 7e 28 e3 20 d3 |...>..=].M.~(. .|
+00000050 55 c2 ed 4f 61 5f cc f9 39 5f 7d 3a 0f f2 81 5d |U..Oa_..9_}:...]|
+00000060 fd 4e 86 92 12 cd 2b b7 e6 46 49 b7 b8 5f 8f e5 |.N....+..FI.._..|
+00000070 b7 5e 64 2f 13 33 65 1c c8 c4 38 bd 70 94 23 e9 |.^d/.3e...8.p.#.|
+00000080 b6 57 81 c8 23 d1 57 85 91 c5 bc 5b 33 55 eb f5 |.W..#.W....[3U..|
+00000090 2d b3 76 53 44 e2 e8 66 fe 42 de f8 6f 03 37 d4 |-.vSD..f.B..o.7.|
+000000a0 a0 a4 75 7a 03 7f 00 92 eb 45 2f b8 5d 01 d3 4b |..uz.....E/.]..K|
+000000b0 e7 ca 2f 5b 3b 20 67 dc 32 2a 4c 06 1b 03 97 c1 |../[; g.2*L.....|
+000000c0 38 40 35 79 31 25 b0 fe d8 f3 b7 ee 6c ad 62 3e |8@5y1%......l.b>|
+000000d0 60 d6 96 6a 10 2b 14 8a 9e 72 f4 c9 63 6a 63 14 |`..j.+...r..cjc.|
+000000e0 d1 b0 e4 1f e9 3d 85 9d ed 11 3f 85 eb fa ca 46 |.....=....?....F|
+000000f0 17 f8 45 d5 65 28 79 8d 63 8e d7 22 40 9f c7 25 |..E.e(y.c.."@..%|
+00000100 ae e0 72 9f 60 70 95 59 99 25 41 1a e6 e9 45 cb |..r.`p.Y.%A...E.|
+00000110 3d 5a 2e 2d 4d c2 3c f2 3a 01 61 1f 96 d7 78 1a |=Z.-M.<.:.a...x.|
+00000120 cd 14 bd 87 75 23 10 7f 67 e4 8e fa 0a 9d 5d e9 |....u#..g.....].|
+00000130 12 f8 c7 35 c1 37 4c a4 91 a1 a5 de 79 9a a7 9c |...5.7L.....y...|
+00000140 ce d2 c9 72 a8 fa a3 27 24 8d 14 4e d7 11 f3 e9 |...r...'$..N....|
+00000150 07 4d 6d 47 92 4d e2 75 9a 71 d0 1e dd 09 61 0e |.MmG.M.u.q....a.|
+00000160 16 36 84 3a b1 dd 9b f8 09 dd 73 78 ed f7 29 4e |.6.:......sx..)N|
+00000170 a6 29 b0 31 54 72 ac 4b 7a 49 13 ba 9b ef b6 8b |.).1Tr.KzI......|
+00000180 48 dd a1 a7 9d 25 0e b7 37 42 5f 70 27 a7 59 40 |H....%..7B_p'.Y@|
+00000190 fe 72 1a 23 3e 71 b7 56 ef ff 02 c0 c9 07 99 20 |.r.#>q.V....... |
+000001a0 19 d2 9e 65 a5 5e f1 15 d3 ec 6e bb b1 c4 bf c0 |...e.^....n.....|
+000001b0 f8 71 19 bc 77 30 93 72 33 eb 1b c0 62 07 5e ca |.q..w0.r3...b.^.|
+000001c0 4a bf 89 5d 5d 44 23 fb 58 8e 71 b4 58 41 b9 97 |J..]]D#.X.q.XA..|
+000001d0 8b da b6 a0 b6 40 54 46 01 b9 47 79 21 bc 7c f3 |.....@TF..Gy!.|.|
+000001e0 4c 46 a3 92 ce d6 ec ac 3b 5d 6f 19 65 d1 b0 cd |LF......;]o.e...|
+000001f0 19 cd 2e 9d 6e 7d d3 57 44 c2 dd c6 56 dd e6 2b |....n}.WD...V..+|
+00000200 06 c6 f1 46 f1 ba ce e6 d9 c8 1e 03 5d b5 15 37 |...F........]..7|
+00000210 9d 8a d2 01 e7 28 33 30 a2 2b a3 42 d1 05 2f e9 |.....(30.+.B../.|
+00000220 7f 50 bf c8 7f 7b f8 c7 7e 12 3f 97 5e d5 1c 34 |.P...{..~.?.^..4|
+00000230 eb bf 2e c2 f0 6b 36 4e 09 c9 73 0e bb 3a cd f8 |.....k6N..s..:..|
+00000240 5f 2a 13 4d f2 92 b3 ae 4f dd 0e 82 a0 58 a9 be |_*.M....O....X..|
+00000250 2f c1 20 5c 64 48 11 e3 66 18 22 4d ea aa 76 21 |/. \dH..f."M..v!|
+00000260 07 ac 5a f2 14 38 a7 d8 9a 58 f8 92 62 77 3c 59 |..Z..8...X..bw<Y|
+00000270 1a 31 4e 3f 56 55 2b 9f 87 96 9c 7e c5 f0 10 fa |.1N?VU+....~....|
+00000280 90 a1 0b 9e e4 66 74 99 80 da 58 85 3d bd 16 03 |.....ft...X.=...|
+00000290 03 00 5e 00 00 00 00 00 00 00 03 42 d9 1d 19 27 |..^........B...'|
+000002a0 98 c0 29 9e bc 35 99 e9 e9 de f5 7c b7 2f ce a1 |..)..5.....|./..|
+000002b0 48 fe a9 79 26 c3 f1 74 63 73 3b 8d b7 4c 47 11 |H..y&..tcs;..LG.|
+000002c0 7c ea 6d 09 4c 1c 10 1d c9 b4 63 d4 5e c4 f1 34 ||.m.L.....c.^..4|
+000002d0 94 63 1c 04 a1 5f d0 65 7c b6 dd 2b a3 1c 1b 5f |.c..._.e|..+..._|
+000002e0 5c d6 dc 7f e7 df c4 75 ad df cc ae 71 47 64 cc |\......u....qGd.|
+000002f0 96 16 03 03 00 a0 00 00 00 00 00 00 00 04 61 37 |..............a7|
+00000300 a3 98 54 d1 7c 5d 14 b9 04 72 6e 02 ab 1a 15 2c |..T.|]...rn....,|
+00000310 93 07 15 ab 56 b1 ac d5 75 75 2e 25 ae 5e 3f fa |....V...uu.%.^?.|
+00000320 d0 20 ff 9d e0 ef fd 25 ed 4d 60 56 c7 33 07 d0 |. .....%.M`V.3..|
+00000330 57 09 e4 12 bd aa f0 d2 cc de 0d 45 23 ab b6 67 |W..........E#..g|
+00000340 ea d3 bc e1 4d 3a 75 9f 2d bb 53 b4 70 67 ce 63 |....M:u.-.S.pg.c|
+00000350 83 29 fa 27 2b db ea a3 19 be 79 77 cd 75 fb bf |.).'+.....yw.u..|
+00000360 c1 27 86 a6 a9 27 06 49 e1 77 13 0d e4 78 0c 07 |.'...'.I.w...x..|
+00000370 d4 1c af 76 f4 7b 05 04 5f 0f ec 66 f9 03 3e 81 |...v.{.._..f..>.|
+00000380 41 be 24 5f 43 2a 99 56 06 a9 d7 be ca 62 46 a2 |A.$_C*.V.....bF.|
+00000390 ba e1 a6 8b 1b 0a 14 03 03 00 19 00 00 00 00 00 |................|
+000003a0 00 00 05 f9 8f d4 80 bf ed b3 38 3a 12 d9 91 b6 |..........8:....|
+000003b0 cf 87 1a 1b 16 03 03 00 28 00 00 00 00 00 00 00 |........(.......|
+000003c0 00 fb 80 da 9a 59 82 9d d2 35 57 57 dd 76 a1 b1 |.....Y...5WW.v..|
+000003d0 4a dc a5 cb f6 81 3f e3 4d cc 0e 7f 3a 96 85 f3 |J.....?.M...:...|
+000003e0 ea |.|
+>>> Flow 14 (server to client)
+00000000 14 03 03 00 19 24 71 bf 67 14 d6 5e 30 cc 1c 3f |.....$q.g..^0..?|
+00000010 3c 20 07 b3 c3 79 d0 6e fd 59 e6 0d 47 fd 16 03 |< ...y.n.Y..G...|
+00000020 03 00 28 54 db a5 f7 3d b3 18 49 39 e5 59 93 bb |..(T...=..I9.Y..|
+00000030 64 93 1c ed 46 d6 f8 89 94 45 ba 4a 9e 73 2e cb |d...F....E.J.s..|
+00000040 03 18 e4 26 6d 33 e3 34 73 d6 fc 17 03 03 00 21 |...&m3.4s......!|
+00000050 54 db a5 f7 3d b3 18 4a aa 45 38 3b 50 02 44 37 |T...=..J.E8;P.D7|
+00000060 6a d1 3e f9 d3 3b 33 33 d5 84 2d 52 33 7d 68 84 |j.>..;33..-R3}h.|
+00000070 ef |.|
+>>> Flow 15 (client to server)
+00000000 15 03 03 00 1a 00 00 00 00 00 00 00 01 55 5f 94 |.............U_.|
+00000010 25 d0 89 86 cb 8f 33 6f b7 b6 35 ec 0f 6a 87 |%.....3o..5..j.|
diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
new file mode 100644
index 0000000..fe2fa88
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
@@ -0,0 +1,255 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 00 00 00 00 00 |................|
+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 22 c0 2f |............."./|
+00000030 c0 2b c0 30 c0 2c c0 11 c0 07 c0 13 c0 09 c0 14 |.+.0.,..........|
+00000040 c0 0a 00 9c 00 9d 00 05 00 2f 00 35 c0 12 00 0a |........./.5....|
+00000050 01 00 00 36 00 05 00 05 01 00 00 00 00 00 0a 00 |...6............|
+00000060 08 00 06 00 17 00 18 00 19 00 0b 00 02 01 00 00 |................|
+00000070 0d 00 0e 00 0c 04 01 04 03 05 01 05 03 02 01 02 |................|
+00000080 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 51 0e b9 8f 73 |....Y...U..Q...s|
+00000010 ec 20 17 90 80 3a 43 7a bc 19 19 f5 75 c3 76 a6 |. ...:Cz....u.v.|
+00000020 53 53 4b 77 ce dd ca 4b 1b 1e ed 20 8d e5 a7 6f |SSKw...K... ...o|
+00000030 53 e9 a4 06 4b 01 a6 08 a1 90 e5 da c9 e3 74 b0 |S...K.........t.|
+00000040 87 1f 17 1a 68 d3 f7 ae 39 b8 3e 80 c0 2f 00 00 |....h...9.>../..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 71 0b 00 02 6d 00 02 6a 00 02 67 30 82 02 |..q...m..j..g0..|
+00000070 63 30 82 01 cc a0 03 02 01 02 02 09 00 a2 73 00 |c0............s.|
+00000080 0c 81 00 cb f3 30 0d 06 09 2a 86 48 86 f7 0d 01 |.....0...*.H....|
+00000090 01 0b 05 00 30 2b 31 17 30 15 06 03 55 04 0a 13 |....0+1.0...U...|
+000000a0 0e 47 6f 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 |.Google TESTING1|
+000000b0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000c0 74 30 1e 17 0d 31 35 30 31 30 31 30 30 30 30 30 |t0...15010100000|
+000000d0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000e0 5a 30 26 31 17 30 15 06 03 55 04 0a 13 0e 47 6f |Z0&1.0...U....Go|
+000000f0 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 0b 30 09 |ogle TESTING1.0.|
+00000100 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+00000110 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000120 81 89 02 81 81 00 af 87 88 f6 20 1b 95 65 6c 14 |.......... ..el.|
+00000130 ab 44 05 af 3b 45 14 e3 b7 6d fd 00 63 4d 95 7f |.D..;E...m..cM..|
+00000140 fe 6a 62 35 86 c0 4a f9 18 7c f6 aa 25 5e 7a 64 |.jb5..J..|..%^zd|
+00000150 31 66 00 ba f4 8e 92 af c7 6b d8 76 d4 f3 5f 41 |1f.......k.v.._A|
+00000160 cb 6e 56 15 97 1b 97 c1 3c 12 39 21 66 3d 2b 16 |.nV.....<.9!f=+.|
+00000170 d1 bc db 1c c0 a7 da b7 ca ad ba da cb d5 21 50 |..............!P|
+00000180 ec de 8d ab d1 6b 81 4b 89 02 f3 c4 be c1 6c 89 |.....k.K......l.|
+00000190 b1 44 84 bd 21 d1 04 7d 9d 16 4d f9 82 15 f6 ef |.D..!..}..M.....|
+000001a0 fa d6 09 47 f2 fb 02 03 01 00 01 a3 81 93 30 81 |...G..........0.|
+000001b0 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001c0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001d0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001e0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001f0 06 03 55 1d 0e 04 12 04 10 12 50 8d 89 6f 1b d1 |..U.......P..o..|
+00000200 dc 54 4d 6e cb 69 5e 06 f4 30 1b 06 03 55 1d 23 |.TMn.i^..0...U.#|
+00000210 04 14 30 12 80 10 bf 3d b6 a9 66 f2 b8 40 cf ea |..0....=..f..@..|
+00000220 b4 03 78 48 1a 41 30 19 06 03 55 1d 11 04 12 30 |..xH.A0...U....0|
+00000230 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000240 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000250 03 81 81 00 92 7c af 91 55 12 18 96 59 31 a6 48 |.....|..U...Y1.H|
+00000260 40 d5 2d d5 ee bb 02 a0 f5 c2 1e 7c 9b b3 30 7d |@.-........|..0}|
+00000270 3c dc 76 da 4f 3d c0 fa ae 2d 33 24 6b 03 7b 1b |<.v.O=...-3$k.{.|
+00000280 67 59 11 21 b5 11 bc 77 b9 d9 e0 6e a8 2d 2e 35 |gY.!...w...n.-.5|
+00000290 fa 64 5f 22 3e 63 10 6b be ff 14 86 6d 0d f0 15 |.d_">c.k....m...|
+000002a0 31 a8 14 38 1e 3b 84 87 2c cb 98 ed 51 76 b9 b1 |1..8.;..,...Qv..|
+000002b0 4f dd db 9b 84 04 86 40 fa 51 dd ba b4 8d eb e3 |O......@.Q......|
+000002c0 46 de 46 b9 4f 86 c7 f9 a4 c2 41 34 ac cc f6 ea |F.F.O.....A4....|
+000002d0 b0 ab 39 18 16 03 03 00 cd 0c 00 00 c9 03 00 17 |..9.............|
+000002e0 41 04 5e 2e 43 b7 c2 0f e8 4a 33 aa b8 d6 04 7f |A.^.C....J3.....|
+000002f0 2b be a2 e3 6f fa 05 1a d1 64 a7 d1 ec 45 f9 16 |+...o....d...E..|
+00000300 b7 75 ad f2 52 3e a3 60 67 f8 fb 87 a0 c0 d4 2f |.u..R>.`g....../|
+00000310 f4 66 c9 dd 38 40 79 5b 16 75 0b 16 6a d8 e5 ad |.f..8@y[.u..j...|
+00000320 63 f3 04 01 00 80 5e 89 b3 6b f4 a1 35 b3 27 be |c.....^..k..5.'.|
+00000330 6a d4 39 42 7c ac e2 d4 9f a0 a0 a3 95 22 b5 09 |j.9B|........"..|
+00000340 70 4a 0c 6f cf 7f 69 f9 7d 27 c4 0d e7 b8 9c 82 |pJ.o..i.}'......|
+00000350 c9 0d 1d bb 5c 23 20 eb ca 09 ca 02 a0 56 27 10 |....\# ......V'.|
+00000360 c5 d6 13 7d cd 05 64 cc 53 20 5d df ac 00 90 7f |...}..d.S ].....|
+00000370 d7 cd f2 a1 07 9c 06 c2 e6 d1 94 60 d3 c6 97 a6 |...........`....|
+00000380 3c e5 89 67 e7 cc b7 c1 ba 75 dc 17 2b 47 ce 23 |<..g.....u..+G.#|
+00000390 a3 37 3b 3f 32 39 ae 4a 64 17 d2 64 d1 75 23 8a |.7;?29.Jd..d.u#.|
+000003a0 e3 b4 fa 75 17 72 16 03 03 00 04 0e 00 00 00 |...u.r.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1e 18 37 ef 0d |....F...BA...7..|
+00000010 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd |.Q.5uq..T[....g.|
+00000020 a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e |.$ >.V...(^.+-O.|
+00000030 f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 |...lK[.V.2B.X..I|
+00000040 a6 b5 68 1a 41 03 56 6b dc 5a 89 14 03 03 00 01 |..h.A.Vk.Z......|
+00000050 01 16 03 03 00 28 00 00 00 00 00 00 00 00 4f ef |.....(........O.|
+00000060 08 7c a7 de 53 70 7e 78 fb 08 79 97 1f bd 33 92 |.|..Sp~x..y...3.|
+00000070 c5 46 4d 64 32 bb 94 f0 07 ad 7d 00 86 9e |.FMd2.....}...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 59 c3 19 1f ed |..........(Y....|
+00000010 d1 1b 54 5b 66 81 47 29 9a 77 84 87 a0 bd c5 d4 |..T[f.G).w......|
+00000020 f0 4e e2 11 d3 1d 26 dd 87 7a 55 11 48 37 7f 3a |.N....&..zU.H7.:|
+00000030 2c fc 62 |,.b|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 02 12 57 |...............W|
+00000010 9d 64 c5 47 13 95 13 7b 2b 3e e0 f7 ae 49 0f c7 |.d.G...{+>...I..|
+00000020 0e 3a 67 |.:g|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 1c 59 c3 19 1f ed d1 1b 55 ac 23 dc |.....Y......U.#.|
+00000010 0c 35 65 1e 7a 65 4f 47 13 46 a0 d0 d0 4d 0a 1f |.5e.zeOG.F...M..|
+00000020 5c |\|
+>>> Flow 7 (client to server)
+00000000 16 03 03 00 a9 00 00 00 00 00 00 00 02 c0 05 0c |................|
+00000010 76 0a 46 19 16 17 a6 75 af 11 bb 73 37 74 a4 26 |v.F....u...s7t.&|
+00000020 d9 16 93 b8 19 5e 2f 17 52 d1 12 9e 36 90 4e c9 |.....^/.R...6.N.|
+00000030 7a f9 89 75 3b d9 d4 e1 2e cf a0 5d 03 7d cc f6 |z..u;......].}..|
+00000040 73 aa a9 52 c7 65 78 d0 89 6f b1 15 6e f9 9e 55 |s..R.ex..o..n..U|
+00000050 42 9e 22 09 df 97 00 31 b8 73 57 1b 93 ff 0c e7 |B."....1.sW.....|
+00000060 46 29 40 79 a7 c0 de b9 44 93 7b 4d 35 a0 35 65 |F)@y....D.{M5.5e|
+00000070 6e 58 07 90 2b 11 49 26 10 f7 c7 32 f7 8e 6e a7 |nX..+.I&...2..n.|
+00000080 9b 75 ba cb 4a ce f7 f0 f1 31 ca 04 a6 02 d0 62 |.u..J....1.....b|
+00000090 da 9b 8b 27 8e 04 b8 4a 49 0d d6 31 10 93 30 37 |...'...JI..1..07|
+000000a0 ad ea d7 c4 49 98 90 f3 a1 45 f4 69 2e 59 |....I....E.i.Y|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 89 59 c3 19 1f ed d1 1b 56 c8 38 86 |.....Y......V.8.|
+00000010 22 b6 5f 55 cb 0c e1 40 e6 12 f2 71 d5 09 bc 47 |"._U...@...q...G|
+00000020 ea 83 38 3a 58 f4 34 da ae 7f 64 fb 8c bc 71 64 |..8:X.4...d...qd|
+00000030 1b aa 84 e4 3e c1 cc c4 a9 05 36 13 5a 9b 1e c0 |....>.....6.Z...|
+00000040 44 cc 86 54 f0 75 b7 d0 aa b0 f0 3a b5 c7 f1 cc |D..T.u.....:....|
+00000050 1f cd 8e 9e 9e bb 24 23 c3 05 0b a5 1d f3 0b 41 |......$#.......A|
+00000060 41 19 89 1e ee 51 fc b3 e8 e2 6e a8 3f c4 8b ab |A....Q....n.?...|
+00000070 cb af d9 a1 7e 1c db e7 6c f6 23 71 c6 31 db 40 |....~...l.#q.1.@|
+00000080 a8 a7 08 fb 1a ff 8d 94 53 88 9a 11 73 6a 16 03 |........S...sj..|
+00000090 03 02 89 59 c3 19 1f ed d1 1b 57 17 dd 9c b5 a5 |...Y......W.....|
+000000a0 89 12 3a 14 61 34 e0 1d 0b 35 d6 3a 6c 09 93 2b |..:.a4...5.:l..+|
+000000b0 6c 69 ee f4 f3 be fb 42 33 99 fd 9a e6 21 38 68 |li.....B3....!8h|
+000000c0 a6 19 37 43 24 81 ba 35 12 fe ab ed 49 0b 03 54 |..7C$..5....I..T|
+000000d0 11 a7 74 4d bb ba e7 b9 f3 ee 6a 4e 1a 84 2f 03 |..tM......jN../.|
+000000e0 0c d1 28 21 49 84 f4 3c 5b 15 92 07 5c 6a 24 89 |..(!I..<[...\j$.|
+000000f0 00 cf 78 31 76 23 0f 9d 45 3b 93 a5 68 ee 9c 73 |..x1v#..E;..h..s|
+00000100 14 3f 08 30 37 40 4e 8b a4 02 03 3c 4b 52 74 99 |.?.07@N....<KRt.|
+00000110 0e 9a ec 40 c6 74 16 ef c5 48 68 33 86 d7 06 57 |...@.t...Hh3...W|
+00000120 bf 8a 6f 3f 41 fe 4d f2 37 0a 1b fd fb 66 55 bd |..o?A.M.7....fU.|
+00000130 70 4d b0 8c 4f 78 24 eb 1f 8f 22 c7 aa 07 89 04 |pM..Ox$...".....|
+00000140 6a b3 07 15 37 25 21 63 97 39 b1 c1 9b fa 81 5e |j...7%!c.9.....^|
+00000150 69 c9 c7 4a 9c 5d b3 6a 41 d0 5e b9 f4 d5 5c a1 |i..J.].jA.^...\.|
+00000160 8e 8a ad 58 6e 5c 4f 73 62 38 1c 5f 8d b1 67 63 |...Xn\Osb8._..gc|
+00000170 49 da 4b 4e 83 54 34 8f 8d 12 de 4e 43 4d dc b9 |I.KN.T4....NCM..|
+00000180 02 ab 08 59 db 0b 45 7e f5 b8 e2 33 f1 04 de 16 |...Y..E~...3....|
+00000190 05 bf b4 2b 07 a1 11 e4 9e 48 f7 52 ab 20 89 04 |...+.....H.R. ..|
+000001a0 a7 44 28 7a 12 6c 19 ab 2f 68 1a d9 26 ec 72 a0 |.D(z.l../h..&.r.|
+000001b0 62 83 48 6f 4b 70 7d 74 3a 43 4f a6 38 37 fe 59 |b.HoKp}t:CO.87.Y|
+000001c0 6e 72 5d 81 7d 2c c7 e1 6b 06 47 41 56 17 2c 25 |nr].},..k.GAV.,%|
+000001d0 06 b1 7f f5 10 0a 31 a3 12 b1 5c 01 2f e0 a6 e4 |......1...\./...|
+000001e0 fa ab d2 0b 02 77 ad ac f8 54 db 70 20 0a 1f 04 |.....w...T.p ...|
+000001f0 86 a8 32 05 26 ee 7d e0 e9 03 19 cc 8f 67 f5 b6 |..2.&.}......g..|
+00000200 97 fe 06 5e c1 d5 df 25 f5 39 70 64 57 a8 c9 84 |...^...%.9pdW...|
+00000210 8f 0f 25 f8 c8 f9 17 70 e5 00 3c 4a 9f 4b c1 d9 |..%....p..<J.K..|
+00000220 6e b8 1a e4 6d 85 a4 e2 42 44 71 ba 43 9b 03 70 |n...m...BDq.C..p|
+00000230 14 ff 72 5e 5c 69 24 2e 52 0c 73 8b df 50 99 68 |..r^\i$.R.s..P.h|
+00000240 57 81 c1 ed b6 33 fc 74 15 45 fd a2 c4 8c f8 95 |W....3.t.E......|
+00000250 bf 8d 0e 92 91 42 72 77 03 ec c6 f6 9a 02 ca 7d |.....Brw.......}|
+00000260 3c 87 72 eb 8d 30 3a 5c b4 03 4a 6d 2e 83 22 c5 |<.r..0:\..Jm..".|
+00000270 e2 4a 95 83 7a 72 72 f2 2a 11 25 4a bd 04 16 ab |.J..zrr.*.%J....|
+00000280 6a 48 44 2b 99 fb 6f 61 9a 14 4a 42 1e bf d1 82 |jHD+..oa..JB....|
+00000290 db 62 5f ac 1e 6d 1d 1b 0d 4b 9d 8d 3a 84 94 b4 |.b_..m...K..:...|
+000002a0 aa 08 5b 90 7f d2 46 b0 a7 40 f4 55 76 6b 0d 4c |..[...F..@.Uvk.L|
+000002b0 8e e3 8c fd ed 33 7d 93 f8 d8 c3 db 26 2d db a1 |.....3}.....&-..|
+000002c0 24 bc b0 fb 26 5f ec 13 5f 97 05 bb 5c 3c cc a3 |$...&_.._...\<..|
+000002d0 c2 57 58 cd 2e 70 0c a7 77 c5 e5 e8 0c 42 f2 e0 |.WX..p..w....B..|
+000002e0 1c 11 0f 62 4b 84 49 c2 b7 10 83 2e 16 1c 38 d4 |...bK.I.......8.|
+000002f0 10 f7 ca 71 7a 87 c5 a3 66 d2 98 1e c8 f2 c0 37 |...qz...f......7|
+00000300 0e 28 31 fe 8e 3e f4 03 74 6e 91 42 22 cb 5d 7f |.(1..>..tn.B".].|
+00000310 d2 22 da 3c f2 a0 2d 09 a9 a5 2d 14 16 03 03 00 |.".<..-...-.....|
+00000320 e5 59 c3 19 1f ed d1 1b 58 3f 19 93 55 cb 19 f8 |.Y......X?..U...|
+00000330 02 1a 43 b3 b2 6c 4e 3e ee 99 b3 df fd 45 24 ac |..C..lN>.....E$.|
+00000340 63 e7 45 cc a4 44 ca cf 3a e1 81 88 01 9a b3 64 |c.E..D..:......d|
+00000350 fe 6b 36 57 9f 81 fc 40 8d ef 21 af 00 be 43 f7 |.k6W...@..!...C.|
+00000360 a3 3b a3 fa f0 01 f2 b4 ab 8a d1 a8 14 58 1b 6f |.;...........X.o|
+00000370 75 01 35 92 54 a7 a6 c1 99 1e 92 d8 87 53 7b 42 |u.5.T........S{B|
+00000380 4a 76 96 5e e9 db bb 4e f1 d9 bb e6 d2 b0 34 10 |Jv.^...N......4.|
+00000390 1b 4c d5 2c ca af 19 0d 3e 77 ee 77 0e 5f ff e2 |.L.,....>w.w._..|
+000003a0 02 c5 4a f2 ec 0b 7d cf d1 e7 3c 72 d2 17 4d 6c |..J...}...<r..Ml|
+000003b0 a7 ca 3a 1b 00 2b 69 17 e5 a9 82 69 49 c2 ff 8a |..:..+i....iI...|
+000003c0 f1 e8 ab 1b c3 8d da f1 31 ba a6 f4 7c 3c 01 6f |........1...|<.o|
+000003d0 ed a8 6f e2 4f a3 68 77 b7 54 b5 87 1b 5c 5c fb |..o.O.hw.T...\\.|
+000003e0 83 bf 48 4d 36 43 d6 f7 0a 48 74 f3 44 9d 43 53 |..HM6C...Ht.D.CS|
+000003f0 f8 54 1b 57 97 24 53 5a 93 e2 e9 33 f0 35 5f 0a |.T.W.$SZ...3.5_.|
+00000400 0d 4c ce 92 4d c9 16 03 03 00 46 59 c3 19 1f ed |.L..M.....FY....|
+00000410 d1 1b 59 80 50 fc 3a 56 e0 0b 06 b4 58 39 0c d8 |..Y.P.:V....X9..|
+00000420 4b b1 11 7a bd cf 1c 78 41 62 ee 22 74 61 7d 61 |K..z...xAb."ta}a|
+00000430 91 3d 0a 74 a4 b0 cd 25 70 19 a5 de d8 1b df 12 |.=.t...%p.......|
+00000440 4e b8 71 db ac bc 48 ea 89 32 ec 27 69 02 0d 8b |N.q...H..2.'i...|
+00000450 83 |.|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 89 00 00 00 00 00 00 00 03 be 8d 55 |...............U|
+00000010 8a 5b 24 10 db e3 f2 11 28 0d 26 cc 1b bc 38 fa |.[$.....(.&...8.|
+00000020 1c 8c f8 c9 64 55 ec 43 16 f7 ca af 12 a8 1c 09 |....dU.C........|
+00000030 0d b0 47 bc 9f 19 02 91 ab 9d 33 b4 bc 45 f7 4d |..G.......3..E.M|
+00000040 53 85 4a 91 7e d3 2d dc d6 02 6e 4a 34 51 99 db |S.J.~.-...nJ4Q..|
+00000050 f2 a1 8d 34 60 6f 15 6a f9 4d 7a 03 0b dc f7 c1 |...4`o.j.Mz.....|
+00000060 99 c2 2c b8 4c a1 63 ce a2 fb 33 0d d6 dd d4 0a |..,.L.c...3.....|
+00000070 88 0c 1d 5c ea 06 00 33 3a 06 6e 3d 63 b4 d5 0c |...\...3:.n=c...|
+00000080 9b 69 f0 86 72 db 47 52 3d 61 0b 66 57 8d 7b 67 |.i..r.GR=a.fW.{g|
+00000090 1e 42 aa b8 ca e6 d3 07 56 cf f5 09 14 25 a2 1d |.B......V....%..|
+000000a0 3b 3e dd 0c 41 ac 66 05 3b db 59 85 9d e2 9f 8b |;>..A.f.;.Y.....|
+000000b0 21 c0 9a 3b 0b 8e 5b 4b af ac 73 87 d3 b4 34 b7 |!..;..[K..s...4.|
+000000c0 2e 26 b0 5d 10 3a 2e 00 cc ac 40 b5 72 40 69 fa |.&.].:....@.r@i.|
+000000d0 11 04 b6 37 38 84 59 76 29 08 f0 0f 0f 79 40 7c |...78.Yv)....y@||
+000000e0 e4 08 15 b7 58 cd 6c f4 d6 77 d6 f8 cb 1d ca 5c |....X.l..w.....\|
+000000f0 41 d7 f8 64 63 14 a5 a5 3a 13 ce 55 b4 0a d9 b5 |A..dc...:..U....|
+00000100 34 f9 5e 69 f2 9a 62 88 b9 69 2f 93 08 2c 55 c4 |4.^i..b..i/..,U.|
+00000110 5d 0d cb 92 ac 2c 30 27 83 11 68 9f 74 35 5d 3a |]....,0'..h.t5]:|
+00000120 96 4c 57 91 95 a8 e7 03 fa b7 ae 8b 94 e3 39 38 |.LW...........98|
+00000130 6d e1 ad b1 f7 26 2c 90 d4 3c eb a5 5e df e4 29 |m....&,..<..^..)|
+00000140 39 ff ba d2 04 f4 b4 9c fa c2 da 34 bc 04 32 07 |9..........4..2.|
+00000150 db 52 38 fd 92 89 4c e9 50 13 e5 90 e7 f1 88 5e |.R8...L.P......^|
+00000160 c1 7a 9b fa 6e 1f 99 ce 52 77 0c 03 d8 a6 5d 64 |.z..n...Rw....]d|
+00000170 ab 58 82 93 10 a1 4f 35 ea a3 6d af a9 64 17 3d |.X....O5..m..d.=|
+00000180 fc a8 d8 9e 7e d7 44 af 2a c1 d6 a8 4d 78 b3 0b |....~.D.*...Mx..|
+00000190 d1 0b 3d 54 e2 c8 df 84 61 cb 92 1a d8 ce 23 a3 |..=T....a.....#.|
+000001a0 68 f7 af 40 53 09 f0 cc 00 7d 39 83 2c 6d f4 44 |h..@S....}9.,m.D|
+000001b0 d6 95 59 06 0a ef 9c 74 39 b3 70 cb 0a 0c 13 cd |..Y....t9.p.....|
+000001c0 ec 1f bf 75 93 01 1a 35 68 75 8b 80 15 80 7d a9 |...u...5hu....}.|
+000001d0 d0 25 9a 52 bc 02 bf 71 eb 60 76 2a 74 90 c8 16 |.%.R...q.`v*t...|
+000001e0 80 03 c2 a8 0c be 94 7c 12 b0 ee 45 3a 38 09 5a |.......|...E:8.Z|
+000001f0 bf 8b ca 78 f3 9e 79 8a 9f 65 57 84 f8 33 79 2a |...x..y..eW..3y*|
+00000200 f8 8c e0 c8 4b 9e 12 19 b1 3f ba cf 9d db 48 13 |....K....?....H.|
+00000210 b4 b0 53 0e 7a 6b 1d 21 13 45 37 8d 90 75 88 f9 |..S.zk.!.E7..u..|
+00000220 b5 9d 41 d0 ee 95 5f 6a e5 96 b6 48 ce 3b 43 20 |..A..._j...H.;C |
+00000230 47 15 db eb ba af 6d bf 38 26 e7 ad 86 ba 1e 91 |G.....m.8&......|
+00000240 be 8b df ba 5c 30 6e 3c 13 6a 96 68 13 24 bf 06 |....\0n<.j.h.$..|
+00000250 f1 d2 b0 05 8f 8e 21 7f 6a 09 5f b8 be 0b c5 5f |......!.j._...._|
+00000260 67 60 94 ec 78 65 6f 70 94 9b 15 82 07 f4 88 fb |g`..xeop........|
+00000270 a2 94 68 f7 57 0a 9c ec ab 3f 8f d5 83 ec 6a 24 |..h.W....?....j$|
+00000280 6f 88 4f 22 7f a1 82 cb ef ec 4c 33 b9 c1 16 03 |o.O"......L3....|
+00000290 03 00 5e 00 00 00 00 00 00 00 04 34 f9 69 a5 83 |..^........4.i..|
+000002a0 c5 86 34 51 f0 07 5b 44 51 36 c1 0d f7 71 c7 1b |..4Q..[DQ6...q..|
+000002b0 70 27 aa 35 cd c7 10 76 fd 96 27 dc bc 6f 39 ff |p'.5...v..'..o9.|
+000002c0 f1 a7 de e3 c5 21 70 e9 70 b1 52 d2 f0 be c0 72 |.....!p.p.R....r|
+000002d0 e5 aa 2b 1a 1d a8 8f 10 37 b5 2f c7 b9 32 c8 3c |..+.....7./..2.<|
+000002e0 7c c8 11 a5 dc aa 84 12 57 f1 ff 3b f9 04 a4 29 ||.......W..;...)|
+000002f0 24 16 03 03 00 a0 00 00 00 00 00 00 00 05 1a 86 |$...............|
+00000300 c7 35 6f 23 c5 38 85 85 0e 31 df 33 1a 42 6e f8 |.5o#.8...1.3.Bn.|
+00000310 c3 f7 81 29 aa 03 85 8c 5a 8a e1 9b 1c d3 6f 7d |...)....Z.....o}|
+00000320 36 41 45 30 06 2b dd 19 dc 22 9e 9e d4 bc 0e 51 |6AE0.+...".....Q|
+00000330 65 59 e9 7e 1b a1 d1 54 4b 3c 9a 41 de b9 43 98 |eY.~...TK<.A..C.|
+00000340 a5 ef 7a b8 77 69 f7 a5 80 02 d6 46 73 96 89 46 |..z.wi.....Fs..F|
+00000350 43 3a d7 ae 21 64 db 05 b5 7d fc 83 a3 75 ba ad |C:..!d...}...u..|
+00000360 0d d2 d6 9b 51 3b cb 37 85 46 92 b5 57 eb 2c dc |....Q;.7.F..W.,.|
+00000370 b2 8f e2 c0 7f 29 bf 5e bd f0 26 dd 31 e4 31 af |.....).^..&.1.1.|
+00000380 09 51 e4 26 09 56 a2 f4 5d fc c5 cb c8 da 51 ee |.Q.&.V..].....Q.|
+00000390 35 2e bb 3e ee bb 14 03 03 00 19 00 00 00 00 00 |5..>............|
+000003a0 00 00 06 b5 3d 07 af c9 3f ad f0 25 b4 5e b9 0f |....=...?..%.^..|
+000003b0 fa f0 16 48 16 03 03 00 28 00 00 00 00 00 00 00 |...H....(.......|
+000003c0 00 43 54 67 b4 f1 0e 1d 9d 7f ab f7 4c b6 77 3f |.CTg........L.w?|
+000003d0 d0 17 da 6a 61 75 a8 c8 42 47 fb 2a f7 22 85 02 |...jau..BG.*."..|
+000003e0 b0 |.|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 19 59 c3 19 1f ed d1 1b 5a 9d 51 67 |.....Y......Z.Qg|
+00000010 ff ed 61 fd 01 85 c2 46 f1 26 e1 08 c3 5b 16 03 |..a....F.&...[..|
+00000020 03 00 28 02 08 83 98 20 78 eb a5 8e f5 d3 31 b6 |..(.... x.....1.|
+00000030 6d 4b 3a 9c cd 76 30 ca 92 4b 6c 17 2c d8 c5 d5 |mK:..v0..Kl.,...|
+00000040 7d 59 76 f8 ff 0c 8f f4 f6 fb 81 17 03 03 00 21 |}Yv............!|
+00000050 02 08 83 98 20 78 eb a6 9b c6 07 33 3b 43 e4 5b |.... x.....3;C.[|
+00000060 c6 d4 31 6e 2b 5b 4a 65 c2 0a df 27 02 a2 3e 3b |..1n+[Je...'..>;|
+00000070 04 16 03 03 00 1c 02 08 83 98 20 78 eb a7 43 45 |.......... x..CE|
+00000080 df 9b 74 94 81 17 21 b1 7d d5 c0 7a 2b cc 38 a1 |..t...!.}..z+.8.|
+00000090 30 1d |0.|
+>>> Flow 11 (client to server)
+00000000 15 03 03 00 1a 00 00 00 00 00 00 00 01 d6 2b 5a |..............+Z|
+00000010 7d c9 ba d3 94 cc 45 26 1c 1e 1e 70 39 6c 4e 15 |}.....E&...p9lN.|
+00000020 03 03 00 1a 00 00 00 00 00 00 00 02 fd 76 21 e8 |.............v!.|
+00000030 b5 16 14 43 36 9f 61 14 6d 40 76 e3 14 11 |...C6.a.m@v...|
diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
new file mode 100644
index 0000000..90adc18
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 00 00 00 00 00 |................|
+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 22 c0 2f |............."./|
+00000030 c0 2b c0 30 c0 2c c0 11 c0 07 c0 13 c0 09 c0 14 |.+.0.,..........|
+00000040 c0 0a 00 9c 00 9d 00 05 00 2f 00 35 c0 12 00 0a |........./.5....|
+00000050 01 00 00 36 00 05 00 05 01 00 00 00 00 00 0a 00 |...6............|
+00000060 08 00 06 00 17 00 18 00 19 00 0b 00 02 01 00 00 |................|
+00000070 0d 00 0e 00 0c 04 01 04 03 05 01 05 03 02 01 02 |................|
+00000080 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 b1 7d c5 82 a4 |....Y...U...}...|
+00000010 f7 1d 3a b9 c0 da 13 7c 2f 75 22 a4 5f 2e 58 2a |..:....|/u"._.X*|
+00000020 39 eb 18 7c bb 0d 98 ba 51 2e 4a 20 41 40 2f 53 |9..|....Q.J A@/S|
+00000030 bc 16 e0 a4 44 07 f0 5e 8f 43 a3 69 87 0b 94 dd |....D..^.C.i....|
+00000040 60 a0 20 d0 25 e1 a1 a0 b8 0d d8 00 c0 2f 00 00 |`. .%......../..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 71 0b 00 02 6d 00 02 6a 00 02 67 30 82 02 |..q...m..j..g0..|
+00000070 63 30 82 01 cc a0 03 02 01 02 02 09 00 a2 73 00 |c0............s.|
+00000080 0c 81 00 cb f3 30 0d 06 09 2a 86 48 86 f7 0d 01 |.....0...*.H....|
+00000090 01 0b 05 00 30 2b 31 17 30 15 06 03 55 04 0a 13 |....0+1.0...U...|
+000000a0 0e 47 6f 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 |.Google TESTING1|
+000000b0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000c0 74 30 1e 17 0d 31 35 30 31 30 31 30 30 30 30 30 |t0...15010100000|
+000000d0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000e0 5a 30 26 31 17 30 15 06 03 55 04 0a 13 0e 47 6f |Z0&1.0...U....Go|
+000000f0 6f 67 6c 65 20 54 45 53 54 49 4e 47 31 0b 30 09 |ogle TESTING1.0.|
+00000100 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+00000110 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000120 81 89 02 81 81 00 af 87 88 f6 20 1b 95 65 6c 14 |.......... ..el.|
+00000130 ab 44 05 af 3b 45 14 e3 b7 6d fd 00 63 4d 95 7f |.D..;E...m..cM..|
+00000140 fe 6a 62 35 86 c0 4a f9 18 7c f6 aa 25 5e 7a 64 |.jb5..J..|..%^zd|
+00000150 31 66 00 ba f4 8e 92 af c7 6b d8 76 d4 f3 5f 41 |1f.......k.v.._A|
+00000160 cb 6e 56 15 97 1b 97 c1 3c 12 39 21 66 3d 2b 16 |.nV.....<.9!f=+.|
+00000170 d1 bc db 1c c0 a7 da b7 ca ad ba da cb d5 21 50 |..............!P|
+00000180 ec de 8d ab d1 6b 81 4b 89 02 f3 c4 be c1 6c 89 |.....k.K......l.|
+00000190 b1 44 84 bd 21 d1 04 7d 9d 16 4d f9 82 15 f6 ef |.D..!..}..M.....|
+000001a0 fa d6 09 47 f2 fb 02 03 01 00 01 a3 81 93 30 81 |...G..........0.|
+000001b0 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001c0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001d0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001e0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001f0 06 03 55 1d 0e 04 12 04 10 12 50 8d 89 6f 1b d1 |..U.......P..o..|
+00000200 dc 54 4d 6e cb 69 5e 06 f4 30 1b 06 03 55 1d 23 |.TMn.i^..0...U.#|
+00000210 04 14 30 12 80 10 bf 3d b6 a9 66 f2 b8 40 cf ea |..0....=..f..@..|
+00000220 b4 03 78 48 1a 41 30 19 06 03 55 1d 11 04 12 30 |..xH.A0...U....0|
+00000230 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000240 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000250 03 81 81 00 92 7c af 91 55 12 18 96 59 31 a6 48 |.....|..U...Y1.H|
+00000260 40 d5 2d d5 ee bb 02 a0 f5 c2 1e 7c 9b b3 30 7d |@.-........|..0}|
+00000270 3c dc 76 da 4f 3d c0 fa ae 2d 33 24 6b 03 7b 1b |<.v.O=...-3$k.{.|
+00000280 67 59 11 21 b5 11 bc 77 b9 d9 e0 6e a8 2d 2e 35 |gY.!...w...n.-.5|
+00000290 fa 64 5f 22 3e 63 10 6b be ff 14 86 6d 0d f0 15 |.d_">c.k....m...|
+000002a0 31 a8 14 38 1e 3b 84 87 2c cb 98 ed 51 76 b9 b1 |1..8.;..,...Qv..|
+000002b0 4f dd db 9b 84 04 86 40 fa 51 dd ba b4 8d eb e3 |O......@.Q......|
+000002c0 46 de 46 b9 4f 86 c7 f9 a4 c2 41 34 ac cc f6 ea |F.F.O.....A4....|
+000002d0 b0 ab 39 18 16 03 03 00 cd 0c 00 00 c9 03 00 17 |..9.............|
+000002e0 41 04 62 2a a7 2d 1f 7a 8d 7e 8a 9e 84 db df e2 |A.b*.-.z.~......|
+000002f0 7c 35 d8 a1 9f ec 23 ef c7 c2 9a c5 45 02 6f eb ||5....#.....E.o.|
+00000300 24 ed 77 e1 ca fe 9a be 06 1e ea 30 5a e7 13 00 |$.w........0Z...|
+00000310 47 52 a4 a2 d8 ee 9d 4e 87 f5 48 83 6f 5d 8e 02 |GR.....N..H.o]..|
+00000320 ff f5 04 01 00 80 19 f6 63 a1 47 d1 cf 4d 28 73 |........c.G..M(s|
+00000330 4e 31 03 78 b5 17 ba 53 64 d0 b8 3f 04 77 9d 6b |N1.x...Sd..?.w.k|
+00000340 85 d0 d4 1e 02 90 b9 ab 10 dc d7 b1 79 1b 12 80 |............y...|
+00000350 e1 5a 4b 69 80 2d 2a 37 4c fd 72 a9 c3 8e 2a 1f |.ZKi.-*7L.r...*.|
+00000360 1a 3f 74 49 c6 49 ce 2f 02 58 3f 68 f0 f6 b5 8a |.?tI.I./.X?h....|
+00000370 16 11 8b 63 15 6a f2 91 f1 74 a8 f0 6d dc 91 0a |...c.j...t..m...|
+00000380 b4 e2 4e 10 14 1d b9 da 05 29 bf 31 30 ee 7d a5 |..N......).10.}.|
+00000390 75 4e da ff db 43 04 a7 55 4b dd 93 4c 5f 32 be |uN...C..UK..L_2.|
+000003a0 e9 23 c9 a1 23 86 16 03 03 00 04 0e 00 00 00 |.#..#..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1e 18 37 ef 0d |....F...BA...7..|
+00000010 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd |.Q.5uq..T[....g.|
+00000020 a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e |.$ >.V...(^.+-O.|
+00000030 f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 |...lK[.V.2B.X..I|
+00000040 a6 b5 68 1a 41 03 56 6b dc 5a 89 14 03 03 00 01 |..h.A.Vk.Z......|
+00000050 01 16 03 03 00 28 00 00 00 00 00 00 00 00 d4 cb |.....(..........|
+00000060 e2 c0 1e fe cb b0 d6 fe da 7c 8f 8c b2 2f f7 c1 |.........|.../..|
+00000070 3d e9 52 6e 70 c1 13 13 87 ff 12 85 6c 2c |=.Rnp.......l,|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 0a 86 ff b2 73 |..........(....s|
+00000010 35 40 a1 89 9f 21 1f 0b 2f 79 50 70 eb 74 e1 2f |5@...!../yPp.t./|
+00000020 4d bc 5c 3c 85 0b 60 cc 73 36 e4 08 01 0a 4c 75 |M.\<..`.s6....Lu|
+00000030 0f a2 9c |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 c9 78 b7 |..............x.|
+00000010 07 d1 a9 95 fc b4 aa 57 16 77 86 fb c7 a9 c6 12 |.......W.w......|
+00000020 bc bd 09 |...|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 1c 0a 86 ff b2 73 35 40 a2 4d b1 9b |.........s5@.M..|
+00000010 eb 51 76 71 6b b8 88 fe 21 60 bb 8b 2a cc e3 3e |.Qvqk...!`..*..>|
+00000020 d5 |.|
+>>> Flow 7 (client to server)
+00000000 15 03 03 00 1a 00 00 00 00 00 00 00 02 0e da c6 |................|
+00000010 01 09 cc 0f bb 7d de c9 41 8d 30 b5 d5 b7 f2 15 |.....}..A.0.....|
+00000020 03 03 00 1a 00 00 00 00 00 00 00 03 a7 0e 24 98 |..............$.|
+00000030 32 62 1b a9 98 17 b6 b3 71 af 88 7a a3 6b |2b......q..z.k|
diff --git a/libgo/go/crypto/tls/ticket.go b/libgo/go/crypto/tls/ticket.go
index 7be50ce..3e7aa93 100644
--- a/libgo/go/crypto/tls/ticket.go
+++ b/libgo/go/crypto/tls/ticket.go
@@ -126,11 +126,7 @@ func (s *sessionState) unmarshal(data []byte) bool {
data = data[certLen:]
}
- if len(data) > 0 {
- return false
- }
-
- return true
+ return len(data) == 0
}
func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go
index 4bedd76..8eef884 100644
--- a/libgo/go/crypto/tls/tls.go
+++ b/libgo/go/crypto/tls/tls.go
@@ -47,14 +47,13 @@ type listener struct {
}
// Accept waits for and returns the next incoming TLS connection.
-// The returned connection c is a *tls.Conn.
-func (l *listener) Accept() (c net.Conn, err error) {
- c, err = l.Listener.Accept()
+// The returned connection is of type *Conn.
+func (l *listener) Accept() (net.Conn, error) {
+ c, err := l.Listener.Accept()
if err != nil {
- return
+ return nil, err
}
- c = Server(c, l.config)
- return
+ return Server(c, l.config), nil
}
// NewListener creates a Listener which accepts connections from an inner
@@ -136,9 +135,9 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*
// from the hostname we're connecting to.
if config.ServerName == "" {
// Make a copy to avoid polluting argument or default.
- c := *config
+ c := config.clone()
c.ServerName = hostname
- config = &c
+ config = c
}
conn := Client(rawConn, config)
@@ -171,10 +170,11 @@ func Dial(network, addr string, config *Config) (*Conn, error) {
return DialWithDialer(new(net.Dialer), network, addr, config)
}
-// LoadX509KeyPair reads and parses a public/private key pair from a pair of
-// files. The files must contain PEM encoded data. On successful return,
-// Certificate.Leaf will be nil because the parsed form of the certificate is
-// not retained.
+// LoadX509KeyPair reads and parses a public/private key pair from a pair
+// of files. The files must contain PEM encoded data. The certificate file
+// may contain intermediate certificates following the leaf certificate to
+// form a certificate chain. On successful return, Certificate.Leaf will
+// be nil because the parsed form of the certificate is not retained.
func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
certPEMBlock, err := ioutil.ReadFile(certFile)
if err != nil {
@@ -210,12 +210,12 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
if len(cert.Certificate) == 0 {
if len(skippedBlockTypes) == 0 {
- return fail(errors.New("crypto/tls: failed to find any PEM data in certificate input"))
- } else if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
- return fail(errors.New("crypto/tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
- } else {
- return fail(fmt.Errorf("crypto/tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
+ return fail(errors.New("tls: failed to find any PEM data in certificate input"))
+ }
+ if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
+ return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
}
+ return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
}
skippedBlockTypes = skippedBlockTypes[:0]
@@ -224,12 +224,12 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
if keyDERBlock == nil {
if len(skippedBlockTypes) == 0 {
- return fail(errors.New("crypto/tls: failed to find any PEM data in key input"))
- } else if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
- return fail(errors.New("crypto/tls: found a certificate rather than a key in the PEM for the private key"))
- } else {
- return fail(fmt.Errorf("crypto/tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
+ return fail(errors.New("tls: failed to find any PEM data in key input"))
}
+ if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
+ return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key"))
+ }
+ return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
}
if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
break
@@ -254,22 +254,21 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
case *rsa.PublicKey:
priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
if !ok {
- return fail(errors.New("crypto/tls: private key type does not match public key type"))
+ return fail(errors.New("tls: private key type does not match public key type"))
}
if pub.N.Cmp(priv.N) != 0 {
- return fail(errors.New("crypto/tls: private key does not match public key"))
+ return fail(errors.New("tls: private key does not match public key"))
}
case *ecdsa.PublicKey:
priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
if !ok {
- return fail(errors.New("crypto/tls: private key type does not match public key type"))
-
+ return fail(errors.New("tls: private key type does not match public key type"))
}
if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
- return fail(errors.New("crypto/tls: private key does not match public key"))
+ return fail(errors.New("tls: private key does not match public key"))
}
default:
- return fail(errors.New("crypto/tls: unknown public key algorithm"))
+ return fail(errors.New("tls: unknown public key algorithm"))
}
return cert, nil
@@ -287,12 +286,12 @@ func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
case *rsa.PrivateKey, *ecdsa.PrivateKey:
return key, nil
default:
- return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping")
+ return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
}
}
if key, err := x509.ParseECPrivateKey(der); err == nil {
return key, nil
}
- return nil, errors.New("crypto/tls: failed to parse private key")
+ return nil, errors.New("tls: failed to parse private key")
}
diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go
index 5cc1427..48b46a0 100644
--- a/libgo/go/crypto/tls/tls_test.go
+++ b/libgo/go/crypto/tls/tls_test.go
@@ -6,13 +6,19 @@ package tls
import (
"bytes"
+ "crypto/x509"
"errors"
"fmt"
"internal/testenv"
"io"
+ "math"
+ "math/rand"
"net"
+ "os"
+ "reflect"
"strings"
"testing"
+ "testing/quick"
"time"
)
@@ -146,7 +152,7 @@ func TestX509MixedKeyPair(t *testing.T) {
}
}
-func newLocalListener(t *testing.T) net.Listener {
+func newLocalListener(t testing.TB) net.Listener {
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
ln, err = net.Listen("tcp6", "[::1]:0")
@@ -188,18 +194,25 @@ func TestDialTimeout(t *testing.T) {
t.Fatal("DialWithTimeout completed successfully")
}
- if !strings.Contains(err.Error(), "timed out") {
- t.Errorf("resulting error not a timeout: %s", err)
+ if !isTimeoutError(err) {
+ t.Errorf("resulting error not a timeout: %v\nType %T: %#v", err, err, err)
}
}
+func isTimeoutError(err error) bool {
+ if ne, ok := err.(net.Error); ok {
+ return ne.Timeout()
+ }
+ return false
+}
+
// tests that Conn.Read returns (non-zero, io.EOF) instead of
// (non-zero, nil) when a Close (alertCloseNotify) is sitting right
// behind the application data in the buffer.
func TestConnReadNonzeroAndEOF(t *testing.T) {
// This test is racy: it assumes that after a write to a
// localhost TCP connection, the peer TCP connection can
- // immediately read it. Because it's racy, we skip this test
+ // immediately read it. Because it's racy, we skip this test
// in short mode, and then retry it several times with an
// increasing sleep in between our final write (via srv.Close
// below) and the following read.
@@ -228,8 +241,8 @@ func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
srvCh <- nil
return
}
- serverConfig := *testConfig
- srv := Server(sconn, &serverConfig)
+ serverConfig := testConfig.clone()
+ srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
serr = fmt.Errorf("handshake: %v", err)
srvCh <- nil
@@ -238,8 +251,8 @@ func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
srvCh <- srv
}()
- clientConfig := *testConfig
- conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
+ clientConfig := testConfig.clone()
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
t.Fatal(err)
}
@@ -282,8 +295,8 @@ func TestTLSUniqueMatches(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- serverConfig := *testConfig
- srv := Server(sconn, &serverConfig)
+ serverConfig := testConfig.clone()
+ srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
t.Fatal(err)
}
@@ -291,9 +304,9 @@ func TestTLSUniqueMatches(t *testing.T) {
}
}()
- clientConfig := *testConfig
+ clientConfig := testConfig.clone()
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
- conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
t.Fatal(err)
}
@@ -302,7 +315,7 @@ func TestTLSUniqueMatches(t *testing.T) {
}
conn.Close()
- conn, err = Dial("tcp", ln.Addr().String(), &clientConfig)
+ conn, err = Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil {
t.Fatal(err)
}
@@ -381,8 +394,8 @@ func TestConnCloseBreakingWrite(t *testing.T) {
srvCh <- nil
return
}
- serverConfig := *testConfig
- srv := Server(sconn, &serverConfig)
+ serverConfig := testConfig.clone()
+ srv := Server(sconn, serverConfig)
if err := srv.Handshake(); err != nil {
serr = fmt.Errorf("handshake: %v", err)
srvCh <- nil
@@ -401,8 +414,8 @@ func TestConnCloseBreakingWrite(t *testing.T) {
Conn: cconn,
}
- clientConfig := *testConfig
- tconn := Client(conn, &clientConfig)
+ clientConfig := testConfig.clone()
+ tconn := Client(conn, clientConfig)
if err := tconn.Handshake(); err != nil {
t.Fatal(err)
}
@@ -445,6 +458,58 @@ func TestConnCloseBreakingWrite(t *testing.T) {
}
}
+func TestClone(t *testing.T) {
+ var c1 Config
+ v := reflect.ValueOf(&c1).Elem()
+
+ rnd := rand.New(rand.NewSource(time.Now().Unix()))
+ typ := v.Type()
+ for i := 0; i < typ.NumField(); i++ {
+ f := v.Field(i)
+ if !f.CanSet() {
+ // unexported field; not cloned.
+ continue
+ }
+
+ // testing/quick can't handle functions or interfaces.
+ fn := typ.Field(i).Name
+ switch fn {
+ case "Rand":
+ f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
+ continue
+ case "Time", "GetCertificate":
+ // DeepEqual can't compare functions.
+ continue
+ case "Certificates":
+ f.Set(reflect.ValueOf([]Certificate{
+ {Certificate: [][]byte{[]byte{'b'}}},
+ }))
+ continue
+ case "NameToCertificate":
+ f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
+ continue
+ case "RootCAs", "ClientCAs":
+ f.Set(reflect.ValueOf(x509.NewCertPool()))
+ continue
+ case "ClientSessionCache":
+ f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
+ continue
+ }
+
+ q, ok := quick.Value(f.Type(), rnd)
+ if !ok {
+ t.Fatalf("quick.Value failed on field %s", fn)
+ }
+ f.Set(q)
+ }
+
+ c2 := c1.clone()
+
+ if !reflect.DeepEqual(&c1, c2) {
+ t.Errorf("clone failed to copy a field")
+ }
+}
+
// changeImplConn is a net.Conn which can change its Write and Close
// methods.
type changeImplConn struct {
@@ -466,3 +531,161 @@ func (w *changeImplConn) Close() error {
}
return w.Conn.Close()
}
+
+func throughput(b *testing.B, totalBytes int64, dynamicRecordSizingDisabled bool) {
+ ln := newLocalListener(b)
+ defer ln.Close()
+
+ N := b.N
+
+ // Less than 64KB because Windows appears to use a TCP rwin < 64KB.
+ // See Issue #15899.
+ const bufsize = 32 << 10
+
+ go func() {
+ buf := make([]byte, bufsize)
+ for i := 0; i < N; i++ {
+ sconn, err := ln.Accept()
+ if err != nil {
+ // panic rather than synchronize to avoid benchmark overhead
+ // (cannot call b.Fatal in goroutine)
+ panic(fmt.Errorf("accept: %v", err))
+ }
+ serverConfig := testConfig.clone()
+ serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ panic(fmt.Errorf("handshake: %v", err))
+ }
+ if _, err := io.CopyBuffer(srv, srv, buf); err != nil {
+ panic(fmt.Errorf("copy buffer: %v", err))
+ }
+ }
+ }()
+
+ b.SetBytes(totalBytes)
+ clientConfig := testConfig.clone()
+ clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+
+ buf := make([]byte, bufsize)
+ chunks := int(math.Ceil(float64(totalBytes) / float64(len(buf))))
+ for i := 0; i < N; i++ {
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for j := 0; j < chunks; j++ {
+ _, err := conn.Write(buf)
+ if err != nil {
+ b.Fatal(err)
+ }
+ _, err = io.ReadFull(conn, buf)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+ conn.Close()
+ }
+}
+
+func BenchmarkThroughput(b *testing.B) {
+ for _, mode := range []string{"Max", "Dynamic"} {
+ for size := 1; size <= 64; size <<= 1 {
+ name := fmt.Sprintf("%sPacket/%dMB", mode, size)
+ b.Run(name, func(b *testing.B) {
+ throughput(b, int64(size<<20), mode == "Max")
+ })
+ }
+ }
+}
+
+type slowConn struct {
+ net.Conn
+ bps int
+}
+
+func (c *slowConn) Write(p []byte) (int, error) {
+ if c.bps == 0 {
+ panic("too slow")
+ }
+ t0 := time.Now()
+ wrote := 0
+ for wrote < len(p) {
+ time.Sleep(100 * time.Microsecond)
+ allowed := int(time.Since(t0).Seconds()*float64(c.bps)) / 8
+ if allowed > len(p) {
+ allowed = len(p)
+ }
+ if wrote < allowed {
+ n, err := c.Conn.Write(p[wrote:allowed])
+ wrote += n
+ if err != nil {
+ return wrote, err
+ }
+ }
+ }
+ return len(p), nil
+}
+
+func latency(b *testing.B, bps int, dynamicRecordSizingDisabled bool) {
+ ln := newLocalListener(b)
+ defer ln.Close()
+
+ N := b.N
+
+ go func() {
+ for i := 0; i < N; i++ {
+ sconn, err := ln.Accept()
+ if err != nil {
+ // panic rather than synchronize to avoid benchmark overhead
+ // (cannot call b.Fatal in goroutine)
+ panic(fmt.Errorf("accept: %v", err))
+ }
+ serverConfig := testConfig.clone()
+ serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+ srv := Server(&slowConn{sconn, bps}, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ panic(fmt.Errorf("handshake: %v", err))
+ }
+ io.Copy(srv, srv)
+ }
+ }()
+
+ clientConfig := testConfig.clone()
+ clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+
+ buf := make([]byte, 16384)
+ peek := make([]byte, 1)
+
+ for i := 0; i < N; i++ {
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ b.Fatal(err)
+ }
+ // make sure we're connected and previous connection has stopped
+ if _, err := conn.Write(buf[:1]); err != nil {
+ b.Fatal(err)
+ }
+ if _, err := io.ReadFull(conn, peek); err != nil {
+ b.Fatal(err)
+ }
+ if _, err := conn.Write(buf); err != nil {
+ b.Fatal(err)
+ }
+ if _, err = io.ReadFull(conn, peek); err != nil {
+ b.Fatal(err)
+ }
+ conn.Close()
+ }
+}
+
+func BenchmarkLatency(b *testing.B) {
+ for _, mode := range []string{"Max", "Dynamic"} {
+ for _, kbps := range []int{200, 500, 1000, 2000, 5000} {
+ name := fmt.Sprintf("%sPacket/%dkbps", mode, kbps)
+ b.Run(name, func(b *testing.B) {
+ latency(b, kbps*1000, mode == "Max")
+ })
+ }
+ }
+}
diff --git a/libgo/go/crypto/x509/cert_pool.go b/libgo/go/crypto/x509/cert_pool.go
index 2362e84..59ab887 100644
--- a/libgo/go/crypto/x509/cert_pool.go
+++ b/libgo/go/crypto/x509/cert_pool.go
@@ -6,6 +6,8 @@ package x509
import (
"encoding/pem"
+ "errors"
+ "runtime"
)
// CertPool is a set of certificates.
@@ -18,12 +20,22 @@ type CertPool struct {
// NewCertPool returns a new, empty CertPool.
func NewCertPool() *CertPool {
return &CertPool{
- make(map[string][]int),
- make(map[string][]int),
- nil,
+ bySubjectKeyId: make(map[string][]int),
+ byName: make(map[string][]int),
}
}
+// SystemCertPool returns a copy of the system cert pool.
+//
+// Any mutations to the returned pool are not written to disk and do
+// not affect any other pool.
+func SystemCertPool() (*CertPool, error) {
+ if runtime.GOOS == "windows" {
+ return nil, errors.New("crypto/x509: system root pool is not available on Windows")
+ }
+ return loadSystemRoots()
+}
+
// findVerifiedParents attempts to find certificates in s which have signed the
// given certificate. If any candidates were rejected then errCert will be set
// to one of them, arbitrarily, and err will contain the reason that it was
@@ -107,10 +119,10 @@ func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
// Subjects returns a list of the DER-encoded subjects of
// all of the certificates in the pool.
-func (s *CertPool) Subjects() (res [][]byte) {
- res = make([][]byte, len(s.certs))
+func (s *CertPool) Subjects() [][]byte {
+ res := make([][]byte, len(s.certs))
for i, c := range s.certs {
res[i] = c.RawSubject
}
- return
+ return res
}
diff --git a/libgo/go/crypto/x509/pem_decrypt.go b/libgo/go/crypto/x509/pem_decrypt.go
index 49ceadb..0388d63 100644
--- a/libgo/go/crypto/x509/pem_decrypt.go
+++ b/libgo/go/crypto/x509/pem_decrypt.go
@@ -42,7 +42,7 @@ type rfc1423Algo struct {
}
// rfc1423Algos holds a slice of the possible ways to encrypt a PEM
-// block. The ivSize numbers were taken from the OpenSSL source.
+// block. The ivSize numbers were taken from the OpenSSL source.
var rfc1423Algos = []rfc1423Algo{{
cipher: PEMCipherDES,
name: "DES-CBC",
diff --git a/libgo/go/crypto/x509/pkcs1.go b/libgo/go/crypto/x509/pkcs1.go
index acebe35..df20a44 100644
--- a/libgo/go/crypto/x509/pkcs1.go
+++ b/libgo/go/crypto/x509/pkcs1.go
@@ -36,15 +36,14 @@ type pkcs1AdditionalRSAPrime struct {
}
// ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
-func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) {
+func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
var priv pkcs1PrivateKey
rest, err := asn1.Unmarshal(der, &priv)
if len(rest) > 0 {
- err = asn1.SyntaxError{Msg: "trailing data"}
- return
+ return nil, asn1.SyntaxError{Msg: "trailing data"}
}
if err != nil {
- return
+ return nil, err
}
if priv.Version > 1 {
@@ -55,7 +54,7 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) {
return nil, errors.New("x509: private key contains zero or negative value")
}
- key = new(rsa.PrivateKey)
+ key := new(rsa.PrivateKey)
key.PublicKey = rsa.PublicKey{
E: priv.E,
N: priv.N,
@@ -80,7 +79,7 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) {
}
key.Precompute()
- return
+ return key, nil
}
// MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
diff --git a/libgo/go/crypto/x509/pkcs8.go b/libgo/go/crypto/x509/pkcs8.go
index ba19989..b304a3f 100644
--- a/libgo/go/crypto/x509/pkcs8.go
+++ b/libgo/go/crypto/x509/pkcs8.go
@@ -13,7 +13,7 @@ import (
// pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
-// and RFC5208.
+// and RFC 5208.
type pkcs8 struct {
Version int
Algo pkix.AlgorithmIdentifier
@@ -21,8 +21,8 @@ type pkcs8 struct {
// optional attributes omitted.
}
-// ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. See
-// http://www.rsa.com/rsalabs/node.asp?id=2130 and RFC5208.
+// ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key.
+// See RFC 5208.
func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
var privKey pkcs8
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
diff --git a/libgo/go/crypto/x509/pkix/pkix.go b/libgo/go/crypto/x509/pkix/pkix.go
index 1b3e3c0..faad406 100644
--- a/libgo/go/crypto/x509/pkix/pkix.go
+++ b/libgo/go/crypto/x509/pkix/pkix.go
@@ -177,7 +177,7 @@ func (certList *CertificateList) HasExpired(now time.Time) bool {
// 5280, section 5.1.
type TBSCertificateList struct {
Raw asn1.RawContent
- Version int `asn1:"optional,default:1"`
+ Version int `asn1:"optional,default:0"`
Signature AlgorithmIdentifier
Issuer RDNSequence
ThisUpdate time.Time
diff --git a/libgo/go/crypto/x509/root.go b/libgo/go/crypto/x509/root.go
index 8aae14e..787d955 100644
--- a/libgo/go/crypto/x509/root.go
+++ b/libgo/go/crypto/x509/root.go
@@ -7,11 +7,16 @@ package x509
import "sync"
var (
- once sync.Once
- systemRoots *CertPool
+ once sync.Once
+ systemRoots *CertPool
+ systemRootsErr error
)
func systemRootsPool() *CertPool {
once.Do(initSystemRoots)
return systemRoots
}
+
+func initSystemRoots() {
+ systemRoots, systemRootsErr = loadSystemRoots()
+}
diff --git a/libgo/go/crypto/x509/root_cgo_darwin.go b/libgo/go/crypto/x509/root_cgo_darwin.go
index bf4a5cd..0e2fb35 100644
--- a/libgo/go/crypto/x509/root_cgo_darwin.go
+++ b/libgo/go/crypto/x509/root_cgo_darwin.go
@@ -21,59 +21,91 @@ package x509
// Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
// we've consumed its content.
int FetchPEMRoots(CFDataRef *pemRoots) {
- if (pemRoots == NULL) {
- return -1;
- }
+ // Get certificates from all domains, not just System, this lets
+ // the user add CAs to their "login" keychain, and Admins to add
+ // to the "System" keychain
+ SecTrustSettingsDomain domains[] = { kSecTrustSettingsDomainSystem,
+ kSecTrustSettingsDomainAdmin,
+ kSecTrustSettingsDomainUser };
- CFArrayRef certs = NULL;
- OSStatus err = SecTrustCopyAnchorCertificates(&certs);
- if (err != noErr) {
+ int numDomains = sizeof(domains)/sizeof(SecTrustSettingsDomain);
+ if (pemRoots == NULL) {
return -1;
}
CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
- int i, ncerts = CFArrayGetCount(certs);
- for (i = 0; i < ncerts; i++) {
- CFDataRef data = NULL;
- SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
- if (cert == NULL) {
- continue;
- }
-
- // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
- // Once we support weak imports via cgo we should prefer that, and fall back to this
- // for older systems.
- err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
+ for (int i = 0; i < numDomains; i++) {
+ CFArrayRef certs = NULL;
+ // Only get certificates from domain that are trusted
+ OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs);
if (err != noErr) {
continue;
}
- if (data != NULL) {
- CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
- CFRelease(data);
- }
- }
+ int numCerts = CFArrayGetCount(certs);
+ for (int j = 0; j < numCerts; j++) {
+ CFDataRef data = NULL;
+ CFErrorRef errRef = NULL;
+ SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j);
+ if (cert == NULL) {
+ continue;
+ }
+ // We only want to add Root CAs, so make sure Subject and Issuer Name match
+ CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
+ if (errRef != NULL) {
+ CFRelease(errRef);
+ continue;
+ }
+ CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, &errRef);
+ if (errRef != NULL) {
+ CFRelease(subjectName);
+ CFRelease(errRef);
+ continue;
+ }
+ Boolean equal = CFEqual(subjectName, issuerName);
+ CFRelease(subjectName);
+ CFRelease(issuerName);
+ if (!equal) {
+ continue;
+ }
- CFRelease(certs);
+ // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
+ // Once we support weak imports via cgo we should prefer that, and fall back to this
+ // for older systems.
+ err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
+ if (err != noErr) {
+ continue;
+ }
+ if (data != NULL) {
+ CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
+ CFRelease(data);
+ }
+ }
+ CFRelease(certs);
+ }
*pemRoots = combinedData;
return 0;
}
*/
import "C"
-import "unsafe"
+import (
+ "errors"
+ "unsafe"
+)
-func initSystemRoots() {
+func loadSystemRoots() (*CertPool, error) {
roots := NewCertPool()
var data C.CFDataRef = nil
err := C.FetchPEMRoots(&data)
if err == -1 {
- return
+ // TODO: better error message
+ return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo")
}
defer C.CFRelease(C.CFTypeRef(data))
buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
roots.AppendCertsFromPEM(buf)
- systemRoots = roots
+ return roots, nil
}
diff --git a/libgo/go/crypto/x509/root_darwin_arm_gen.go b/libgo/go/crypto/x509/root_darwin_arm_gen.go
index 5817158..fc2488a 100644
--- a/libgo/go/crypto/x509/root_darwin_arm_gen.go
+++ b/libgo/go/crypto/x509/root_darwin_arm_gen.go
@@ -184,8 +184,9 @@ const header = `
package x509
-func initSystemRoots() {
- systemRoots = NewCertPool()
- systemRoots.AppendCertsFromPEM([]byte(systemRootsPEM))
+func loadSystemRoots() (*CertPool, error) {
+ p := NewCertPool()
+ p.AppendCertsFromPEM([]byte(systemRootsPEM))
+ return p, nil
}
`
diff --git a/libgo/go/crypto/x509/root_darwin_armx.go b/libgo/go/crypto/x509/root_darwin_armx.go
index 37675b4..ad1c53d 100644
--- a/libgo/go/crypto/x509/root_darwin_armx.go
+++ b/libgo/go/crypto/x509/root_darwin_armx.go
@@ -10,9 +10,10 @@
package x509
-func initSystemRoots() {
- systemRoots = NewCertPool()
- systemRoots.AppendCertsFromPEM([]byte(systemRootsPEM))
+func loadSystemRoots() (*CertPool, error) {
+ p := NewCertPool()
+ p.AppendCertsFromPEM([]byte(systemRootsPEM))
+ return p, nil
}
const systemRootsPEM = `
diff --git a/libgo/go/crypto/x509/root_nocgo_darwin.go b/libgo/go/crypto/x509/root_nocgo_darwin.go
index d00e257..2ac4666 100644
--- a/libgo/go/crypto/x509/root_nocgo_darwin.go
+++ b/libgo/go/crypto/x509/root_nocgo_darwin.go
@@ -6,6 +6,6 @@
package x509
-func initSystemRoots() {
- systemRoots, _ = execSecurityRoots()
+func loadSystemRoots() (*CertPool, error) {
+ return execSecurityRoots()
}
diff --git a/libgo/go/crypto/x509/root_plan9.go b/libgo/go/crypto/x509/root_plan9.go
index 9965caa..ebeb7df 100644
--- a/libgo/go/crypto/x509/root_plan9.go
+++ b/libgo/go/crypto/x509/root_plan9.go
@@ -6,7 +6,10 @@
package x509
-import "io/ioutil"
+import (
+ "io/ioutil"
+ "os"
+)
// Possible certificate files; stop after finding one.
var certFiles = []string{
@@ -17,17 +20,18 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
return nil, nil
}
-func initSystemRoots() {
+func loadSystemRoots() (*CertPool, error) {
roots := NewCertPool()
+ var bestErr error
for _, file := range certFiles {
data, err := ioutil.ReadFile(file)
if err == nil {
roots.AppendCertsFromPEM(data)
- systemRoots = roots
- return
+ return roots, nil
+ }
+ if bestErr == nil || (os.IsNotExist(bestErr) && !os.IsNotExist(err)) {
+ bestErr = err
}
}
-
- // All of the files failed to load. systemRoots will be nil which will
- // trigger a specific error at verification time.
+ return nil, bestErr
}
diff --git a/libgo/go/crypto/x509/root_unix.go b/libgo/go/crypto/x509/root_unix.go
index 9f06f9d..7bcb3d6 100644
--- a/libgo/go/crypto/x509/root_unix.go
+++ b/libgo/go/crypto/x509/root_unix.go
@@ -6,7 +6,10 @@
package x509
-import "io/ioutil"
+import (
+ "io/ioutil"
+ "os"
+)
// Possible directories with certificate files; stop after successfully
// reading at least one file from a directory.
@@ -19,20 +22,26 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
return nil, nil
}
-func initSystemRoots() {
+func loadSystemRoots() (*CertPool, error) {
roots := NewCertPool()
+ var firstErr error
for _, file := range certFiles {
data, err := ioutil.ReadFile(file)
if err == nil {
roots.AppendCertsFromPEM(data)
- systemRoots = roots
- return
+ return roots, nil
+ }
+ if firstErr == nil && !os.IsNotExist(err) {
+ firstErr = err
}
}
for _, directory := range certDirectories {
fis, err := ioutil.ReadDir(directory)
if err != nil {
+ if firstErr == nil && !os.IsNotExist(err) {
+ firstErr = err
+ }
continue
}
rootsAdded := false
@@ -43,11 +52,9 @@ func initSystemRoots() {
}
}
if rootsAdded {
- systemRoots = roots
- return
+ return roots, nil
}
}
- // All of the files failed to load. systemRoots will be nil which will
- // trigger a specific error at verification time.
+ return nil, firstErr
}
diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go
index 81018b7..392c869 100644
--- a/libgo/go/crypto/x509/root_windows.go
+++ b/libgo/go/crypto/x509/root_windows.go
@@ -179,7 +179,7 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
}
// CertGetCertificateChain will traverse Windows's root stores
- // in an attempt to build a verified certificate chain. Once
+ // in an attempt to build a verified certificate chain. Once
// it has found a verified chain, it stops. MSDN docs on
// CERT_CHAIN_CONTEXT:
//
@@ -225,5 +225,4 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
return chains, nil
}
-func initSystemRoots() {
-}
+func loadSystemRoots() (*CertPool, error) { return nil, nil }
diff --git a/libgo/go/crypto/x509/sec1.go b/libgo/go/crypto/x509/sec1.go
index 1424dea..33f376c 100644
--- a/libgo/go/crypto/x509/sec1.go
+++ b/libgo/go/crypto/x509/sec1.go
@@ -17,9 +17,9 @@ const ecPrivKeyVersion = 1
// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
// References:
-// RFC5915
+// RFC 5915
// SEC1 - http://www.secg.org/sec1-v2.pdf
-// Per RFC5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
+// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
// most cases it is not.
type ecPrivateKey struct {
Version int
@@ -29,7 +29,7 @@ type ecPrivateKey struct {
}
// ParseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
-func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) {
+func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
return parseECPrivateKey(nil, der)
}
diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go
index 27e9bbf..85c083f 100644
--- a/libgo/go/crypto/x509/verify.go
+++ b/libgo/go/crypto/x509/verify.go
@@ -117,10 +117,16 @@ func (e UnknownAuthorityError) Error() string {
}
// SystemRootsError results when we fail to load the system root certificates.
-type SystemRootsError struct{}
+type SystemRootsError struct {
+ Err error
+}
-func (SystemRootsError) Error() string {
- return "x509: failed to load system roots and no roots provided"
+func (se SystemRootsError) Error() string {
+ msg := "x509: failed to load system roots and no roots provided"
+ if se.Err != nil {
+ return msg + "; " + se.Err.Error()
+ }
+ return msg
}
// errNotParsed is returned when a certificate without ASN.1 contents is
@@ -179,7 +185,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
// being valid for encryption only, but no-one noticed. Another
// European CA marked its signature keys as not being valid for
// signatures. A different CA marked its own trusted root certificate
- // as being invalid for certificate signing. Another national CA
+ // as being invalid for certificate signing. Another national CA
// distributed a certificate to be used to encrypt data for the
// country’s tax authority that was marked as only being usable for
// digital signatures but not for encryption. Yet another CA reversed
@@ -240,7 +246,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
if opts.Roots == nil {
opts.Roots = systemRootsPool()
if opts.Roots == nil {
- return nil, SystemRootsError{}
+ return nil, SystemRootsError{systemRootsErr}
}
}
diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go
index 694c140..bacf7de 100644
--- a/libgo/go/crypto/x509/verify_test.go
+++ b/libgo/go/crypto/x509/verify_test.go
@@ -382,7 +382,7 @@ func testVerify(t *testing.T, useSystemRoots bool) {
continue
}
for k, cert := range chain {
- if strings.Index(nameToKey(&cert.Subject), expectedChain[k]) == -1 {
+ if !strings.Contains(nameToKey(&cert.Subject), expectedChain[k]) {
continue TryNextExpected
}
}
@@ -650,50 +650,6 @@ um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
-----END CERTIFICATE-----`
-const startComRootSHA256 = `-----BEGIN CERTIFICATE-----
-MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
-F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
-ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
-ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
-aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
-YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
-c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
-d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
-CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
-wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
-Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
-0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
-pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
-CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
-P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
-1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
-KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
-JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
-8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
-fyWl8kgAwKQB2j8=
------END CERTIFICATE-----`
-
const smimeLeaf = `-----BEGIN CERTIFICATE-----
MIIFBjCCA+6gAwIBAgISESFvrjT8XcJTEe6rBlPptILlMA0GCSqGSIb3DQEBBQUA
MFQxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSowKAYD
diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go
index d9288bb..9ad3cf2 100644
--- a/libgo/go/crypto/x509/x509.go
+++ b/libgo/go/crypto/x509/x509.go
@@ -36,6 +36,12 @@ type pkixPublicKey struct {
// ParsePKIXPublicKey parses a DER encoded public key. These values are
// typically found in PEM blocks with "BEGIN PUBLIC KEY".
+//
+// Supported key types include RSA, DSA, and ECDSA. Unknown key
+// types result in an error.
+//
+// On success, pub will be of type *rsa.PublicKey, *dsa.PublicKey,
+// or *ecdsa.PublicKey.
func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
var pki publicKeyInfo
if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil {
@@ -120,7 +126,7 @@ type certificate struct {
type tbsCertificate struct {
Raw asn1.RawContent
- Version int `asn1:"optional,explicit,default:1,tag:0"`
+ Version int `asn1:"optional,explicit,default:0,tag:0"`
SerialNumber *big.Int
SignatureAlgorithm pkix.AlgorithmIdentifier
Issuer asn1.RawValue
@@ -264,7 +270,7 @@ var (
oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
- oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 4, 3, 2}
+ oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
@@ -635,7 +641,7 @@ var entrustBrokenSPKI = []byte{
// CheckSignatureFrom verifies that the signature on c is a valid signature
// from parent.
-func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
+func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
// RFC 5280, 4.2.1.9:
// "If the basic constraints extension is not present in a version 3
// certificate, or the extension is present but the cA boolean is not
@@ -663,7 +669,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
// CheckSignature verifies that signature is a valid signature over signed from
// c's public key.
-func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) {
+func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
return checkSignature(algo, signed, signature, c.PublicKey)
}
@@ -731,7 +737,7 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey
}
// CheckCRLSignature checks that the signature in crl is from c.
-func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) (err error) {
+func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) error {
algo := getSignatureAlgorithmFromOID(crl.SignatureAlgorithm.Algorithm)
return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())
}
@@ -1127,7 +1133,7 @@ func parseCertificate(in *certificate) (*Certificate, error) {
if rest, err := asn1.Unmarshal(e.Value, &keyid); err != nil {
return nil, err
} else if len(rest) != 0 {
- return nil, errors.New("x509: trailing data after X.509 authority key-id")
+ return nil, errors.New("x509: trailing data after X.509 key-id")
}
out.SubjectKeyId = keyid
@@ -1581,21 +1587,21 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
return nil, err
}
- if len(parent.SubjectKeyId) > 0 {
- template.AuthorityKeyId = parent.SubjectKeyId
- }
-
- extensions, err := buildExtensions(template)
+ asn1Issuer, err := subjectBytes(parent)
if err != nil {
return
}
- asn1Issuer, err := subjectBytes(parent)
+ asn1Subject, err := subjectBytes(template)
if err != nil {
return
}
- asn1Subject, err := subjectBytes(template)
+ if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 {
+ template.AuthorityKeyId = parent.SubjectKeyId
+ }
+
+ extensions, err := buildExtensions(template)
if err != nil {
return
}
@@ -1648,7 +1654,7 @@ var pemType = "X509 CRL"
// encoded CRLs will appear where they should be DER encoded, so this function
// will transparently handle PEM encoding as long as there isn't any leading
// garbage.
-func ParseCRL(crlBytes []byte) (certList *pkix.CertificateList, err error) {
+func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) {
if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
block, _ := pem.Decode(crlBytes)
if block != nil && block.Type == pemType {
@@ -1659,8 +1665,8 @@ func ParseCRL(crlBytes []byte) (certList *pkix.CertificateList, err error) {
}
// ParseDERCRL parses a DER encoded CRL from the given bytes.
-func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) {
- certList = new(pkix.CertificateList)
+func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) {
+ certList := new(pkix.CertificateList)
if rest, err := asn1.Unmarshal(derBytes, certList); err != nil {
return nil, err
} else if len(rest) != 0 {
@@ -1790,6 +1796,9 @@ var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn1.RawValue, error) {
var rawAttributes []asn1.RawValue
b, err := asn1.Marshal(attributes)
+ if err != nil {
+ return nil, err
+ }
rest, err := asn1.Unmarshal(b, &rawAttributes)
if err != nil {
return nil, err
@@ -1847,8 +1856,8 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error)
return ret, nil
}
-// CreateCertificateRequest creates a new certificate based on a template. The
-// following members of template are used: Subject, Attributes,
+// CreateCertificateRequest creates a new certificate request based on a template.
+// The following members of template are used: Subject, Attributes,
// SignatureAlgorithm, Extensions, DNSNames, EmailAddresses, and IPAddresses.
// The private key is the private key of the signer.
//
@@ -2065,7 +2074,7 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
return out, nil
}
-// CheckSignature verifies that the signature on c is a valid signature
-func (c *CertificateRequest) CheckSignature() (err error) {
+// CheckSignature reports whether the signature on c is valid.
+func (c *CertificateRequest) CheckSignature() error {
return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey)
}
diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go
index d1ef027..c6448d3 100644
--- a/libgo/go/crypto/x509/x509_test.go
+++ b/libgo/go/crypto/x509/x509_test.go
@@ -96,6 +96,17 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
-----END RSA PRIVATE KEY-----
`
+var testPrivateKey *rsa.PrivateKey
+
+func init() {
+ block, _ := pem.Decode([]byte(pemPrivateKey))
+
+ var err error
+ if testPrivateKey, err = ParsePKCS1PrivateKey(block.Bytes); err != nil {
+ panic("Failed to parse private key: " + err.Error())
+ }
+}
+
func bigFromString(s string) *big.Int {
ret := new(big.Int)
ret.SetString(s, 10)
@@ -314,12 +325,6 @@ var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be13
func TestCreateSelfSignedCertificate(t *testing.T) {
random := rand.Reader
- block, _ := pem.Decode([]byte(pemPrivateKey))
- rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- t.Fatalf("Failed to parse private key: %s", err)
- }
-
ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("Failed to generate ECDSA key: %s", err)
@@ -331,9 +336,9 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
checkSig bool
sigAlgo SignatureAlgorithm
}{
- {"RSA/RSA", &rsaPriv.PublicKey, rsaPriv, true, SHA1WithRSA},
- {"RSA/ECDSA", &rsaPriv.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
- {"ECDSA/RSA", &ecdsaPriv.PublicKey, rsaPriv, false, SHA256WithRSA},
+ {"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, SHA1WithRSA},
+ {"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
+ {"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA},
{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
}
@@ -488,7 +493,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name)
}
- if bytes.Index(derBytes, extraExtensionData) == -1 {
+ if !bytes.Contains(derBytes, extraExtensionData) {
t.Errorf("%s: didn't find extra extension in DER output", test.name)
}
@@ -874,12 +879,6 @@ const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RF
func TestCreateCertificateRequest(t *testing.T) {
random := rand.Reader
- block, _ := pem.Decode([]byte(pemPrivateKey))
- rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- t.Fatalf("Failed to parse private key: %s", err)
- }
-
ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatalf("Failed to generate ECDSA key: %s", err)
@@ -900,7 +899,7 @@ func TestCreateCertificateRequest(t *testing.T) {
priv interface{}
sigAlgo SignatureAlgorithm
}{
- {"RSA", rsaPriv, SHA1WithRSA},
+ {"RSA", testPrivateKey, SHA1WithRSA},
{"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
{"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
{"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
@@ -951,13 +950,7 @@ func TestCreateCertificateRequest(t *testing.T) {
}
func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest {
- block, _ := pem.Decode([]byte(pemPrivateKey))
- rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- t.Fatal(err)
- }
-
- derBytes, err := CreateCertificateRequest(rand.Reader, template, rsaPriv)
+ derBytes, err := CreateCertificateRequest(rand.Reader, template, testPrivateKey)
if err != nil {
t.Fatal(err)
}
@@ -1113,13 +1106,25 @@ func TestCriticalFlagInCSRRequestedExtensions(t *testing.T) {
}
}
-func TestMaxPathLen(t *testing.T) {
- block, _ := pem.Decode([]byte(pemPrivateKey))
- rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+// serialiseAndParse generates a self-signed certificate from template and
+// returns a parsed version of it.
+func serialiseAndParse(t *testing.T, template *Certificate) *Certificate {
+ derBytes, err := CreateCertificate(rand.Reader, template, template, &testPrivateKey.PublicKey, testPrivateKey)
if err != nil {
- t.Fatalf("Failed to parse private key: %s", err)
+ t.Fatalf("failed to create certificate: %s", err)
+ return nil
}
+ cert, err := ParseCertificate(derBytes)
+ if err != nil {
+ t.Fatalf("failed to parse certificate: %s", err)
+ return nil
+ }
+
+ return cert
+}
+
+func TestMaxPathLen(t *testing.T) {
template := &Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
@@ -1132,23 +1137,7 @@ func TestMaxPathLen(t *testing.T) {
IsCA: true,
}
- serialiseAndParse := func(template *Certificate) *Certificate {
- derBytes, err := CreateCertificate(rand.Reader, template, template, &rsaPriv.PublicKey, rsaPriv)
- if err != nil {
- t.Fatalf("failed to create certificate: %s", err)
- return nil
- }
-
- cert, err := ParseCertificate(derBytes)
- if err != nil {
- t.Fatalf("failed to parse certificate: %s", err)
- return nil
- }
-
- return cert
- }
-
- cert1 := serialiseAndParse(template)
+ cert1 := serialiseAndParse(t, template)
if m := cert1.MaxPathLen; m != -1 {
t.Errorf("Omitting MaxPathLen didn't turn into -1, got %d", m)
}
@@ -1157,7 +1146,7 @@ func TestMaxPathLen(t *testing.T) {
}
template.MaxPathLen = 1
- cert2 := serialiseAndParse(template)
+ cert2 := serialiseAndParse(t, template)
if m := cert2.MaxPathLen; m != 1 {
t.Errorf("Setting MaxPathLen didn't work. Got %d but set 1", m)
}
@@ -1167,7 +1156,7 @@ func TestMaxPathLen(t *testing.T) {
template.MaxPathLen = 0
template.MaxPathLenZero = true
- cert3 := serialiseAndParse(template)
+ cert3 := serialiseAndParse(t, template)
if m := cert3.MaxPathLen; m != 0 {
t.Errorf("Setting MaxPathLenZero didn't work, got %d", m)
}
@@ -1176,6 +1165,30 @@ func TestMaxPathLen(t *testing.T) {
}
}
+func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) {
+ template := &Certificate{
+ SerialNumber: big.NewInt(1),
+ Subject: pkix.Name{
+ CommonName: "Σ Acme Co",
+ },
+ NotBefore: time.Unix(1000, 0),
+ NotAfter: time.Unix(100000, 0),
+
+ BasicConstraintsValid: true,
+ IsCA: true,
+ SubjectKeyId: []byte{1, 2, 3, 4},
+ }
+
+ if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) != 0 {
+ t.Fatalf("self-signed certificate contained default authority key id")
+ }
+
+ template.AuthorityKeyId = []byte{1, 2, 3, 4}
+ if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) == 0 {
+ t.Fatalf("self-signed certificate erased explicit authority key id")
+ }
+}
+
func TestASN1BitLength(t *testing.T) {
tests := []struct {
bytes []byte