aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/crypto
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-09-24 21:46:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-09-24 21:46:21 +0000
commitdd931d9b48647e898dc80927c532ae93cc09e192 (patch)
tree71be2295cd79b8a182f6130611658db8628772d5 /libgo/go/crypto
parent779d8a5ad09b01428726ea5a0e6c87bd9ac3c0e4 (diff)
downloadgcc-dd931d9b48647e898dc80927c532ae93cc09e192.zip
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.gz
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.bz2
libgo: update to Go 1.11
Reviewed-on: https://go-review.googlesource.com/136435 gotools/: * Makefile.am (mostlyclean-local): Run chmod on check-go-dir to make sure it is writable. (check-go-tools): Likewise. (check-vet): Copy internal/objabi to check-vet-dir. * Makefile.in: Rebuild. From-SVN: r264546
Diffstat (limited to 'libgo/go/crypto')
-rw-r--r--libgo/go/crypto/aes/aes_gcm.go53
-rw-r--r--libgo/go/crypto/aes/aes_test.go2
-rw-r--r--libgo/go/crypto/aes/block.go4
-rw-r--r--libgo/go/crypto/aes/cbc_s390x.go4
-rw-r--r--libgo/go/crypto/aes/cipher.go7
-rw-r--r--libgo/go/crypto/aes/cipher_asm.go (renamed from libgo/go/crypto/aes/cipher_amd64.go)33
-rw-r--r--libgo/go/crypto/aes/cipher_generic.go2
-rw-r--r--libgo/go/crypto/aes/cipher_ppc64le.go12
-rw-r--r--libgo/go/crypto/aes/cipher_s390x.go23
-rw-r--r--libgo/go/crypto/aes/const.go2
-rw-r--r--libgo/go/crypto/aes/ctr_s390x.go9
-rw-r--r--libgo/go/crypto/aes/gcm_s390x.go81
-rw-r--r--libgo/go/crypto/aes/modes.go2
-rw-r--r--libgo/go/crypto/aes/modes_test.go2
-rw-r--r--libgo/go/crypto/cipher/cbc.go8
-rw-r--r--libgo/go/crypto/cipher/cfb.go8
-rw-r--r--libgo/go/crypto/cipher/cfb_test.go2
-rw-r--r--libgo/go/crypto/cipher/cipher.go2
-rw-r--r--libgo/go/crypto/cipher/ctr.go8
-rw-r--r--libgo/go/crypto/cipher/gcm.go81
-rw-r--r--libgo/go/crypto/cipher/gcm_test.go70
-rw-r--r--libgo/go/crypto/cipher/ofb.go8
-rw-r--r--libgo/go/crypto/des/cipher.go47
-rw-r--r--libgo/go/crypto/dsa/dsa.go4
-rw-r--r--libgo/go/crypto/ecdsa/ecdsa.go4
-rw-r--r--libgo/go/crypto/ecdsa/ecdsa_test.go2
-rw-r--r--libgo/go/crypto/ecdsa/example_test.go34
-rw-r--r--libgo/go/crypto/elliptic/elliptic.go6
-rw-r--r--libgo/go/crypto/elliptic/elliptic_test.go4
-rw-r--r--libgo/go/crypto/elliptic/fuzz_test.go54
-rw-r--r--libgo/go/crypto/elliptic/p224.go4
-rw-r--r--libgo/go/crypto/elliptic/p256.go8
-rw-r--r--libgo/go/crypto/elliptic/p256_asm.go (renamed from libgo/go/crypto/elliptic/p256_amd64.go)209
-rw-r--r--libgo/go/crypto/elliptic/p256_generic.go2
-rw-r--r--libgo/go/crypto/hmac/hmac.go2
-rw-r--r--libgo/go/crypto/hmac/hmac_test.go4
-rw-r--r--libgo/go/crypto/internal/cipherhw/cipherhw_amd64.go16
-rw-r--r--libgo/go/crypto/internal/cipherhw/cipherhw_s390x.go18
-rw-r--r--libgo/go/crypto/internal/cipherhw/doc.go7
-rw-r--r--libgo/go/crypto/internal/cipherhw/generic.go11
-rw-r--r--libgo/go/crypto/internal/randutil/randutil.go38
-rw-r--r--libgo/go/crypto/internal/subtle/aliasing.go34
-rw-r--r--libgo/go/crypto/internal/subtle/aliasing_appengine.go37
-rw-r--r--libgo/go/crypto/internal/subtle/aliasing_test.go50
-rw-r--r--libgo/go/crypto/md5/gen.go3
-rw-r--r--libgo/go/crypto/md5/md5.go10
-rw-r--r--libgo/go/crypto/md5/md5block.go3
-rw-r--r--libgo/go/crypto/md5/md5block_decl.go2
-rw-r--r--libgo/go/crypto/md5/md5block_generic.go2
-rw-r--r--libgo/go/crypto/rand/rand.go5
-rw-r--r--libgo/go/crypto/rand/rand_js.go27
-rw-r--r--libgo/go/crypto/rc4/rc4.go21
-rw-r--r--libgo/go/crypto/rc4/rc4_asm.go10
-rw-r--r--libgo/go/crypto/rc4/rc4_test.go4
-rw-r--r--libgo/go/crypto/rsa/pkcs1v15.go14
-rw-r--r--libgo/go/crypto/rsa/pss.go2
-rw-r--r--libgo/go/crypto/rsa/rsa.go57
-rw-r--r--libgo/go/crypto/sha1/sha1.go14
-rw-r--r--libgo/go/crypto/sha1/sha1block_s390x.go7
-rw-r--r--libgo/go/crypto/sha256/sha256.go74
-rw-r--r--libgo/go/crypto/sha256/sha256block_s390x.go7
-rw-r--r--libgo/go/crypto/sha512/sha512.go64
-rw-r--r--libgo/go/crypto/sha512/sha512block_s390x.go7
-rw-r--r--libgo/go/crypto/tls/auth.go108
-rw-r--r--libgo/go/crypto/tls/auth_test.go101
-rw-r--r--libgo/go/crypto/tls/cipher_suites.go6
-rw-r--r--libgo/go/crypto/tls/common.go54
-rw-r--r--libgo/go/crypto/tls/conn.go129
-rw-r--r--libgo/go/crypto/tls/generate_cert.go20
-rw-r--r--libgo/go/crypto/tls/handshake_client.go31
-rw-r--r--libgo/go/crypto/tls/handshake_client_test.go76
-rw-r--r--libgo/go/crypto/tls/handshake_messages.go18
-rw-r--r--libgo/go/crypto/tls/handshake_server.go65
-rw-r--r--libgo/go/crypto/tls/handshake_server_test.go44
-rw-r--r--libgo/go/crypto/tls/key_agreement.go142
-rw-r--r--libgo/go/crypto/tls/prf.go75
-rw-r--r--libgo/go/crypto/tls/prf_test.go41
-rw-r--r--libgo/go/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial89
-rw-r--r--libgo/go/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial84
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial92
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial92
-rw-r--r--libgo/go/crypto/tls/testdata/example-cert.pem11
-rw-r--r--libgo/go/crypto/tls/testdata/example-key.pem5
-rw-r--r--libgo/go/crypto/tls/tls.go9
-rw-r--r--libgo/go/crypto/tls/tls_test.go9
-rw-r--r--libgo/go/crypto/x509/cert_pool.go27
-rw-r--r--libgo/go/crypto/x509/name_constraints_test.go98
-rw-r--r--libgo/go/crypto/x509/pkcs8.go2
-rw-r--r--libgo/go/crypto/x509/pkix/pkix.go2
-rw-r--r--libgo/go/crypto/x509/root.go3
-rw-r--r--libgo/go/crypto/x509/root_cgo_darwin.go78
-rw-r--r--libgo/go/crypto/x509/root_darwin.go4
-rw-r--r--libgo/go/crypto/x509/root_js.go10
-rw-r--r--libgo/go/crypto/x509/root_plan9.go3
-rw-r--r--libgo/go/crypto/x509/root_unix.go4
-rw-r--r--libgo/go/crypto/x509/root_unix_test.go4
-rw-r--r--libgo/go/crypto/x509/root_windows.go12
-rw-r--r--libgo/go/crypto/x509/sha2_windows_test.go19
-rw-r--r--libgo/go/crypto/x509/verify.go129
-rw-r--r--libgo/go/crypto/x509/verify_test.go233
-rw-r--r--libgo/go/crypto/x509/x509.go186
-rw-r--r--libgo/go/crypto/x509/x509_test.go105
102 files changed, 2521 insertions, 1050 deletions
diff --git a/libgo/go/crypto/aes/aes_gcm.go b/libgo/go/crypto/aes/aes_gcm.go
index 3e5e235..3888010 100644
--- a/libgo/go/crypto/aes/aes_gcm.go
+++ b/libgo/go/crypto/aes/aes_gcm.go
@@ -3,21 +3,18 @@
// license that can be found in the LICENSE file.
// +build ignore
-// -build amd64
+// -build amd64 arm64
package aes
import (
"crypto/cipher"
+ subtleoverlap "crypto/internal/subtle"
"crypto/subtle"
"errors"
)
-// The following functions are defined in gcm_amd64.s.
-func hasGCMAsm() bool
-
-//go:noescape
-func aesEncBlock(dst, src *[16]byte, ks []uint32)
+// The following functions are defined in gcm_*.s.
//go:noescape
func gcmAesInit(productTable *[256]byte, ks []uint32)
@@ -37,6 +34,7 @@ func gcmAesFinish(productTable *[256]byte, tagMask, T *[16]byte, pLen, dLen uint
const (
gcmBlockSize = 16
gcmTagSize = 16
+ gcmMinimumTagSize = 12 // NIST SP 800-38D recommends tags with 12 or more bytes.
gcmStandardNonceSize = 12
)
@@ -54,8 +52,8 @@ 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) {
- g := &gcmAsm{ks: c.enc, nonceSize: nonceSize}
+func (c *aesCipherGCM) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
+ g := &gcmAsm{ks: c.enc, nonceSize: nonceSize, tagSize: tagSize}
gcmAesInit(&g.productTable, g.ks)
return g, nil
}
@@ -69,14 +67,16 @@ type gcmAsm struct {
productTable [256]byte
// nonceSize contains the expected size of the nonce, in bytes.
nonceSize int
+ // tagSize contains the size of the tag, in bytes.
+ tagSize int
}
func (g *gcmAsm) NonceSize() int {
return g.nonceSize
}
-func (*gcmAsm) Overhead() int {
- return gcmTagSize
+func (g *gcmAsm) Overhead() int {
+ return g.tagSize
}
// sliceForAppend takes a slice and a requested number of bytes. It returns a
@@ -98,10 +98,10 @@ func sliceForAppend(in []byte, n int) (head, tail []byte) {
// details.
func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
}
if uint64(len(plaintext)) > ((1<<32)-2)*BlockSize {
- panic("cipher: message too large for GCM")
+ panic("crypto/cipher: message too large for GCM")
}
var counter, tagMask [gcmBlockSize]byte
@@ -116,12 +116,15 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
gcmAesFinish(&g.productTable, &tagMask, &counter, uint64(len(nonce)), uint64(0))
}
- aesEncBlock(&tagMask, &counter, g.ks)
+ encryptBlockAsm(len(g.ks)/4-1, &g.ks[0], &tagMask[0], &counter[0])
var tagOut [gcmTagSize]byte
gcmAesData(&g.productTable, data, &tagOut)
- ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
+ ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
+ if subtleoverlap.InexactOverlap(out[:len(plaintext)], plaintext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
if len(plaintext) > 0 {
gcmAesEnc(&g.productTable, out, plaintext, &counter, &tagOut, g.ks)
}
@@ -135,18 +138,23 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
// for details.
func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
+ }
+ // Sanity check to prevent the authentication from always succeeding if an implementation
+ // leaves tagSize uninitialized, for example.
+ if g.tagSize < gcmMinimumTagSize {
+ panic("crypto/cipher: incorrect GCM tag size")
}
- if len(ciphertext) < gcmTagSize {
+ if len(ciphertext) < g.tagSize {
return nil, errOpen
}
- if uint64(len(ciphertext)) > ((1<<32)-2)*BlockSize+gcmTagSize {
+ if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(BlockSize)+uint64(g.tagSize) {
return nil, errOpen
}
- tag := ciphertext[len(ciphertext)-gcmTagSize:]
- ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
+ tag := ciphertext[len(ciphertext)-g.tagSize:]
+ ciphertext = ciphertext[:len(ciphertext)-g.tagSize]
// See GCM spec, section 7.1.
var counter, tagMask [gcmBlockSize]byte
@@ -161,18 +169,21 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
gcmAesFinish(&g.productTable, &tagMask, &counter, uint64(len(nonce)), uint64(0))
}
- aesEncBlock(&tagMask, &counter, g.ks)
+ encryptBlockAsm(len(g.ks)/4-1, &g.ks[0], &tagMask[0], &counter[0])
var expectedTag [gcmTagSize]byte
gcmAesData(&g.productTable, data, &expectedTag)
ret, out := sliceForAppend(dst, len(ciphertext))
+ if subtleoverlap.InexactOverlap(out, ciphertext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
if len(ciphertext) > 0 {
gcmAesDec(&g.productTable, out, ciphertext, &counter, &expectedTag, g.ks)
}
gcmAesFinish(&g.productTable, &tagMask, &expectedTag, uint64(len(ciphertext)), uint64(len(data)))
- if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 {
+ if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
for i := range out {
out[i] = 0
}
diff --git a/libgo/go/crypto/aes/aes_test.go b/libgo/go/crypto/aes/aes_test.go
index 2814496..bedc2da 100644
--- a/libgo/go/crypto/aes/aes_test.go
+++ b/libgo/go/crypto/aes/aes_test.go
@@ -122,7 +122,7 @@ func TestTd(t *testing.T) {
}
// Test vectors are from FIPS 197:
-// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+// https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
// Appendix A of FIPS 197: Key expansion examples
type KeyTest struct {
diff --git a/libgo/go/crypto/aes/block.go b/libgo/go/crypto/aes/block.go
index 41ea9cf..8647019 100644
--- a/libgo/go/crypto/aes/block.go
+++ b/libgo/go/crypto/aes/block.go
@@ -31,8 +31,8 @@
//
// See FIPS 197 for specification, and see Daemen and Rijmen's Rijndael submission
// for implementation details.
-// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
-// http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf
+// https://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+// https://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf
package aes
diff --git a/libgo/go/crypto/aes/cbc_s390x.go b/libgo/go/crypto/aes/cbc_s390x.go
index 6b011b2..67e928e 100644
--- a/libgo/go/crypto/aes/cbc_s390x.go
+++ b/libgo/go/crypto/aes/cbc_s390x.go
@@ -8,6 +8,7 @@ package aes
import (
"crypto/cipher"
+ "crypto/internal/subtle"
)
// Assert that aesCipherAsm implements the cbcEncAble and cbcDecAble interfaces.
@@ -50,6 +51,9 @@ func (x *cbc) CryptBlocks(dst, src []byte) {
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
if len(src) > 0 {
cryptBlocksChain(x.c, &x.iv[0], &x.b.key[0], &dst[0], &src[0], len(src))
}
diff --git a/libgo/go/crypto/aes/cipher.go b/libgo/go/crypto/aes/cipher.go
index c5a8e91..bb93fbb 100644
--- a/libgo/go/crypto/aes/cipher.go
+++ b/libgo/go/crypto/aes/cipher.go
@@ -6,6 +6,7 @@ package aes
import (
"crypto/cipher"
+ "crypto/internal/subtle"
"strconv"
)
@@ -57,6 +58,9 @@ func (c *aesCipher) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
encryptBlockGo(c.enc, dst, src)
}
@@ -67,5 +71,8 @@ func (c *aesCipher) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
decryptBlockGo(c.dec, dst, src)
}
diff --git a/libgo/go/crypto/aes/cipher_amd64.go b/libgo/go/crypto/aes/cipher_asm.go
index fbd157e..dc4251a 100644
--- a/libgo/go/crypto/aes/cipher_amd64.go
+++ b/libgo/go/crypto/aes/cipher_asm.go
@@ -2,33 +2,42 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build ignore
+// +build ignore_for_gccgo
+// +build amd64 arm64
package aes
import (
"crypto/cipher"
- "crypto/internal/cipherhw"
+ "crypto/internal/subtle"
+ "internal/cpu"
)
-// defined in asm_amd64.s
+// defined in asm_*.s
+
+//go:noescape
func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+
+//go:noescape
func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+
+//go:noescape
func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
type aesCipherAsm struct {
aesCipher
}
-var useAsm = cipherhw.AESGCMSupport()
+var supportsAES = cpu.X86.HasAES || cpu.ARM64.HasAES
+var supportsGFMUL = cpu.X86.HasPCLMULQDQ || cpu.ARM64.HasPMULL
func newCipher(key []byte) (cipher.Block, error) {
- if !useAsm {
+ if !supportsAES {
return newCipherGeneric(key)
}
n := len(key) + 28
c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
- rounds := 10
+ var rounds int
switch len(key) {
case 128 / 8:
rounds = 10
@@ -37,11 +46,11 @@ func newCipher(key []byte) (cipher.Block, error) {
case 256 / 8:
rounds = 14
}
+
expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
- if hasGCMAsm() {
+ if supportsAES && supportsGFMUL {
return &aesCipherGCM{c}, nil
}
-
return &c, nil
}
@@ -54,6 +63,9 @@ func (c *aesCipherAsm) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
}
@@ -64,13 +76,16 @@ func (c *aesCipherAsm) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
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 {
+ if supportsAES {
rounds := 10 // rounds needed for AES128
switch len(key) {
case 192 / 8:
diff --git a/libgo/go/crypto/aes/cipher_generic.go b/libgo/go/crypto/aes/cipher_generic.go
index 98169bf..19a930f0 100644
--- a/libgo/go/crypto/aes/cipher_generic.go
+++ b/libgo/go/crypto/aes/cipher_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,!s390x,!ppc64le
+// -build !amd64,!s390x,!ppc64le,!arm64
package aes
diff --git a/libgo/go/crypto/aes/cipher_ppc64le.go b/libgo/go/crypto/aes/cipher_ppc64le.go
index 1d16fe0..599ea82 100644
--- a/libgo/go/crypto/aes/cipher_ppc64le.go
+++ b/libgo/go/crypto/aes/cipher_ppc64le.go
@@ -8,28 +8,24 @@ package aes
import (
"crypto/cipher"
+ "crypto/internal/subtle"
)
// defined in asm_ppc64le.s
//go:noescape
-
func setEncryptKeyAsm(key *byte, keylen int, enc *uint32) int
//go:noescape
-
func setDecryptKeyAsm(key *byte, keylen int, dec *uint32) int
//go:noescape
-
func doEncryptKeyAsm(key *byte, keylen int, dec *uint32) int
//go:noescape
-
func encryptBlockAsm(dst, src *byte, enc *uint32)
//go:noescape
-
func decryptBlockAsm(dst, src *byte, dec *uint32)
type aesCipherAsm struct {
@@ -61,6 +57,9 @@ func (c *aesCipherAsm) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
encryptBlockAsm(&dst[0], &src[0], &c.enc[0])
}
@@ -71,6 +70,9 @@ func (c *aesCipherAsm) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
decryptBlockAsm(&dst[0], &src[0], &c.dec[0])
}
diff --git a/libgo/go/crypto/aes/cipher_s390x.go b/libgo/go/crypto/aes/cipher_s390x.go
index 253ce89..b885a45 100644
--- a/libgo/go/crypto/aes/cipher_s390x.go
+++ b/libgo/go/crypto/aes/cipher_s390x.go
@@ -8,7 +8,8 @@ package aes
import (
"crypto/cipher"
- "crypto/internal/cipherhw"
+ "crypto/internal/subtle"
+ "internal/cpu"
)
type code int
@@ -21,9 +22,9 @@ const (
)
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
+ function code // code for cipher message instruction
+ key []byte // key (128, 192 or 256 bits)
+ storage [32]byte // array backing key slice
}
// cryptBlocks invokes the cipher message (KM) instruction with
@@ -32,10 +33,12 @@ type aesCipherAsm struct {
//go:noescape
func cryptBlocks(c code, key, dst, src *byte, length int)
-var useAsm = cipherhw.AESGCMSupport()
-
func newCipher(key []byte) (cipher.Block, error) {
- if !useAsm {
+ // The aesCipherAsm type implements the cbcEncAble, cbcDecAble,
+ // ctrAble and gcmAble interfaces. We therefore need to check
+ // for all the features required to implement these modes.
+ // Keep in sync with crypto/tls/common.go.
+ if !(cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)) {
return newCipherGeneric(key)
}
@@ -67,6 +70,9 @@ func (c *aesCipherAsm) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
}
@@ -77,6 +83,9 @@ func (c *aesCipherAsm) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/aes: invalid buffer overlap")
+ }
// The decrypt function code is equal to the function code + 128.
cryptBlocks(c.function+128, &c.key[0], &dst[0], &src[0], BlockSize)
}
diff --git a/libgo/go/crypto/aes/const.go b/libgo/go/crypto/aes/const.go
index cbac5ff..4eca4b9 100644
--- a/libgo/go/crypto/aes/const.go
+++ b/libgo/go/crypto/aes/const.go
@@ -15,7 +15,7 @@ package aes
// This file contains AES constants - 8720 bytes of initialized data.
-// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+// https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
// AES is based on the mathematical behavior of binary polynomials
// (polynomials over GF(2)) modulo the irreducible polynomial x⁸ + x⁴ + x³ + x + 1.
diff --git a/libgo/go/crypto/aes/ctr_s390x.go b/libgo/go/crypto/aes/ctr_s390x.go
index 7892f79..a3c43a3 100644
--- a/libgo/go/crypto/aes/ctr_s390x.go
+++ b/libgo/go/crypto/aes/ctr_s390x.go
@@ -8,6 +8,7 @@ package aes
import (
"crypto/cipher"
+ "crypto/internal/subtle"
"unsafe"
)
@@ -66,9 +67,11 @@ func (c *aesctr) refill() {
}
func (c *aesctr) XORKeyStream(dst, src []byte) {
- if len(src) > 0 {
- // Assert len(dst) >= len(src)
- _ = dst[len(src)-1]
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
}
for len(src) > 0 {
if len(c.buffer) == 0 {
diff --git a/libgo/go/crypto/aes/gcm_s390x.go b/libgo/go/crypto/aes/gcm_s390x.go
index ba6d7ce..18b0e82 100644
--- a/libgo/go/crypto/aes/gcm_s390x.go
+++ b/libgo/go/crypto/aes/gcm_s390x.go
@@ -8,8 +8,10 @@ package aes
import (
"crypto/cipher"
+ subtleoverlap "crypto/internal/subtle"
"crypto/subtle"
"errors"
+ "internal/cpu"
)
// This file contains two implementations of AES-GCM. The first implementation
@@ -60,11 +62,13 @@ type gcmAsm struct {
block *aesCipherAsm
hashKey gcmHashKey
nonceSize int
+ tagSize int
}
const (
gcmBlockSize = 16
gcmTagSize = 16
+ gcmMinimumTagSize = 12 // NIST SP 800-38D recommends tags with 12 or more bytes.
gcmStandardNonceSize = 12
)
@@ -75,15 +79,16 @@ var _ gcmAble = (*aesCipherAsm)(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 *aesCipherAsm) NewGCM(nonceSize int) (cipher.AEAD, error) {
+func (c *aesCipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
var hk gcmHashKey
c.Encrypt(hk[:], hk[:])
g := gcmAsm{
block: c,
hashKey: hk,
nonceSize: nonceSize,
+ tagSize: tagSize,
}
- if hasKMA {
+ if cpu.S390X.HasAESGCM {
g := gcmKMA{g}
return &g, nil
}
@@ -94,8 +99,8 @@ func (g *gcmAsm) NonceSize() int {
return g.nonceSize
}
-func (*gcmAsm) Overhead() int {
- return gcmTagSize
+func (g *gcmAsm) Overhead() int {
+ return g.tagSize
}
// sliceForAppend takes a slice and a requested number of bytes. It returns a
@@ -218,13 +223,16 @@ func (g *gcmAsm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSi
// details.
func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
}
if uint64(len(plaintext)) > ((1<<32)-2)*BlockSize {
- panic("cipher: message too large for GCM")
+ panic("crypto/cipher: message too large for GCM")
}
- ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
+ ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
+ if subtleoverlap.InexactOverlap(out[:len(plaintext)], plaintext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
counter := g.deriveCounter(nonce)
@@ -232,8 +240,10 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
g.block.Encrypt(tagMask[:], counter[:])
counter.inc()
+ var tagOut [gcmTagSize]byte
g.counterCrypt(out, plaintext, &counter)
- g.auth(out[len(plaintext):], out[:len(plaintext)], data, &tagMask)
+ g.auth(tagOut[:], out[:len(plaintext)], data, &tagMask)
+ copy(out[len(plaintext):], tagOut[:])
return ret
}
@@ -242,17 +252,22 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
// for details.
func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
+ }
+ // Sanity check to prevent the authentication from always succeeding if an implementation
+ // leaves tagSize uninitialized, for example.
+ if g.tagSize < gcmMinimumTagSize {
+ panic("crypto/cipher: incorrect GCM tag size")
}
- if len(ciphertext) < gcmTagSize {
+ if len(ciphertext) < g.tagSize {
return nil, errOpen
}
- if uint64(len(ciphertext)) > ((1<<32)-2)*BlockSize+gcmTagSize {
+ if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(BlockSize)+uint64(g.tagSize) {
return nil, errOpen
}
- tag := ciphertext[len(ciphertext)-gcmTagSize:]
- ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
+ tag := ciphertext[len(ciphertext)-g.tagSize:]
+ ciphertext = ciphertext[:len(ciphertext)-g.tagSize]
counter := g.deriveCounter(nonce)
@@ -264,8 +279,11 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
g.auth(expectedTag[:], ciphertext, data, &tagMask)
ret, out := sliceForAppend(dst, len(ciphertext))
+ if subtleoverlap.InexactOverlap(out, ciphertext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
- if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 {
+ if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
// The AESNI code decrypts and authenticates concurrently, and
// so overwrites dst in the event of a tag mismatch. That
// behavior is mimicked here in order to be consistent across
@@ -280,13 +298,6 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
return ret, nil
}
-// supportsKMA reports whether the message-security-assist 8 facility is available.
-// This function call may be expensive so hasKMA should be queried instead.
-func supportsKMA() bool
-
-// hasKMA contains the result of supportsKMA.
-var hasKMA = supportsKMA()
-
// gcmKMA implements the cipher.AEAD interface using the KMA instruction. It should
// only be used if hasKMA is true.
type gcmKMA struct {
@@ -312,13 +323,16 @@ func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
// details.
func (g *gcmKMA) Seal(dst, nonce, plaintext, data []byte) []byte {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
}
if uint64(len(plaintext)) > ((1<<32)-2)*BlockSize {
- panic("cipher: message too large for GCM")
+ panic("crypto/cipher: message too large for GCM")
}
- ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
+ ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
+ if subtleoverlap.InexactOverlap(out[:len(plaintext)], plaintext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
counter := g.deriveCounter(nonce)
fc := g.block.function | kmaLAAD | kmaLPC
@@ -334,18 +348,25 @@ func (g *gcmKMA) Seal(dst, nonce, plaintext, data []byte) []byte {
// for details.
func (g *gcmKMA) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
}
- if len(ciphertext) < gcmTagSize {
+ if len(ciphertext) < g.tagSize {
return nil, errOpen
}
- if uint64(len(ciphertext)) > ((1<<32)-2)*BlockSize+gcmTagSize {
+ if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(BlockSize)+uint64(g.tagSize) {
return nil, errOpen
}
- tag := ciphertext[len(ciphertext)-gcmTagSize:]
- ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
+ tag := ciphertext[len(ciphertext)-g.tagSize:]
+ ciphertext = ciphertext[:len(ciphertext)-g.tagSize]
ret, out := sliceForAppend(dst, len(ciphertext))
+ if subtleoverlap.InexactOverlap(out, ciphertext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
+
+ if g.tagSize < gcmMinimumTagSize {
+ panic("crypto/cipher: incorrect GCM tag size")
+ }
counter := g.deriveCounter(nonce)
fc := g.block.function | kmaLAAD | kmaLPC | kmaDecrypt
@@ -353,7 +374,7 @@ func (g *gcmKMA) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
var expectedTag [gcmTagSize]byte
kmaGCM(fc, g.block.key, out[:len(ciphertext)], ciphertext, data, &expectedTag, &counter)
- if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 {
+ if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
// The AESNI code decrypts and authenticates concurrently, and
// so overwrites dst in the event of a tag mismatch. That
// behavior is mimicked here in order to be consistent across
diff --git a/libgo/go/crypto/aes/modes.go b/libgo/go/crypto/aes/modes.go
index 1623fc1..5c0b08e 100644
--- a/libgo/go/crypto/aes/modes.go
+++ b/libgo/go/crypto/aes/modes.go
@@ -12,7 +12,7 @@ import (
// implementation of GCM through the AEAD interface.
// See crypto/cipher/gcm.go.
type gcmAble interface {
- NewGCM(size int) (cipher.AEAD, error)
+ NewGCM(nonceSize, tagSize int) (cipher.AEAD, error)
}
// cbcEncAble is implemented by cipher.Blocks that can provide an optimized
diff --git a/libgo/go/crypto/aes/modes_test.go b/libgo/go/crypto/aes/modes_test.go
index 8c2e5f0..a3364c9 100644
--- a/libgo/go/crypto/aes/modes_test.go
+++ b/libgo/go/crypto/aes/modes_test.go
@@ -25,7 +25,7 @@ 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) {
+func (*testBlock) NewGCM(int, int) (cipher.AEAD, error) {
return &testAEAD{}, nil
}
func (*testBlock) NewCBCEncrypter([]byte) cipher.BlockMode {
diff --git a/libgo/go/crypto/cipher/cbc.go b/libgo/go/crypto/cipher/cbc.go
index 0367d59..0d07192 100644
--- a/libgo/go/crypto/cipher/cbc.go
+++ b/libgo/go/crypto/cipher/cbc.go
@@ -11,6 +11,8 @@
package cipher
+import "crypto/internal/subtle"
+
type cbc struct {
b Block
blockSize int
@@ -59,6 +61,9 @@ func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
iv := x.iv
@@ -116,6 +121,9 @@ func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
if len(src) == 0 {
return
}
diff --git a/libgo/go/crypto/cipher/cfb.go b/libgo/go/crypto/cipher/cfb.go
index 9b4eebf..80c9bc2 100644
--- a/libgo/go/crypto/cipher/cfb.go
+++ b/libgo/go/crypto/cipher/cfb.go
@@ -6,6 +6,8 @@
package cipher
+import "crypto/internal/subtle"
+
type cfb struct {
b Block
next []byte
@@ -16,6 +18,12 @@ type cfb struct {
}
func (x *cfb) XORKeyStream(dst, src []byte) {
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
for len(src) > 0 {
if x.outUsed == len(x.out) {
x.b.Encrypt(x.out, x.next)
diff --git a/libgo/go/crypto/cipher/cfb_test.go b/libgo/go/crypto/cipher/cfb_test.go
index 9b544bb..ecb716d 100644
--- a/libgo/go/crypto/cipher/cfb_test.go
+++ b/libgo/go/crypto/cipher/cfb_test.go
@@ -14,7 +14,7 @@ import (
)
// cfbTests contains the test vectors from
-// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, section
+// https://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, section
// F.3.13.
var cfbTests = []struct {
key, iv, plaintext, ciphertext string
diff --git a/libgo/go/crypto/cipher/cipher.go b/libgo/go/crypto/cipher/cipher.go
index 31c14d7..7e1a4de 100644
--- a/libgo/go/crypto/cipher/cipher.go
+++ b/libgo/go/crypto/cipher/cipher.go
@@ -4,7 +4,7 @@
// Package cipher implements standard block cipher modes that can be wrapped
// around low-level block cipher implementations.
-// See http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html
+// See https://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html
// and NIST Special Publication 800-38A.
package cipher
diff --git a/libgo/go/crypto/cipher/ctr.go b/libgo/go/crypto/cipher/ctr.go
index 75f46cf..cba028d 100644
--- a/libgo/go/crypto/cipher/ctr.go
+++ b/libgo/go/crypto/cipher/ctr.go
@@ -12,6 +12,8 @@
package cipher
+import "crypto/internal/subtle"
+
type ctr struct {
b Block
ctr []byte
@@ -71,6 +73,12 @@ func (x *ctr) refill() {
}
func (x *ctr) XORKeyStream(dst, src []byte) {
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
for len(src) > 0 {
if x.outUsed >= len(x.out)-x.b.BlockSize() {
x.refill()
diff --git a/libgo/go/crypto/cipher/gcm.go b/libgo/go/crypto/cipher/gcm.go
index 28f3ddd..6321e9e 100644
--- a/libgo/go/crypto/cipher/gcm.go
+++ b/libgo/go/crypto/cipher/gcm.go
@@ -5,6 +5,7 @@
package cipher
import (
+ subtleoverlap "crypto/internal/subtle"
"crypto/subtle"
"errors"
)
@@ -26,8 +27,8 @@ type AEAD interface {
// slice. The nonce must be NonceSize() bytes long and unique for all
// time, for a given key.
//
- // The plaintext and dst must overlap exactly or not at all. To reuse
- // plaintext's storage for the encrypted output, use plaintext[:0] as dst.
+ // To reuse plaintext's storage for the encrypted output, use plaintext[:0]
+ // as dst. Otherwise, the remaining capacity of dst must not overlap plaintext.
Seal(dst, nonce, plaintext, additionalData []byte) []byte
// Open decrypts and authenticates ciphertext, authenticates the
@@ -36,8 +37,8 @@ type AEAD interface {
// bytes long and both it and the additional data must match the
// value passed to Seal.
//
- // The ciphertext and dst must overlap exactly or not at all. To reuse
- // ciphertext's storage for the decrypted output, use ciphertext[:0] as dst.
+ // To reuse ciphertext's storage for the decrypted output, use ciphertext[:0]
+ // as dst. Otherwise, the remaining capacity of dst must not overlap plaintext.
//
// Even if the function fails, the contents of dst, up to its capacity,
// may be overwritten.
@@ -48,7 +49,7 @@ type AEAD interface {
// implementation of GCM, like crypto/aes. NewGCM will check for this interface
// and return the specific AEAD if found.
type gcmAble interface {
- NewGCM(int) (AEAD, error)
+ NewGCM(nonceSize, tagSize int) (AEAD, error)
}
// gcmFieldElement represents a value in GF(2¹²⁸). In order to reflect the GCM
@@ -63,10 +64,11 @@ type gcmFieldElement struct {
}
// gcm represents a Galois Counter Mode with a specific key. See
-// http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
+// https://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
type gcm struct {
cipher Block
nonceSize int
+ tagSize int
// productTable contains the first sixteen powers of the key, H.
// However, they are in bit reversed order. See NewGCMWithNonceSize.
productTable [16]gcmFieldElement
@@ -79,7 +81,7 @@ type gcm struct {
// An exception is when the underlying Block was created by aes.NewCipher
// on systems with hardware support for AES. See the crypto/aes package documentation for details.
func NewGCM(cipher Block) (AEAD, error) {
- return NewGCMWithNonceSize(cipher, gcmStandardNonceSize)
+ return newGCMWithNonceAndTagSize(cipher, gcmStandardNonceSize, gcmTagSize)
}
// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois
@@ -89,8 +91,28 @@ func NewGCM(cipher Block) (AEAD, error) {
// cryptosystem that uses non-standard nonce lengths. All other users should use
// NewGCM, which is faster and more resistant to misuse.
func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error) {
+ return newGCMWithNonceAndTagSize(cipher, size, gcmTagSize)
+}
+
+// NewGCMWithTagSize returns the given 128-bit, block cipher wrapped in Galois
+// Counter Mode, which generates tags with the given length.
+//
+// Tag sizes between 12 and 16 bytes are allowed.
+//
+// Only use this function if you require compatibility with an existing
+// cryptosystem that uses non-standard tag lengths. All other users should use
+// NewGCM, which is more resistant to misuse.
+func NewGCMWithTagSize(cipher Block, tagSize int) (AEAD, error) {
+ return newGCMWithNonceAndTagSize(cipher, gcmStandardNonceSize, tagSize)
+}
+
+func newGCMWithNonceAndTagSize(cipher Block, nonceSize, tagSize int) (AEAD, error) {
+ if tagSize < gcmMinimumTagSize || tagSize > gcmBlockSize {
+ return nil, errors.New("cipher: incorrect tag size given to GCM")
+ }
+
if cipher, ok := cipher.(gcmAble); ok {
- return cipher.NewGCM(size)
+ return cipher.NewGCM(nonceSize, tagSize)
}
if cipher.BlockSize() != gcmBlockSize {
@@ -100,7 +122,7 @@ func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error) {
var key [gcmBlockSize]byte
cipher.Encrypt(key[:], key[:])
- g := &gcm{cipher: cipher, nonceSize: size}
+ g := &gcm{cipher: cipher, nonceSize: nonceSize, tagSize: tagSize}
// We precompute 16 multiples of |key|. However, when we do lookups
// into this table we'll be using bits from a field element and
@@ -124,6 +146,7 @@ func NewGCMWithNonceSize(cipher Block, size int) (AEAD, error) {
const (
gcmBlockSize = 16
gcmTagSize = 16
+ gcmMinimumTagSize = 12 // NIST SP 800-38D recommends tags with 12 or more bytes.
gcmStandardNonceSize = 12
)
@@ -131,19 +154,22 @@ func (g *gcm) NonceSize() int {
return g.nonceSize
}
-func (*gcm) Overhead() int {
- return gcmTagSize
+func (g *gcm) Overhead() int {
+ return g.tagSize
}
func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
}
if uint64(len(plaintext)) > ((1<<32)-2)*uint64(g.cipher.BlockSize()) {
- panic("cipher: message too large for GCM")
+ panic("crypto/cipher: message too large for GCM")
}
- ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize)
+ ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
+ if subtleoverlap.InexactOverlap(out, plaintext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
var counter, tagMask [gcmBlockSize]byte
g.deriveCounter(&counter, nonce)
@@ -152,7 +178,10 @@ func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte {
gcmInc32(&counter)
g.counterCrypt(out, plaintext, &counter)
- g.auth(out[len(plaintext):], out[:len(plaintext)], data, &tagMask)
+
+ var tag [gcmTagSize]byte
+ g.auth(tag[:], out[:len(plaintext)], data, &tagMask)
+ copy(out[len(plaintext):], tag[:])
return ret
}
@@ -161,18 +190,23 @@ var errOpen = errors.New("cipher: message authentication failed")
func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(nonce) != g.nonceSize {
- panic("cipher: incorrect nonce length given to GCM")
+ panic("crypto/cipher: incorrect nonce length given to GCM")
+ }
+ // Sanity check to prevent the authentication from always succeeding if an implementation
+ // leaves tagSize uninitialized, for example.
+ if g.tagSize < gcmMinimumTagSize {
+ panic("crypto/cipher: incorrect GCM tag size")
}
- if len(ciphertext) < gcmTagSize {
+ if len(ciphertext) < g.tagSize {
return nil, errOpen
}
- if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(g.cipher.BlockSize())+gcmTagSize {
+ if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(g.cipher.BlockSize())+uint64(g.tagSize) {
return nil, errOpen
}
- tag := ciphertext[len(ciphertext)-gcmTagSize:]
- ciphertext = ciphertext[:len(ciphertext)-gcmTagSize]
+ tag := ciphertext[len(ciphertext)-g.tagSize:]
+ ciphertext = ciphertext[:len(ciphertext)-g.tagSize]
var counter, tagMask [gcmBlockSize]byte
g.deriveCounter(&counter, nonce)
@@ -184,8 +218,11 @@ func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
g.auth(expectedTag[:], ciphertext, data, &tagMask)
ret, out := sliceForAppend(dst, len(ciphertext))
+ if subtleoverlap.InexactOverlap(out, ciphertext) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
- if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 {
+ if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
// The AESNI code decrypts and authenticates concurrently, and
// so overwrites dst in the event of a tag mismatch. That
// behavior is mimicked here in order to be consistent across
@@ -387,6 +424,7 @@ func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize]
}
func getUint64(data []byte) uint64 {
+ _ = data[7] // bounds check hint to compiler; see golang.org/issue/14808
r := uint64(data[0])<<56 |
uint64(data[1])<<48 |
uint64(data[2])<<40 |
@@ -399,6 +437,7 @@ func getUint64(data []byte) uint64 {
}
func putUint64(out []byte, v uint64) {
+ _ = out[7] // bounds check hint to compiler; see golang.org/issue/14808
out[0] = byte(v >> 56)
out[1] = byte(v >> 48)
out[2] = byte(v >> 40)
diff --git a/libgo/go/crypto/cipher/gcm_test.go b/libgo/go/crypto/cipher/gcm_test.go
index 6878b4c..64d5cc0 100644
--- a/libgo/go/crypto/cipher/gcm_test.go
+++ b/libgo/go/crypto/cipher/gcm_test.go
@@ -188,6 +188,35 @@ var aesGCMTests = []struct {
"0feccdfae8ed65fa31a0858a1c466f79e8aa658c2f3ba93c3f92158b4e30955e1c62580450beff",
"b69a7e17bb5af688883274550a4ded0d1aff49a0b18343f4b382f745c163f7f714c9206a32a1ff012427e19431951edd0a755e5f491b0eedfd7df68bbc6085dd2888607a2f998c3e881eb1694109250db28291e71f4ad344a125624fb92e16ea9815047cd1111cabfdc9cb8c3b4b0f40aa91d31774009781231400789ed545404af6c3f76d07ddc984a7bd8f52728159782832e298cc4d529be96d17be898efd83e44dc7b0e2efc645849fd2bba61fef0ae7be0dcab233cc4e2b7ba4e887de9c64b97f2a1818aa54371a8d629dae37975f7784e5e3cc77055ed6e975b1e5f55e6bbacdc9f295ce4ada2c16113cd5b323cf78b7dde39f4a87aa8c141a31174e3584ccbd380cf5ec6d1dba539928b084fa9683e9c0953acf47cc3ac384a2c38914f1da01fb2cfd78905c2b58d36b2574b9df15535d82",
},
+ // These cases test non-standard tag sizes.
+ {
+ "89c54b0d3bc3c397d5039058c220685f",
+ "bc7f45c00868758d62d4bb4d",
+ "582670b0baf5540a3775b6615605bd05",
+ "48d16cda0337105a50e2ed76fd18e114",
+ "fc2d4c4eee2209ddbba6663c02765e6955e783b00156f5da0446e2970b877f",
+ },
+ {
+ "bad6049678bf75c9087b3e3ae7e72c13",
+ "a0a017b83a67d8f1b883e561",
+ "a1be93012f05a1958440f74a5311f4a1",
+ "f7c27b51d5367161dc2ff1e9e3edc6f2",
+ "36f032f7e3dc3275ca22aedcdc68436b99a2227f8bb69d45ea5d8842cd08",
+ },
+ {
+ "66a3c722ccf9709525650973ecc100a9",
+ "1621d42d3a6d42a2d2bf9494",
+ "61fa9dbbed2190fbc2ffabf5d2ea4ff8",
+ "d7a9b6523b8827068a6354a6d166c6b9",
+ "fef3b20f40e08a49637cc82f4c89b8603fd5c0132acfab97b5fff651c4",
+ },
+ {
+ "562ae8aadb8d23e0f271a99a7d1bd4d1",
+ "f7a5e2399413b89b6ad31aff",
+ "bbdc3504d803682aa08a773cde5f231a",
+ "2b9680b886b3efb7c6354b38c63b5373",
+ "e2b7e5ed5ff27fc8664148f5a628a46dcbf2015184fffb82f2651c36",
+ },
}
func TestAESGCM(t *testing.T) {
@@ -201,9 +230,29 @@ func TestAESGCM(t *testing.T) {
nonce, _ := hex.DecodeString(test.nonce)
plaintext, _ := hex.DecodeString(test.plaintext)
ad, _ := hex.DecodeString(test.ad)
- aesgcm, err := cipher.NewGCMWithNonceSize(aes, len(nonce))
- if err != nil {
- t.Fatal(err)
+ tagSize := (len(test.result) - len(test.plaintext)) / 2
+
+ var aesgcm cipher.AEAD
+ switch {
+ // Handle non-standard nonce sizes
+ case tagSize != 16:
+ aesgcm, err = cipher.NewGCMWithTagSize(aes, tagSize)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Handle non-standard tag sizes
+ case len(nonce) != 12:
+ aesgcm, err = cipher.NewGCMWithNonceSize(aes, len(nonce))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ default:
+ aesgcm, err = cipher.NewGCM(aes)
+ if err != nil {
+ t.Fatal(err)
+ }
}
ct := aesgcm.Seal(nil, nonce, plaintext, ad)
@@ -245,6 +294,19 @@ func TestAESGCM(t *testing.T) {
}
}
+func TestGCMInvalidTagSize(t *testing.T) {
+ key, _ := hex.DecodeString("ab72c77b97cb5fe9a382d9fe81ffdbed")
+
+ aes, _ := aes.NewCipher(key)
+
+ for _, tagSize := range []int{0, 1, aes.BlockSize() + 1} {
+ aesgcm, err := cipher.NewGCMWithTagSize(aes, tagSize)
+ if aesgcm != nil || err == nil {
+ t.Fatalf("NewGCMWithNonceAndTagSize was successful with an invalid %d-byte tag size", tagSize)
+ }
+ }
+}
+
func TestTagFailureOverwrite(t *testing.T) {
// The AESNI GCM code decrypts and authenticates concurrently and so
// overwrites the output buffer before checking the authentication tag.
@@ -362,7 +424,7 @@ func TestGCMAsm(t *testing.T) {
// generate permutations
type pair struct{ align, length int }
- lengths := []int{0, 8192, 8193, 8208}
+ lengths := []int{0, 156, 8192, 8193, 8208}
keySizes := []int{16, 24, 32}
alignments := []int{0, 1, 2, 3}
if testing.Short() {
diff --git a/libgo/go/crypto/cipher/ofb.go b/libgo/go/crypto/cipher/ofb.go
index 7b35f89..fc47724 100644
--- a/libgo/go/crypto/cipher/ofb.go
+++ b/libgo/go/crypto/cipher/ofb.go
@@ -6,6 +6,8 @@
package cipher
+import "crypto/internal/subtle"
+
type ofb struct {
b Block
cipher []byte
@@ -54,6 +56,12 @@ func (x *ofb) refill() {
}
func (x *ofb) XORKeyStream(dst, src []byte) {
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
for len(src) > 0 {
if x.outUsed >= len(x.out)-x.b.BlockSize() {
x.refill()
diff --git a/libgo/go/crypto/des/cipher.go b/libgo/go/crypto/des/cipher.go
index 46af5b0..9e6779c 100644
--- a/libgo/go/crypto/des/cipher.go
+++ b/libgo/go/crypto/des/cipher.go
@@ -6,6 +6,7 @@ package des
import (
"crypto/cipher"
+ "crypto/internal/subtle"
"encoding/binary"
"strconv"
)
@@ -37,9 +38,31 @@ func NewCipher(key []byte) (cipher.Block, error) {
func (c *desCipher) BlockSize() int { return BlockSize }
-func (c *desCipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) }
+func (c *desCipher) Encrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/des: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/des: output not full block")
+ }
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/des: invalid buffer overlap")
+ }
+ encryptBlock(c.subkeys[:], dst, src)
+}
-func (c *desCipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) }
+func (c *desCipher) Decrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/des: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/des: output not full block")
+ }
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/des: invalid buffer overlap")
+ }
+ decryptBlock(c.subkeys[:], dst, src)
+}
// A tripleDESCipher is an instance of TripleDES encryption.
type tripleDESCipher struct {
@@ -62,6 +85,16 @@ func NewTripleDESCipher(key []byte) (cipher.Block, error) {
func (c *tripleDESCipher) BlockSize() int { return BlockSize }
func (c *tripleDESCipher) Encrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/des: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/des: output not full block")
+ }
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/des: invalid buffer overlap")
+ }
+
b := binary.BigEndian.Uint64(src)
b = permuteInitialBlock(b)
left, right := uint32(b>>32), uint32(b)
@@ -87,6 +120,16 @@ func (c *tripleDESCipher) Encrypt(dst, src []byte) {
}
func (c *tripleDESCipher) Decrypt(dst, src []byte) {
+ if len(src) < BlockSize {
+ panic("crypto/des: input not full block")
+ }
+ if len(dst) < BlockSize {
+ panic("crypto/des: output not full block")
+ }
+ if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+ panic("crypto/des: invalid buffer overlap")
+ }
+
b := binary.BigEndian.Uint64(src)
b = permuteInitialBlock(b)
left, right := uint32(b>>32), uint32(b)
diff --git a/libgo/go/crypto/dsa/dsa.go b/libgo/go/crypto/dsa/dsa.go
index e945855..575314b 100644
--- a/libgo/go/crypto/dsa/dsa.go
+++ b/libgo/go/crypto/dsa/dsa.go
@@ -11,6 +11,8 @@ import (
"errors"
"io"
"math/big"
+
+ "crypto/internal/randutil"
)
// Parameters represents the domain parameters for a key. These parameters can
@@ -195,6 +197,8 @@ func fermatInverse(k, P *big.Int) *big.Int {
// Be aware that calling Sign with an attacker-controlled PrivateKey may
// require an arbitrary amount of CPU.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+ randutil.MaybeReadByte(rand)
+
// FIPS 186-3, section 4.6
n := priv.Q.BitLen()
diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go
index 755ed28..2bab14c 100644
--- a/libgo/go/crypto/ecdsa/ecdsa.go
+++ b/libgo/go/crypto/ecdsa/ecdsa.go
@@ -26,6 +26,8 @@ import (
"errors"
"io"
"math/big"
+
+ "crypto/internal/randutil"
)
// A invertible implements fast inverse mod Curve.Params().N
@@ -152,6 +154,8 @@ var errZeroParam = errors.New("zero parameter")
// 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) {
+ randutil.MaybeReadByte(rand)
+
// Get min(log2(q) / 2, 256) bits of entropy from rand.
entropylen := (priv.Curve.Params().BitSize + 7) / 16
if entropylen > 32 {
diff --git a/libgo/go/crypto/ecdsa/ecdsa_test.go b/libgo/go/crypto/ecdsa/ecdsa_test.go
index 9224a03..6284e06 100644
--- a/libgo/go/crypto/ecdsa/ecdsa_test.go
+++ b/libgo/go/crypto/ecdsa/ecdsa_test.go
@@ -213,7 +213,7 @@ func fromHex(s string) *big.Int {
func TestVectors(t *testing.T) {
// This test runs the full set of NIST test vectors from
- // http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
+ // https://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
//
// The SigVer.rsp file has been edited to remove test vectors for
// unsupported algorithms and has been compressed.
diff --git a/libgo/go/crypto/ecdsa/example_test.go b/libgo/go/crypto/ecdsa/example_test.go
new file mode 100644
index 0000000..7c7fb1b
--- /dev/null
+++ b/libgo/go/crypto/ecdsa/example_test.go
@@ -0,0 +1,34 @@
+// Copyright 2018 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 gccgo_examples
+
+package ecdsa_test
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/sha256"
+ "fmt"
+)
+
+func Example() {
+ privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ if err != nil {
+ panic(err)
+ }
+
+ msg := "hello, world"
+ hash := sha256.Sum256([]byte(msg))
+
+ r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:])
+ if err != nil {
+ panic(err)
+ }
+ fmt.Printf("signature: (0x%x, 0x%x)\n", r, s)
+
+ valid := ecdsa.Verify(&privateKey.PublicKey, hash[:], r, s)
+ fmt.Println("signature verified:", valid)
+}
diff --git a/libgo/go/crypto/elliptic/elliptic.go b/libgo/go/crypto/elliptic/elliptic.go
index 35aacf2..4fc2b5e 100644
--- a/libgo/go/crypto/elliptic/elliptic.go
+++ b/libgo/go/crypto/elliptic/elliptic.go
@@ -20,7 +20,7 @@ import (
)
// A Curve represents a short-form Weierstrass curve with a=-3.
-// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
+// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
type Curve interface {
// Params returns the parameters for the curve.
Params() *CurveParams
@@ -108,7 +108,7 @@ func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
// (x2, y2, z2) and returns their sum, also in Jacobian form.
func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
- // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
+ // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int)
if z1.Sign() == 0 {
x3.Set(x2)
@@ -191,7 +191,7 @@ func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
// returns its double, also in Jacobian form.
func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
- // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
delta := new(big.Int).Mul(z, z)
delta.Mod(delta, curve.P)
gamma := new(big.Int).Mul(y, y)
diff --git a/libgo/go/crypto/elliptic/elliptic_test.go b/libgo/go/crypto/elliptic/elliptic_test.go
index f661359..09c5483 100644
--- a/libgo/go/crypto/elliptic/elliptic_test.go
+++ b/libgo/go/crypto/elliptic/elliptic_test.go
@@ -608,7 +608,7 @@ func TestUnmarshalToLargeCoordinates(t *testing.T) {
copy(invalidX[33:], y.Bytes())
if X, Y := Unmarshal(curve, invalidX); X != nil || Y != nil {
- t.Errorf("Unmarshal accpets invalid X coordinate")
+ t.Errorf("Unmarshal accepts invalid X coordinate")
}
// This is a point on the curve with a small y value, small enough that we can add p and still be within 32 bytes.
@@ -625,6 +625,6 @@ func TestUnmarshalToLargeCoordinates(t *testing.T) {
copy(invalidY[33:], y.Bytes())
if X, Y := Unmarshal(curve, invalidY); X != nil || Y != nil {
- t.Errorf("Unmarshal accpets invalid Y coordinate")
+ t.Errorf("Unmarshal accepts invalid Y coordinate")
}
}
diff --git a/libgo/go/crypto/elliptic/fuzz_test.go b/libgo/go/crypto/elliptic/fuzz_test.go
new file mode 100644
index 0000000..10196cf
--- /dev/null
+++ b/libgo/go/crypto/elliptic/fuzz_test.go
@@ -0,0 +1,54 @@
+// Copyright 2018 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 arm64
+
+package elliptic
+
+import (
+ "crypto/rand"
+ "testing"
+ "time"
+)
+
+func TestFuzz(t *testing.T) {
+
+ p256 := P256()
+ p256Generic := p256.Params()
+
+ var scalar1 [32]byte
+ var scalar2 [32]byte
+ var timeout *time.Timer
+
+ if testing.Short() {
+ timeout = time.NewTimer(500 * time.Millisecond)
+ } else {
+ timeout = time.NewTimer(2 * time.Second)
+ }
+
+ for {
+ select {
+ case <-timeout.C:
+ return
+ default:
+ }
+
+ rand.Read(scalar1[:])
+ rand.Read(scalar2[:])
+
+ x, y := p256.ScalarBaseMult(scalar1[:])
+ x2, y2 := p256Generic.ScalarBaseMult(scalar1[:])
+
+ xx, yy := p256.ScalarMult(x, y, scalar2[:])
+ xx2, yy2 := p256Generic.ScalarMult(x2, y2, scalar2[:])
+
+ if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
+ t.Fatalf("ScalarBaseMult does not match reference result with scalar: %x, please report this error to security@golang.org", scalar1)
+ }
+
+ if xx.Cmp(xx2) != 0 || yy.Cmp(yy2) != 0 {
+ t.Fatalf("ScalarMult does not match reference result with scalars: %x and %x, please report this error to security@golang.org", scalar1, scalar2)
+ }
+ }
+}
diff --git a/libgo/go/crypto/elliptic/p224.go b/libgo/go/crypto/elliptic/p224.go
index 22d0e24..2ea63f3 100644
--- a/libgo/go/crypto/elliptic/p224.go
+++ b/libgo/go/crypto/elliptic/p224.go
@@ -7,7 +7,7 @@ package elliptic
// This is a constant-time, 32-bit implementation of P224. See FIPS 186-3,
// section D.2.2.
//
-// See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background.
+// See https://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background.
import (
"math/big"
@@ -503,7 +503,7 @@ func p224Contract(out, in *p224FieldElement) {
// p224AddJacobian computes *out = a+b where a != b.
func p224AddJacobian(x3, y3, z3, x1, y1, z1, x2, y2, z2 *p224FieldElement) {
- // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-p224Add-2007-bl
+ // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-p224Add-2007-bl
var z1z1, z2z2, u1, u2, s1, s2, h, i, j, r, v p224FieldElement
var c p224LargeFieldElement
diff --git a/libgo/go/crypto/elliptic/p256.go b/libgo/go/crypto/elliptic/p256.go
index a0933dc..937d2a4 100644
--- a/libgo/go/crypto/elliptic/p256.go
+++ b/libgo/go/crypto/elliptic/p256.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
+// -build !amd64,!arm64
package elliptic
@@ -817,7 +817,7 @@ func p256Scalar8(out *[p256Limbs]uint32) {
// p256PointDouble sets {xOut,yOut,zOut} = 2*{x,y,z}.
//
-// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
+// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
func p256PointDouble(xOut, yOut, zOut, x, y, z *[p256Limbs]uint32) {
var delta, gamma, alpha, beta, tmp, tmp2 [p256Limbs]uint32
@@ -850,7 +850,7 @@ func p256PointDouble(xOut, yOut, zOut, x, y, z *[p256Limbs]uint32) {
// p256PointAddMixed sets {xOut,yOut,zOut} = {x1,y1,z1} + {x2,y2,1}.
// (i.e. the second point is affine.)
//
-// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
+// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
//
// Note that this function does not handle P+P, infinity+P nor P+infinity
// correctly.
@@ -886,7 +886,7 @@ func p256PointAddMixed(xOut, yOut, zOut, x1, y1, z1, x2, y2 *[p256Limbs]uint32)
// p256PointAdd sets {xOut,yOut,zOut} = {x1,y1,z1} + {x2,y2,z2}.
//
-// See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
+// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
//
// Note that this function does not handle P+P, infinity+P nor P+infinity
// correctly.
diff --git a/libgo/go/crypto/elliptic/p256_amd64.go b/libgo/go/crypto/elliptic/p256_asm.go
index f108e73..aee065b 100644
--- a/libgo/go/crypto/elliptic/p256_amd64.go
+++ b/libgo/go/crypto/elliptic/p256_asm.go
@@ -7,11 +7,11 @@
// detail in:
// S.Gueron and V.Krasnov, "Fast prime field elliptic-curve cryptography with
// 256-bit primes"
-// http://link.springer.com/article/10.1007%2Fs13389-014-0090-x
+// https://link.springer.com/article/10.1007%2Fs13389-014-0090-x
// https://eprint.iacr.org/2013/816.pdf
-// +build ignore
-// +build amd64
+// +build ignore_for_gccgo
+// +build amd64 arm64
package elliptic
@@ -32,7 +32,7 @@ type (
var (
p256 p256Curve
- p256Precomputed *[37][64 * 8]uint64
+ p256Precomputed *[43][32 * 8]uint64
precomputeOnce sync.Once
)
@@ -51,14 +51,14 @@ func (curve p256Curve) Params() *CurveParams {
return curve.CurveParams
}
-// Functions implemented in p256_asm_amd64.s
+// Functions implemented in p256_asm_*64.s
// Montgomery multiplication modulo P256
//go:noescape
func p256Mul(res, in1, in2 []uint64)
-// Montgomery square modulo P256
+// Montgomery square modulo P256, repeated n times (n >= 1)
//go:noescape
-func p256Sqr(res, in []uint64)
+func p256Sqr(res, in []uint64, n int)
// Montgomery multiplication by 1
//go:noescape
@@ -122,11 +122,20 @@ func (curve p256Curve) Inverse(k *big.Int) *big.Int {
k = new(big.Int).Mod(k, p256.N)
}
- // table will store precomputed powers of x. The four words at index
- // 4×i store x^(i+1).
- var table [4 * 15]uint64
+ // table will store precomputed powers of x.
+ var table [4 * 9]uint64
+ var (
+ _1 = table[4*0 : 4*1]
+ _11 = table[4*1 : 4*2]
+ _101 = table[4*2 : 4*3]
+ _111 = table[4*3 : 4*4]
+ _1111 = table[4*4 : 4*5]
+ _10101 = table[4*5 : 4*6]
+ _101111 = table[4*6 : 4*7]
+ x = table[4*7 : 4*8]
+ t = table[4*8 : 4*9]
+ )
- x := make([]uint64, 4)
fromBig(x[:], k)
// This code operates in the Montgomery domain where R = 2^256 mod n
// and n is the order of the scalar field. (See initP256 for the
@@ -134,53 +143,49 @@ func (curve p256Curve) Inverse(k *big.Int) *big.Int {
// multiplication of x and y in the calculates (x × y × R^-1) mod n. RR
// is R×R mod n thus the Montgomery multiplication x and RR gives x×R,
// i.e. converts x into the Montgomery domain.
+ // Window values borrowed from https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion
RR := []uint64{0x83244c95be79eea2, 0x4699799c49bd6fa6, 0x2845b2392b6bec59, 0x66e12d94f3d95620}
- p256OrdMul(table[:4], x, RR)
-
- // Prepare the table, no need in constant time access, because the
- // power is not a secret. (Entry 0 is never used.)
- for i := 2; i < 16; i += 2 {
- p256OrdSqr(table[4*(i-1):], table[4*((i/2)-1):], 1)
- p256OrdMul(table[4*i:], table[4*(i-1):], table[:4])
- }
-
- x[0] = table[4*14+0] // f
- x[1] = table[4*14+1]
- x[2] = table[4*14+2]
- x[3] = table[4*14+3]
-
- p256OrdSqr(x, x, 4)
- p256OrdMul(x, x, table[4*14:4*14+4]) // ff
- t := make([]uint64, 4, 4)
- t[0] = x[0]
- t[1] = x[1]
- t[2] = x[2]
- t[3] = x[3]
-
- p256OrdSqr(x, x, 8)
- p256OrdMul(x, x, t) // ffff
- t[0] = x[0]
- t[1] = x[1]
- t[2] = x[2]
- t[3] = x[3]
-
- p256OrdSqr(x, x, 16)
- p256OrdMul(x, x, t) // ffffffff
- t[0] = x[0]
- t[1] = x[1]
- t[2] = x[2]
- t[3] = x[3]
-
- p256OrdSqr(x, x, 64) // ffffffff0000000000000000
- p256OrdMul(x, x, t) // ffffffff00000000ffffffff
- p256OrdSqr(x, x, 32) // ffffffff00000000ffffffff00000000
- p256OrdMul(x, x, t) // ffffffff00000000ffffffffffffffff
-
- // Remaining 32 windows
- expLo := [32]byte{0xb, 0xc, 0xe, 0x6, 0xf, 0xa, 0xa, 0xd, 0xa, 0x7, 0x1, 0x7, 0x9, 0xe, 0x8, 0x4, 0xf, 0x3, 0xb, 0x9, 0xc, 0xa, 0xc, 0x2, 0xf, 0xc, 0x6, 0x3, 0x2, 0x5, 0x4, 0xf}
- for i := 0; i < 32; i++ {
- p256OrdSqr(x, x, 4)
- p256OrdMul(x, x, table[4*(expLo[i]-1):])
+ p256OrdMul(_1, x, RR) // _1
+ p256OrdSqr(x, _1, 1) // _10
+ p256OrdMul(_11, x, _1) // _11
+ p256OrdMul(_101, x, _11) // _101
+ p256OrdMul(_111, x, _101) // _111
+ p256OrdSqr(x, _101, 1) // _1010
+ p256OrdMul(_1111, _101, x) // _1111
+
+ p256OrdSqr(t, x, 1) // _10100
+ p256OrdMul(_10101, t, _1) // _10101
+ p256OrdSqr(x, _10101, 1) // _101010
+ p256OrdMul(_101111, _101, x) // _101111
+ p256OrdMul(x, _10101, x) // _111111 = x6
+ p256OrdSqr(t, x, 2) // _11111100
+ p256OrdMul(t, t, _11) // _11111111 = x8
+ p256OrdSqr(x, t, 8) // _ff00
+ p256OrdMul(x, x, t) // _ffff = x16
+ p256OrdSqr(t, x, 16) // _ffff0000
+ p256OrdMul(t, t, x) // _ffffffff = x32
+
+ p256OrdSqr(x, t, 64)
+ p256OrdMul(x, x, t)
+ p256OrdSqr(x, x, 32)
+ p256OrdMul(x, x, t)
+
+ sqrs := []uint8{
+ 6, 5, 4, 5, 5,
+ 4, 3, 3, 5, 9,
+ 6, 2, 5, 6, 5,
+ 4, 5, 5, 3, 10,
+ 2, 5, 5, 3, 7, 6}
+ muls := [][]uint64{
+ _101111, _111, _11, _1111, _10101,
+ _101, _101, _101, _111, _101111,
+ _1111, _1, _1, _1111, _111,
+ _111, _111, _101, _11, _101111,
+ _11, _11, _11, _1, _10101, _1111}
+
+ for i, s := range sqrs {
+ p256OrdSqr(x, x, int(s))
+ p256OrdMul(x, x, muls[i])
}
// Multiplying by one in the Montgomery domain converts a Montgomery
@@ -310,7 +315,7 @@ func (p *p256Point) p256PointToAffine() (x, y *big.Int) {
zInv := make([]uint64, 4)
zInvSq := make([]uint64, 4)
p256Inverse(zInv, p.xyz[8:12])
- p256Sqr(zInvSq, zInv)
+ p256Sqr(zInvSq, zInv, 1)
p256Mul(zInv, zInv, zInvSq)
p256Mul(zInvSq, p.xyz[0:4], zInvSq)
@@ -347,71 +352,43 @@ func p256Inverse(out, in []uint64) {
p16 := stack[4*3 : 4*3+4]
p32 := stack[4*4 : 4*4+4]
- p256Sqr(out, in)
+ p256Sqr(out, in, 1)
p256Mul(p2, out, in) // 3*p
- p256Sqr(out, p2)
- p256Sqr(out, out)
+ p256Sqr(out, p2, 2)
p256Mul(p4, out, p2) // f*p
- p256Sqr(out, p4)
- p256Sqr(out, out)
- p256Sqr(out, out)
- p256Sqr(out, out)
+ p256Sqr(out, p4, 4)
p256Mul(p8, out, p4) // ff*p
- p256Sqr(out, p8)
-
- for i := 0; i < 7; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, p8, 8)
p256Mul(p16, out, p8) // ffff*p
- p256Sqr(out, p16)
- for i := 0; i < 15; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, p16, 16)
p256Mul(p32, out, p16) // ffffffff*p
- p256Sqr(out, p32)
-
- for i := 0; i < 31; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, p32, 32)
p256Mul(out, out, in)
- for i := 0; i < 32*4; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, out, 128)
p256Mul(out, out, p32)
- for i := 0; i < 32; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, out, 32)
p256Mul(out, out, p32)
- for i := 0; i < 16; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, out, 16)
p256Mul(out, out, p16)
- for i := 0; i < 8; i++ {
- p256Sqr(out, out)
- }
+ p256Sqr(out, out, 8)
p256Mul(out, out, p8)
- p256Sqr(out, out)
- p256Sqr(out, out)
- p256Sqr(out, out)
- p256Sqr(out, out)
+ p256Sqr(out, out, 4)
p256Mul(out, out, p4)
- p256Sqr(out, out)
- p256Sqr(out, out)
+ p256Sqr(out, out, 2)
p256Mul(out, out, p2)
- p256Sqr(out, out)
- p256Sqr(out, out)
+ p256Sqr(out, out, 2)
p256Mul(out, out, in)
}
@@ -427,16 +404,16 @@ func boothW5(in uint) (int, int) {
return int(d), int(s & 1)
}
-func boothW7(in uint) (int, int) {
- var s uint = ^((in >> 7) - 1)
- var d uint = (1 << 8) - in - 1
+func boothW6(in uint) (int, int) {
+ var s uint = ^((in >> 6) - 1)
+ var d uint = (1 << 7) - in - 1
d = (d & s) | (in & (^s))
d = (d >> 1) + (d & 1)
return int(d), int(s & 1)
}
func initTable() {
- p256Precomputed = new([37][64 * 8]uint64)
+ p256Precomputed = new([43][32 * 8]uint64)
basePoint := []uint64{
0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
@@ -449,19 +426,19 @@ func initTable() {
zInv := make([]uint64, 4)
zInvSq := make([]uint64, 4)
- for j := 0; j < 64; j++ {
+ for j := 0; j < 32; j++ {
copy(t1, t2)
- for i := 0; i < 37; i++ {
- // The window size is 7 so we need to double 7 times.
+ for i := 0; i < 43; i++ {
+ // The window size is 6 so we need to double 6 times.
if i != 0 {
- for k := 0; k < 7; k++ {
+ for k := 0; k < 6; k++ {
p256PointDoubleAsm(t1, t1)
}
}
// Convert the point to affine form. (Its values are
// still in Montgomery form however.)
p256Inverse(zInv, t1[8:12])
- p256Sqr(zInvSq, zInv)
+ p256Sqr(zInvSq, zInv, 1)
p256Mul(zInv, zInv, zInvSq)
p256Mul(t1[:4], t1[:4], zInvSq)
@@ -482,8 +459,8 @@ func initTable() {
func (p *p256Point) p256BaseMult(scalar []uint64) {
precomputeOnce.Do(initTable)
- wvalue := (scalar[0] << 1) & 0xff
- sel, sign := boothW7(uint(wvalue))
+ wvalue := (scalar[0] << 1) & 0x7f
+ sel, sign := boothW6(uint(wvalue))
p256SelectBase(p.xyz[0:8], p256Precomputed[0][0:], sel)
p256NegCond(p.xyz[4:8], sign)
@@ -500,17 +477,17 @@ func (p *p256Point) p256BaseMult(scalar []uint64) {
t0.xyz[10] = 0xffffffffffffffff
t0.xyz[11] = 0x00000000fffffffe
- index := uint(6)
+ index := uint(5)
zero := sel
- for i := 1; i < 37; i++ {
+ for i := 1; i < 43; i++ {
if index < 192 {
- wvalue = ((scalar[index/64] >> (index % 64)) + (scalar[index/64+1] << (64 - (index % 64)))) & 0xff
+ wvalue = ((scalar[index/64] >> (index % 64)) + (scalar[index/64+1] << (64 - (index % 64)))) & 0x7f
} else {
- wvalue = (scalar[index/64] >> (index % 64)) & 0xff
+ wvalue = (scalar[index/64] >> (index % 64)) & 0x7f
}
- index += 7
- sel, sign = boothW7(uint(wvalue))
+ index += 6
+ sel, sign = boothW6(uint(wvalue))
p256SelectBase(t0.xyz[0:8], p256Precomputed[i][0:], sel)
p256PointAddAffineAsm(p.xyz[0:12], p.xyz[0:12], t0.xyz[0:8], sign, sel, zero)
zero |= sel
diff --git a/libgo/go/crypto/elliptic/p256_generic.go b/libgo/go/crypto/elliptic/p256_generic.go
index 49445c3..48954a2 100644
--- a/libgo/go/crypto/elliptic/p256_generic.go
+++ b/libgo/go/crypto/elliptic/p256_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,!s390x
+// -build !amd64,!s390x,!arm64
package elliptic
diff --git a/libgo/go/crypto/hmac/hmac.go b/libgo/go/crypto/hmac/hmac.go
index 3c8e727..c8c0617 100644
--- a/libgo/go/crypto/hmac/hmac.go
+++ b/libgo/go/crypto/hmac/hmac.go
@@ -27,7 +27,7 @@ import (
)
// FIPS 198-1:
-// http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf
+// https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf
// key is zero padded to the block size of the hash function
// ipad = 0x36 byte repeated for key length
diff --git a/libgo/go/crypto/hmac/hmac_test.go b/libgo/go/crypto/hmac/hmac_test.go
index aac9aa9..eea345e 100644
--- a/libgo/go/crypto/hmac/hmac_test.go
+++ b/libgo/go/crypto/hmac/hmac_test.go
@@ -25,7 +25,7 @@ type hmacTest struct {
var hmacTests = []hmacTest{
// Tests from US FIPS 198
- // http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
+ // https://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
{
sha1.New,
[]byte{
@@ -205,7 +205,7 @@ var hmacTests = []hmacTest{
sha256.BlockSize,
},
- // Tests from http://csrc.nist.gov/groups/ST/toolkit/examples.html
+ // Tests from https://csrc.nist.gov/groups/ST/toolkit/examples.html
// (truncated tag tests are left out)
{
sha1.New,
diff --git a/libgo/go/crypto/internal/cipherhw/cipherhw_amd64.go b/libgo/go/crypto/internal/cipherhw/cipherhw_amd64.go
deleted file mode 100644
index be0d490..0000000
--- a/libgo/go/crypto/internal/cipherhw/cipherhw_amd64.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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,!gccgo,!appengine
-
-package cipherhw
-
-// defined in asm_amd64.s
-func hasAESNI() bool
-
-// AESGCMSupport returns true if the Go standard library supports AES-GCM in
-// hardware.
-func AESGCMSupport() bool {
- return hasAESNI()
-}
diff --git a/libgo/go/crypto/internal/cipherhw/cipherhw_s390x.go b/libgo/go/crypto/internal/cipherhw/cipherhw_s390x.go
deleted file mode 100644
index 9cd7679..0000000
--- a/libgo/go/crypto/internal/cipherhw/cipherhw_s390x.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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,!gccgo,!appengine
-
-package cipherhw
-
-// hasHWSupport reports whether the AES-128, AES-192 and AES-256 cipher message
-// (KM) function codes are supported. Note that this function is expensive.
-// defined in asm_s390x.s
-func hasHWSupport() bool
-
-var hwSupport = hasHWSupport()
-
-func AESGCMSupport() bool {
- return hwSupport
-}
diff --git a/libgo/go/crypto/internal/cipherhw/doc.go b/libgo/go/crypto/internal/cipherhw/doc.go
deleted file mode 100644
index a75fcf6..0000000
--- a/libgo/go/crypto/internal/cipherhw/doc.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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 cipherhw exposes common functions for detecting whether hardware
-// support for certain ciphers and authenticators is present.
-package cipherhw
diff --git a/libgo/go/crypto/internal/cipherhw/generic.go b/libgo/go/crypto/internal/cipherhw/generic.go
deleted file mode 100644
index 64d90d3..0000000
--- a/libgo/go/crypto/internal/cipherhw/generic.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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 gccgo appengine
-
-package cipherhw
-
-func AESGCMSupport() bool {
- return false
-}
diff --git a/libgo/go/crypto/internal/randutil/randutil.go b/libgo/go/crypto/internal/randutil/randutil.go
new file mode 100644
index 0000000..84b1295
--- /dev/null
+++ b/libgo/go/crypto/internal/randutil/randutil.go
@@ -0,0 +1,38 @@
+// Copyright 2018 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 randutil contains internal randomness utilities for various
+// crypto packages.
+package randutil
+
+import (
+ "io"
+ "sync"
+)
+
+var (
+ closedChanOnce sync.Once
+ closedChan chan struct{}
+)
+
+// MaybeReadByte reads a single byte from r with ~50% probability. This is used
+// to ensure that callers do not depend on non-guaranteed behaviour, e.g.
+// assuming that rsa.GenerateKey is deterministic w.r.t. a given random stream.
+//
+// This does not affect tests that pass a stream of fixed bytes as the random
+// source (e.g. a zeroReader).
+func MaybeReadByte(r io.Reader) {
+ closedChanOnce.Do(func() {
+ closedChan = make(chan struct{})
+ close(closedChan)
+ })
+
+ select {
+ case <-closedChan:
+ return
+ case <-closedChan:
+ var buf [1]byte
+ r.Read(buf[:])
+ }
+}
diff --git a/libgo/go/crypto/internal/subtle/aliasing.go b/libgo/go/crypto/internal/subtle/aliasing.go
new file mode 100644
index 0000000..812ce3c
--- /dev/null
+++ b/libgo/go/crypto/internal/subtle/aliasing.go
@@ -0,0 +1,34 @@
+// Copyright 2018 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 !appengine
+
+// Package subtle implements functions that are often useful in cryptographic
+// code but require careful thought to use correctly.
+//
+// This is a mirror of golang.org/x/crypto/internal/subtle.
+package subtle // import "crypto/internal/subtle"
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/libgo/go/crypto/internal/subtle/aliasing_appengine.go b/libgo/go/crypto/internal/subtle/aliasing_appengine.go
new file mode 100644
index 0000000..844f901
--- /dev/null
+++ b/libgo/go/crypto/internal/subtle/aliasing_appengine.go
@@ -0,0 +1,37 @@
+// Copyright 2018 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 appengine
+
+// Package subtle implements functions that are often useful in cryptographic
+// code but require careful thought to use correctly.
+//
+// This is a mirror of golang.org/x/crypto/internal/subtle.
+package subtle // import "crypto/internal/subtle"
+
+// This is the Google App Engine standard variant based on reflect
+// because the unsafe package and cgo are disallowed.
+
+import "reflect"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
+ reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/libgo/go/crypto/internal/subtle/aliasing_test.go b/libgo/go/crypto/internal/subtle/aliasing_test.go
new file mode 100644
index 0000000..f1e7238
--- /dev/null
+++ b/libgo/go/crypto/internal/subtle/aliasing_test.go
@@ -0,0 +1,50 @@
+// Copyright 2018 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 subtle_test
+
+import (
+ "testing"
+
+ "crypto/internal/subtle"
+)
+
+var a, b [100]byte
+
+var aliasingTests = []struct {
+ x, y []byte
+ anyOverlap, inexactOverlap bool
+}{
+ {a[:], b[:], false, false},
+ {a[:], b[:0], false, false},
+ {a[:], b[:50], false, false},
+ {a[40:50], a[50:60], false, false},
+ {a[40:50], a[60:70], false, false},
+ {a[:51], a[50:], true, true},
+ {a[:], a[:], true, false},
+ {a[:50], a[:60], true, false},
+ {a[:], nil, false, false},
+ {nil, nil, false, false},
+ {a[:], a[:0], false, false},
+ {a[:10], a[:10:20], true, false},
+ {a[:10], a[5:10:20], true, true},
+}
+
+func testAliasing(t *testing.T, i int, x, y []byte, anyOverlap, inexactOverlap bool) {
+ any := subtle.AnyOverlap(x, y)
+ if any != anyOverlap {
+ t.Errorf("%d: wrong AnyOverlap result, expected %v, got %v", i, anyOverlap, any)
+ }
+ inexact := subtle.InexactOverlap(x, y)
+ if inexact != inexactOverlap {
+ t.Errorf("%d: wrong InexactOverlap result, expected %v, got %v", i, inexactOverlap, any)
+ }
+}
+
+func TestAliasing(t *testing.T) {
+ for i, tt := range aliasingTests {
+ testAliasing(t, i, tt.x, tt.y, tt.anyOverlap, tt.inexactOverlap)
+ testAliasing(t, i, tt.y, tt.x, tt.anyOverlap, tt.inexactOverlap)
+ }
+}
diff --git a/libgo/go/crypto/md5/gen.go b/libgo/go/crypto/md5/gen.go
index 178fad1..a815dc2 100644
--- a/libgo/go/crypto/md5/gen.go
+++ b/libgo/go/crypto/md5/gen.go
@@ -179,8 +179,7 @@ var program = `// 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.
-// DO NOT EDIT.
-// Generate with: go run gen.go{{if .Full}} -full{{end}} -output md5block.go
+// Code generated by go run gen.go{{if .Full}} -full{{end}} -output md5block.go; DO NOT EDIT.
package md5
diff --git a/libgo/go/crypto/md5/md5.go b/libgo/go/crypto/md5/md5.go
index 7aeee60..88d914d 100644
--- a/libgo/go/crypto/md5/md5.go
+++ b/libgo/go/crypto/md5/md5.go
@@ -64,7 +64,7 @@ func (d *digest) MarshalBinary() ([]byte, error) {
b = appendUint32(b, d.s[2])
b = appendUint32(b, d.s[3])
b = append(b, d.x[:d.nx]...)
- b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+ b = b[:len(b)+len(d.x)-d.nx] // already zero
b = appendUint64(b, d.len)
return b, nil
}
@@ -160,10 +160,10 @@ func (d *digest) Write(p []byte) (nn int, err error) {
return
}
-func (d0 *digest) Sum(in []byte) []byte {
- // Make a copy of d0 so that caller can keep writing and summing.
- d := *d0
- hash := d.checkSum()
+func (d *digest) Sum(in []byte) []byte {
+ // Make a copy of d so that caller can keep writing and summing.
+ d0 := *d
+ hash := d0.checkSum()
return append(in, hash[:]...)
}
diff --git a/libgo/go/crypto/md5/md5block.go b/libgo/go/crypto/md5/md5block.go
index 64e1e7c..8ac32ff 100644
--- a/libgo/go/crypto/md5/md5block.go
+++ b/libgo/go/crypto/md5/md5block.go
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// DO NOT EDIT.
-// Generate with: go run gen.go -full -output md5block.go
+// Code generated by go run gen.go -full -output md5block.go; DO NOT EDIT.
package md5
diff --git a/libgo/go/crypto/md5/md5block_decl.go b/libgo/go/crypto/md5/md5block_decl.go
index 4de38cf..5f9d7ab 100644
--- a/libgo/go/crypto/md5/md5block_decl.go
+++ b/libgo/go/crypto/md5/md5block_decl.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build ignore
-// -build amd64 amd64p32 386 arm ppc64le s390x
+// -build amd64 amd64p32 386 arm ppc64le s390x arm64
package md5
diff --git a/libgo/go/crypto/md5/md5block_generic.go b/libgo/go/crypto/md5/md5block_generic.go
index c23d02b..c580bc6 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,!ppc64le,!s390x
+// -build !amd64,!amd64p32,!386,!arm,!ppc64le,!s390x,!arm64
package md5
diff --git a/libgo/go/crypto/rand/rand.go b/libgo/go/crypto/rand/rand.go
index 6f7523d..b8df8a3 100644
--- a/libgo/go/crypto/rand/rand.go
+++ b/libgo/go/crypto/rand/rand.go
@@ -3,18 +3,19 @@
// license that can be found in the LICENSE file.
// Package rand implements a cryptographically secure
-// pseudorandom number generator.
+// random number generator.
package rand
import "io"
// Reader is a global, shared instance of a cryptographically
-// strong pseudo-random generator.
+// secure random number generator.
//
// 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.
+// On Wasm, Reader uses the Web Crypto API.
var Reader io.Reader
// Read is a helper function that calls Reader.Read using io.ReadFull.
diff --git a/libgo/go/crypto/rand/rand_js.go b/libgo/go/crypto/rand/rand_js.go
new file mode 100644
index 0000000..bb21396
--- /dev/null
+++ b/libgo/go/crypto/rand/rand_js.go
@@ -0,0 +1,27 @@
+// Copyright 2018 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 js,wasm
+
+package rand
+
+import "syscall/js"
+
+func init() {
+ Reader = &reader{}
+}
+
+var jsCrypto = js.Global().Get("crypto")
+
+// reader implements a pseudorandom generator
+// using JavaScript crypto.getRandomValues method.
+// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues.
+type reader struct{}
+
+func (r *reader) Read(b []byte) (int, error) {
+ a := js.TypedArrayOf(b)
+ jsCrypto.Call("getRandomValues", a)
+ a.Release()
+ return len(b), nil
+}
diff --git a/libgo/go/crypto/rc4/rc4.go b/libgo/go/crypto/rc4/rc4.go
index 8274325..c445bb0 100644
--- a/libgo/go/crypto/rc4/rc4.go
+++ b/libgo/go/crypto/rc4/rc4.go
@@ -9,7 +9,10 @@
// applications.
package rc4
-import "strconv"
+import (
+ "crypto/internal/subtle"
+ "strconv"
+)
// A Cipher is an instance of RC4 using a particular key.
type Cipher struct {
@@ -57,12 +60,22 @@ func (c *Cipher) Reset() {
// This is the pure Go version. rc4_{amd64,386,arm}* contain assembly
// implementations. This is here for tests and to prevent bitrot.
func (c *Cipher) xorKeyStreamGeneric(dst, src []byte) {
+ if len(src) == 0 {
+ return
+ }
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/rc4: invalid buffer overlap")
+ }
i, j := c.i, c.j
+ _ = dst[len(src)-1]
+ dst = dst[:len(src)] // eliminate bounds check from loop
for k, v := range src {
i += 1
- j += uint8(c.s[i])
- c.s[i], c.s[j] = c.s[j], c.s[i]
- dst[k] = v ^ uint8(c.s[uint8(c.s[i]+c.s[j])])
+ x := c.s[i]
+ j += uint8(x)
+ y := c.s[j]
+ c.s[i], c.s[j] = y, x
+ dst[k] = v ^ uint8(c.s[uint8(x+y)])
}
c.i, c.j = i, j
}
diff --git a/libgo/go/crypto/rc4/rc4_asm.go b/libgo/go/crypto/rc4/rc4_asm.go
index aea1939..ce2162d 100644
--- a/libgo/go/crypto/rc4/rc4_asm.go
+++ b/libgo/go/crypto/rc4/rc4_asm.go
@@ -8,6 +8,8 @@
package rc4
+import "crypto/internal/subtle"
+
func xorKeyStream(dst, src *byte, n int, state *[256]uint32, i, j *uint8)
// XORKeyStream sets dst to the result of XORing src with the key stream.
@@ -16,7 +18,11 @@ func (c *Cipher) XORKeyStream(dst, src []byte) {
if len(src) == 0 {
return
}
- // Assert len(dst) >= len(src)
- _ = dst[len(src)-1]
+ if len(dst) < len(src) {
+ panic("crypto/cipher: output smaller than input")
+ }
+ if subtle.InexactOverlap(dst[:len(src)], src) {
+ panic("crypto/cipher: invalid buffer overlap")
+ }
xorKeyStream(&dst[0], &src[0], len(src), &c.s, &c.i, &c.j)
}
diff --git a/libgo/go/crypto/rc4/rc4_test.go b/libgo/go/crypto/rc4/rc4_test.go
index af79882..1fc08b8 100644
--- a/libgo/go/crypto/rc4/rc4_test.go
+++ b/libgo/go/crypto/rc4/rc4_test.go
@@ -16,7 +16,7 @@ type rc4Test struct {
var golden = []rc4Test{
// Test vectors from the original cypherpunk posting of ARC4:
- // http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0?pli=1
+ // https://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0?pli=1
{
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
[]byte{0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79},
@@ -30,7 +30,7 @@ var golden = []rc4Test{
[]byte{0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, 0xbd, 0x61},
},
- // Test vectors from the Wikipedia page: http://en.wikipedia.org/wiki/RC4
+ // Test vectors from the Wikipedia page: https://en.wikipedia.org/wiki/RC4
{
[]byte{0x4b, 0x65, 0x79},
[]byte{0xeb, 0x9f, 0x77, 0x81, 0xb7, 0x34, 0xca, 0x72, 0xa7, 0x19},
diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go
index 3517a8c..37790ac 100644
--- a/libgo/go/crypto/rsa/pkcs1v15.go
+++ b/libgo/go/crypto/rsa/pkcs1v15.go
@@ -10,6 +10,8 @@ import (
"errors"
"io"
"math/big"
+
+ "crypto/internal/randutil"
)
// This file implements encryption and decryption using PKCS#1 v1.5 padding.
@@ -35,10 +37,12 @@ type PKCS1v15DecryptOptions struct {
// 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) {
+ randutil.MaybeReadByte(rand)
+
if err := checkPub(pub); err != nil {
return nil, err
}
- k := (pub.N.BitLen() + 7) / 8
+ k := pub.Size()
if len(msg) > k-11 {
return nil, ErrMessageTooLong
}
@@ -106,7 +110,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by
if err := checkPub(&priv.PublicKey); err != nil {
return err
}
- k := (priv.N.BitLen() + 7) / 8
+ k := priv.Size()
if k-(len(key)+3+8) < 0 {
return ErrDecryption
}
@@ -134,7 +138,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by
// in order to maintain constant memory access patterns. If the plaintext was
// valid then index contains the index of the original message in em.
func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
- k := (priv.N.BitLen() + 7) / 8
+ k := priv.Size()
if k < 11 {
err = ErrDecryption
return
@@ -232,7 +236,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
}
tLen := len(prefix) + hashLen
- k := (priv.N.BitLen() + 7) / 8
+ k := priv.Size()
if k < tLen+11 {
return nil, ErrMessageTooLong
}
@@ -268,7 +272,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte)
}
tLen := len(prefix) + hashLen
- k := (pub.N.BitLen() + 7) / 8
+ k := pub.Size()
if k < tLen+11 {
return ErrVerification
}
diff --git a/libgo/go/crypto/rsa/pss.go b/libgo/go/crypto/rsa/pss.go
index 75558a9..3ff0c2f 100644
--- a/libgo/go/crypto/rsa/pss.go
+++ b/libgo/go/crypto/rsa/pss.go
@@ -36,7 +36,7 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
// 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
if emLen < hLen+sLen+2 {
- return nil, errors.New("crypto/rsa: encoding error")
+ return nil, errors.New("crypto/rsa: key size too small for PSS signature")
}
em := make([]byte, emLen)
diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go
index 0faca43..ad32d3e 100644
--- a/libgo/go/crypto/rsa/rsa.go
+++ b/libgo/go/crypto/rsa/rsa.go
@@ -31,6 +31,8 @@ import (
"io"
"math"
"math/big"
+
+ "crypto/internal/randutil"
)
var bigZero = big.NewInt(0)
@@ -42,6 +44,12 @@ type PublicKey struct {
E int // public exponent
}
+// Size returns the modulus size in bytes. Raw signatures and ciphertexts
+// for or by this public key will have the same size.
+func (pub *PublicKey) Size() int {
+ return (pub.N.BitLen() + 7) / 8
+}
+
// OAEPOptions is an interface for passing options to OAEP decryption using the
// crypto.Decrypter interface.
type OAEPOptions struct {
@@ -62,7 +70,7 @@ var (
// We require pub.E to fit into a 32-bit integer so that we
// do not have different behavior depending on whether
// int is 32 or 64 bits. See also
-// http://www.imperialviolet.org/2012/03/16/rsae.html.
+// https://www.imperialviolet.org/2012/03/16/rsae.html.
func checkPub(pub *PublicKey) error {
if pub.N == nil {
return errPublicModulus
@@ -212,6 +220,8 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, 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) (*PrivateKey, error) {
+ randutil.MaybeReadByte(random)
+
priv := new(PrivateKey)
priv.E = 65537
@@ -286,18 +296,13 @@ NextSetOfPrimes:
continue NextSetOfPrimes
}
- g := new(big.Int)
priv.D = new(big.Int)
e := big.NewInt(int64(priv.E))
- g.GCD(priv.D, nil, e, totient)
+ ok := priv.D.ModInverse(e, totient)
- if g.Cmp(bigOne) == 0 {
- if priv.D.Sign() < 0 {
- priv.D.Add(priv.D, totient)
- }
+ if ok != nil {
priv.Primes = primes
priv.N = n
-
break
}
}
@@ -373,7 +378,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
return nil, err
}
hash.Reset()
- k := (pub.N.BitLen() + 7) / 8
+ k := pub.Size()
if len(msg) > k-2*hash.Size()-2 {
return nil, ErrMessageTooLong
}
@@ -421,29 +426,6 @@ var ErrDecryption = errors.New("crypto/rsa: decryption error")
// It is deliberately vague to avoid adaptive attacks.
var ErrVerification = errors.New("crypto/rsa: verification error")
-// modInverse returns ia, the inverse of a in the multiplicative group of prime
-// order n. It requires that a be a member of the group (i.e. less than n).
-func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
- g := new(big.Int)
- x := new(big.Int)
- g.GCD(x, nil, a, n)
- if g.Cmp(bigOne) != 0 {
- // In this case, a and n aren't coprime and we cannot calculate
- // the inverse. This happens because the values of n are nearly
- // prime (being the product of two primes) rather than truly
- // prime.
- return
- }
-
- if x.Cmp(bigOne) < 0 {
- // 0 is not the multiplicative inverse of any element so, if x
- // < 1, then x is negative.
- x.Add(x, n)
- }
-
- return x, true
-}
-
// Precompute performs some calculations that speed up private key operations
// in the future.
func (priv *PrivateKey) Precompute() {
@@ -489,13 +471,15 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er
var ir *big.Int
if random != nil {
+ randutil.MaybeReadByte(random)
+
// Blinding enabled. Blinding involves multiplying c by r^e.
// Then the decryption operation performs (m^e * r^e)^d mod n
// which equals mr mod n. The factor of r can then be removed
// by multiplying by the multiplicative inverse of r.
var r *big.Int
-
+ ir = new(big.Int)
for {
r, err = rand.Int(random, priv.N)
if err != nil {
@@ -504,9 +488,8 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er
if r.Cmp(bigZero) == 0 {
r = bigOne
}
- var ok bool
- ir, ok = modInverse(r, priv.N)
- if ok {
+ ok := ir.ModInverse(r, priv.N)
+ if ok != nil {
break
}
}
@@ -587,7 +570,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
- k := (priv.N.BitLen() + 7) / 8
+ k := priv.Size()
if len(ciphertext) > k ||
k < hash.Size()*2+2 {
return nil, ErrDecryption
diff --git a/libgo/go/crypto/sha1/sha1.go b/libgo/go/crypto/sha1/sha1.go
index ae4896f..db70b7d 100644
--- a/libgo/go/crypto/sha1/sha1.go
+++ b/libgo/go/crypto/sha1/sha1.go
@@ -150,10 +150,10 @@ func (d *digest) Write(p []byte) (nn int, err error) {
return
}
-func (d0 *digest) Sum(in []byte) []byte {
- // Make a copy of d0 so that caller can keep writing and summing.
- d := *d0
- hash := d.checkSum()
+func (d *digest) Sum(in []byte) []byte {
+ // Make a copy of d so that caller can keep writing and summing.
+ d0 := *d
+ hash := d0.checkSum()
return append(in, hash[:]...)
}
@@ -189,9 +189,9 @@ func (d *digest) checkSum() [Size]byte {
}
// ConstantTimeSum computes the same result of Sum() but in constant time
-func (d0 *digest) ConstantTimeSum(in []byte) []byte {
- d := *d0
- hash := d.constSum()
+func (d *digest) ConstantTimeSum(in []byte) []byte {
+ d0 := *d
+ hash := d0.constSum()
return append(in, hash[:]...)
}
diff --git a/libgo/go/crypto/sha1/sha1block_s390x.go b/libgo/go/crypto/sha1/sha1block_s390x.go
index 55a2359..64c4018 100644
--- a/libgo/go/crypto/sha1/sha1block_s390x.go
+++ b/libgo/go/crypto/sha1/sha1block_s390x.go
@@ -6,9 +6,6 @@
package sha1
-// featureCheck reports whether the CPU supports the
-// SHA-1 compute intermediate message digest (KIMD)
-// function code.
-func featureCheck() bool
+import "internal/cpu"
-var useAsm = featureCheck()
+var useAsm = cpu.S390X.HasSHA1
diff --git a/libgo/go/crypto/sha256/sha256.go b/libgo/go/crypto/sha256/sha256.go
index b8ddaf4..1389de2 100644
--- a/libgo/go/crypto/sha256/sha256.go
+++ b/libgo/go/crypto/sha256/sha256.go
@@ -104,27 +104,35 @@ func (d *digest) UnmarshalBinary(b []byte) error {
return nil
}
+func putUint32(x []byte, s uint32) {
+ _ = x[3]
+ x[0] = byte(s >> 24)
+ x[1] = byte(s >> 16)
+ x[2] = byte(s >> 8)
+ x[3] = byte(s)
+}
+
+func putUint64(x []byte, s uint64) {
+ _ = x[7]
+ x[0] = byte(s >> 56)
+ x[1] = byte(s >> 48)
+ x[2] = byte(s >> 40)
+ x[3] = byte(s >> 32)
+ x[4] = byte(s >> 24)
+ x[5] = byte(s >> 16)
+ x[6] = byte(s >> 8)
+ x[7] = byte(s)
+}
+
func appendUint64(b []byte, x uint64) []byte {
- a := [8]byte{
- byte(x >> 56),
- byte(x >> 48),
- byte(x >> 40),
- byte(x >> 32),
- byte(x >> 24),
- byte(x >> 16),
- byte(x >> 8),
- byte(x),
- }
+ var a [8]byte
+ putUint64(a[:], x)
return append(b, a[:]...)
}
func appendUint32(b []byte, x uint32) []byte {
- a := [4]byte{
- byte(x >> 24),
- byte(x >> 16),
- byte(x >> 8),
- byte(x),
- }
+ var a [4]byte
+ putUint32(a[:], x)
return append(b, a[:]...)
}
@@ -215,11 +223,11 @@ func (d *digest) Write(p []byte) (nn int, err error) {
return
}
-func (d0 *digest) Sum(in []byte) []byte {
- // Make a copy of d0 so that caller can keep writing and summing.
- d := *d0
- hash := d.checkSum()
- if d.is224 {
+func (d *digest) Sum(in []byte) []byte {
+ // Make a copy of d so that caller can keep writing and summing.
+ d0 := *d
+ hash := d0.checkSum()
+ if d0.is224 {
return append(in, hash[:Size224]...)
}
return append(in, hash[:]...)
@@ -238,26 +246,24 @@ func (d *digest) checkSum() [Size]byte {
// Length in bits.
len <<= 3
- for i := uint(0); i < 8; i++ {
- tmp[i] = byte(len >> (56 - 8*i))
- }
+ putUint64(tmp[:], len)
d.Write(tmp[0:8])
if d.nx != 0 {
panic("d.nx != 0")
}
- h := d.h[:]
- if d.is224 {
- h = d.h[:7]
- }
-
var digest [Size]byte
- for i, s := range h {
- digest[i*4] = byte(s >> 24)
- digest[i*4+1] = byte(s >> 16)
- digest[i*4+2] = byte(s >> 8)
- digest[i*4+3] = byte(s)
+
+ putUint32(digest[0:], d.h[0])
+ putUint32(digest[4:], d.h[1])
+ putUint32(digest[8:], d.h[2])
+ putUint32(digest[12:], d.h[3])
+ putUint32(digest[16:], d.h[4])
+ putUint32(digest[20:], d.h[5])
+ putUint32(digest[24:], d.h[6])
+ if !d.is224 {
+ putUint32(digest[28:], d.h[7])
}
return digest
diff --git a/libgo/go/crypto/sha256/sha256block_s390x.go b/libgo/go/crypto/sha256/sha256block_s390x.go
index 8e5f69d..4de1c83 100644
--- a/libgo/go/crypto/sha256/sha256block_s390x.go
+++ b/libgo/go/crypto/sha256/sha256block_s390x.go
@@ -6,9 +6,6 @@
package sha256
-// featureCheck reports whether the CPU supports the
-// SHA256 compute intermediate message digest (KIMD)
-// function code.
-func featureCheck() bool
+import "internal/cpu"
-var useAsm = featureCheck()
+var useAsm = cpu.S390X.HasSHA256
diff --git a/libgo/go/crypto/sha512/sha512.go b/libgo/go/crypto/sha512/sha512.go
index b199951..24fde7dc 100644
--- a/libgo/go/crypto/sha512/sha512.go
+++ b/libgo/go/crypto/sha512/sha512.go
@@ -195,17 +195,21 @@ func (d *digest) UnmarshalBinary(b []byte) error {
return nil
}
+func putUint64(x []byte, s uint64) {
+ _ = x[7]
+ x[0] = byte(s >> 56)
+ x[1] = byte(s >> 48)
+ x[2] = byte(s >> 40)
+ x[3] = byte(s >> 32)
+ x[4] = byte(s >> 24)
+ x[5] = byte(s >> 16)
+ x[6] = byte(s >> 8)
+ x[7] = byte(s)
+}
+
func appendUint64(b []byte, x uint64) []byte {
- a := [8]byte{
- byte(x >> 56),
- byte(x >> 48),
- byte(x >> 40),
- byte(x >> 32),
- byte(x >> 24),
- byte(x >> 16),
- byte(x >> 8),
- byte(x),
- }
+ var a [8]byte
+ putUint64(a[:], x)
return append(b, a[:]...)
}
@@ -282,12 +286,12 @@ func (d *digest) Write(p []byte) (nn int, err error) {
return
}
-func (d0 *digest) Sum(in []byte) []byte {
- // Make a copy of d0 so that caller can keep writing and summing.
- d := new(digest)
- *d = *d0
- hash := d.checkSum()
- switch d.function {
+func (d *digest) Sum(in []byte) []byte {
+ // Make a copy of d so that caller can keep writing and summing.
+ d0 := new(digest)
+ *d0 = *d
+ hash := d0.checkSum()
+ switch d0.function {
case crypto.SHA384:
return append(in, hash[:Size384]...)
case crypto.SHA512_224:
@@ -312,30 +316,24 @@ func (d *digest) checkSum() [Size]byte {
// Length in bits.
len <<= 3
- for i := uint(0); i < 16; i++ {
- tmp[i] = byte(len >> (120 - 8*i))
- }
+ putUint64(tmp[0:], 0) // upper 64 bits are always zero, because len variable has type uint64
+ putUint64(tmp[8:], len)
d.Write(tmp[0:16])
if d.nx != 0 {
panic("d.nx != 0")
}
- h := d.h[:]
- if d.function == crypto.SHA384 {
- h = d.h[:6]
- }
-
var digest [Size]byte
- for i, s := range h {
- digest[i*8] = byte(s >> 56)
- digest[i*8+1] = byte(s >> 48)
- digest[i*8+2] = byte(s >> 40)
- digest[i*8+3] = byte(s >> 32)
- digest[i*8+4] = byte(s >> 24)
- digest[i*8+5] = byte(s >> 16)
- digest[i*8+6] = byte(s >> 8)
- digest[i*8+7] = byte(s)
+ putUint64(digest[0:], d.h[0])
+ putUint64(digest[8:], d.h[1])
+ putUint64(digest[16:], d.h[2])
+ putUint64(digest[24:], d.h[3])
+ putUint64(digest[32:], d.h[4])
+ putUint64(digest[40:], d.h[5])
+ if d.function != crypto.SHA384 {
+ putUint64(digest[48:], d.h[6])
+ putUint64(digest[56:], d.h[7])
}
return digest
diff --git a/libgo/go/crypto/sha512/sha512block_s390x.go b/libgo/go/crypto/sha512/sha512block_s390x.go
index 26896fc..f8ab231 100644
--- a/libgo/go/crypto/sha512/sha512block_s390x.go
+++ b/libgo/go/crypto/sha512/sha512block_s390x.go
@@ -6,9 +6,6 @@
package sha512
-// featureCheck reports whether the CPU supports the
-// SHA512 compute intermediate message digest (KIMD)
-// function code.
-func featureCheck() bool
+import "internal/cpu"
-var useAsm = featureCheck()
+var useAsm = cpu.S390X.HasSHA512
diff --git a/libgo/go/crypto/tls/auth.go b/libgo/go/crypto/tls/auth.go
new file mode 100644
index 0000000..88face4c
--- /dev/null
+++ b/libgo/go/crypto/tls/auth.go
@@ -0,0 +1,108 @@
+// Copyright 2017 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 tls
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/rsa"
+ "encoding/asn1"
+ "errors"
+ "fmt"
+)
+
+// pickSignatureAlgorithm selects a signature algorithm that is compatible with
+// the given public key and the list of algorithms from the peer and this side.
+// The lists of signature algorithms (peerSigAlgs and ourSigAlgs) are ignored
+// for tlsVersion < VersionTLS12.
+//
+// The returned SignatureScheme codepoint is only meaningful for TLS 1.2,
+// previous TLS versions have a fixed hash function.
+func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []SignatureScheme, tlsVersion uint16) (sigAlg SignatureScheme, sigType uint8, hashFunc crypto.Hash, err error) {
+ if tlsVersion < VersionTLS12 || len(peerSigAlgs) == 0 {
+ // For TLS 1.1 and before, the signature algorithm could not be
+ // negotiated and the hash is fixed based on the signature type.
+ // For TLS 1.2, if the client didn't send signature_algorithms
+ // extension then we can assume that it supports SHA1. See
+ // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+ switch pubkey.(type) {
+ case *rsa.PublicKey:
+ if tlsVersion < VersionTLS12 {
+ return 0, signaturePKCS1v15, crypto.MD5SHA1, nil
+ } else {
+ return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil
+ }
+ case *ecdsa.PublicKey:
+ return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
+ default:
+ return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
+ }
+ }
+ for _, sigAlg := range peerSigAlgs {
+ if !isSupportedSignatureAlgorithm(sigAlg, ourSigAlgs) {
+ continue
+ }
+ hashAlg, err := lookupTLSHash(sigAlg)
+ if err != nil {
+ panic("tls: supported signature algorithm has an unknown hash function")
+ }
+ sigType := signatureFromSignatureScheme(sigAlg)
+ switch pubkey.(type) {
+ case *rsa.PublicKey:
+ if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS {
+ return sigAlg, sigType, hashAlg, nil
+ }
+ case *ecdsa.PublicKey:
+ if sigType == signatureECDSA {
+ return sigAlg, sigType, hashAlg, nil
+ }
+ default:
+ return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
+ }
+ }
+ return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms")
+}
+
+// verifyHandshakeSignature verifies a signature against pre-hashed handshake
+// contents.
+func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, digest, sig []byte) error {
+ switch sigType {
+ case signatureECDSA:
+ pubKey, ok := pubkey.(*ecdsa.PublicKey)
+ if !ok {
+ return errors.New("tls: ECDSA signing requires a ECDSA 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("tls: ECDSA signature contained zero or negative values")
+ }
+ if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
+ return errors.New("tls: ECDSA verification failure")
+ }
+ case signaturePKCS1v15:
+ pubKey, ok := pubkey.(*rsa.PublicKey)
+ if !ok {
+ return errors.New("tls: RSA signing requires a RSA public key")
+ }
+ if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
+ return err
+ }
+ case signatureRSAPSS:
+ pubKey, ok := pubkey.(*rsa.PublicKey)
+ if !ok {
+ return errors.New("tls: RSA signing requires a RSA public key")
+ }
+ signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
+ if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil {
+ return err
+ }
+ default:
+ return errors.New("tls: unknown signature algorithm")
+ }
+ return nil
+}
diff --git a/libgo/go/crypto/tls/auth_test.go b/libgo/go/crypto/tls/auth_test.go
new file mode 100644
index 0000000..3f876b9
--- /dev/null
+++ b/libgo/go/crypto/tls/auth_test.go
@@ -0,0 +1,101 @@
+// Copyright 2017 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 tls
+
+import (
+ "crypto"
+ "testing"
+)
+
+func TestSignatureSelection(t *testing.T) {
+ rsaCert := &testRSAPrivateKey.PublicKey
+ ecdsaCert := &testECDSAPrivateKey.PublicKey
+ sigsPKCS1WithSHA := []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1}
+ sigsPSSWithSHA := []SignatureScheme{PSSWithSHA256, PSSWithSHA384}
+ sigsECDSAWithSHA := []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}
+
+ tests := []struct {
+ pubkey crypto.PublicKey
+ peerSigAlgs []SignatureScheme
+ ourSigAlgs []SignatureScheme
+ tlsVersion uint16
+
+ expectedSigAlg SignatureScheme // or 0 if ignored
+ expectedSigType uint8
+ expectedHash crypto.Hash
+ }{
+ // Hash is fixed for RSA in TLS 1.1 and before.
+ // https://tools.ietf.org/html/rfc4346#page-44
+ {rsaCert, nil, nil, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1},
+ {rsaCert, nil, nil, VersionTLS10, 0, signaturePKCS1v15, crypto.MD5SHA1},
+ {rsaCert, nil, nil, VersionSSL30, 0, signaturePKCS1v15, crypto.MD5SHA1},
+
+ // Before TLS 1.2, there is no signature_algorithms extension
+ // nor field in CertificateRequest and digitally-signed and thus
+ // it should be ignored.
+ {rsaCert, sigsPKCS1WithSHA, nil, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1},
+ {rsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1},
+ // Use SHA-1 for TLS 1.0 and 1.1 with ECDSA, see https://tools.ietf.org/html/rfc4492#page-20
+ {ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS11, 0, signatureECDSA, crypto.SHA1},
+ {ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS10, 0, signatureECDSA, crypto.SHA1},
+
+ // TLS 1.2 without signature_algorithms extension
+ // https://tools.ietf.org/html/rfc5246#page-47
+ {rsaCert, nil, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
+ {ecdsaCert, nil, sigsPKCS1WithSHA, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
+
+ {rsaCert, []SignatureScheme{PKCS1WithSHA1}, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
+ {rsaCert, []SignatureScheme{PKCS1WithSHA256}, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256},
+ // "sha_hash" may denote hashes other than SHA-1
+ // https://tools.ietf.org/html/draft-ietf-tls-rfc4492bis-17#page-17
+ {ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, sigsECDSAWithSHA, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
+ {ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, sigsECDSAWithSHA, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
+
+ // RSASSA-PSS is defined in TLS 1.3 for TLS 1.2
+ // https://tools.ietf.org/html/draft-ietf-tls-tls13-21#page-45
+ {rsaCert, []SignatureScheme{PSSWithSHA256}, sigsPSSWithSHA, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256},
+ }
+
+ for testNo, test := range tests {
+ sigAlg, sigType, hashFunc, err := pickSignatureAlgorithm(test.pubkey, test.peerSigAlgs, test.ourSigAlgs, test.tlsVersion)
+ if err != nil {
+ t.Errorf("test[%d]: unexpected error: %v", testNo, err)
+ }
+ if test.expectedSigAlg != 0 && test.expectedSigAlg != sigAlg {
+ t.Errorf("test[%d]: expected signature scheme %#x, got %#x", testNo, test.expectedSigAlg, sigAlg)
+ }
+ if test.expectedSigType != sigType {
+ t.Errorf("test[%d]: expected signature algorithm %#x, got %#x", testNo, test.expectedSigType, sigType)
+ }
+ if test.expectedHash != hashFunc {
+ t.Errorf("test[%d]: expected hash function %#x, got %#x", testNo, test.expectedHash, hashFunc)
+ }
+ }
+
+ badTests := []struct {
+ pubkey crypto.PublicKey
+ peerSigAlgs []SignatureScheme
+ ourSigAlgs []SignatureScheme
+ tlsVersion uint16
+ }{
+ {rsaCert, sigsECDSAWithSHA, sigsPKCS1WithSHA, VersionTLS12},
+ {ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS12},
+ {ecdsaCert, sigsECDSAWithSHA, sigsPKCS1WithSHA, VersionTLS12},
+ {rsaCert, []SignatureScheme{0}, sigsPKCS1WithSHA, VersionTLS12},
+
+ // ECDSA is unspecified for SSL 3.0 in RFC 4492.
+ // TODO a SSL 3.0 client cannot advertise signature_algorithms,
+ // but if an application feeds an ECDSA certificate anyway, it
+ // will be accepted rather than trigger a handshake failure. Ok?
+ //{ecdsaCert, nil, nil, VersionSSL30},
+ }
+
+ for testNo, test := range badTests {
+ sigAlg, sigType, hashFunc, err := pickSignatureAlgorithm(test.pubkey, test.peerSigAlgs, test.ourSigAlgs, test.tlsVersion)
+ if err == nil {
+ t.Errorf("test[%d]: unexpected success, got %#x %#x %#x", testNo, sigAlg, sigType, hashFunc)
+ }
+ }
+}
diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go
index beb0f19..3c8dc4b 100644
--- a/libgo/go/crypto/tls/cipher_suites.go
+++ b/libgo/go/crypto/tls/cipher_suites.go
@@ -333,14 +333,14 @@ func rsaKA(version uint16) keyAgreement {
func ecdheECDSAKA(version uint16) keyAgreement {
return &ecdheKeyAgreement{
- sigType: signatureECDSA,
+ isRSA: false,
version: version,
}
}
func ecdheRSAKA(version uint16) keyAgreement {
return &ecdheKeyAgreement{
- sigType: signatureRSA,
+ isRSA: true,
version: version,
}
}
@@ -364,7 +364,7 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
// 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
+// Taken from https://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
diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go
index 646b107..7b627fc 100644
--- a/libgo/go/crypto/tls/common.go
+++ b/libgo/go/crypto/tls/common.go
@@ -7,12 +7,12 @@ package tls
import (
"container/list"
"crypto"
- "crypto/internal/cipherhw"
"crypto/rand"
"crypto/sha512"
"crypto/x509"
"errors"
"fmt"
+ "internal/cpu"
"io"
"math/big"
"net"
@@ -91,7 +91,7 @@ const (
)
// CurveID is the type of a TLS identifier for an elliptic curve. See
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
type CurveID uint16
const (
@@ -102,7 +102,7 @@ const (
)
// TLS Elliptic Curve Point Formats
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
const (
pointFormatUncompressed uint8 = 0
)
@@ -127,10 +127,12 @@ const (
// Rest of these are reserved by the TLS spec
)
-// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1)
+// Signature algorithms (for internal signaling use). Starting at 16 to avoid overlap with
+// TLS 1.2 codepoints (RFC 5246, section A.4.1), with which these have nothing to do.
const (
- signatureRSA uint8 = 1
- signatureECDSA uint8 = 3
+ signaturePKCS1v15 uint8 = iota + 16
+ signatureECDSA
+ signatureRSAPSS
)
// supportedSignatureAlgorithms contains the signature and hash algorithms that
@@ -162,6 +164,9 @@ type ConnectionState struct {
SignedCertificateTimestamps [][]byte // SCTs from the server, if any
OCSPResponse []byte // stapled OCSP response from server, if any
+ // ekm is a closure exposed via ExportKeyingMaterial.
+ ekm func(label string, context []byte, length int) ([]byte, error)
+
// TLSUnique contains the "tls-unique" channel binding value (see RFC
// 5929, section 3). For resumed sessions this value will be nil
// because resumption does not include enough context (see
@@ -171,6 +176,14 @@ type ConnectionState struct {
TLSUnique []byte
}
+// ExportKeyingMaterial returns length bytes of exported key material in a new
+// slice as defined in https://tools.ietf.org/html/rfc5705. If context is nil,
+// it is not used as part of the seed. If the connection was set to allow
+// renegotiation via Config.Renegotiation, this function will return an error.
+func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
+ return cs.ekm(label, context, length)
+}
+
// ClientAuthType declares the policy the server will follow for
// TLS Client Authentication.
type ClientAuthType int
@@ -240,19 +253,19 @@ type ClientHelloInfo struct {
// ServerName indicates the name of the server requested by the client
// in order to support virtual hosting. ServerName is only set if the
// client is using SNI (see
- // http://tools.ietf.org/html/rfc4366#section-3.1).
+ // https://tools.ietf.org/html/rfc4366#section-3.1).
ServerName string
// SupportedCurves lists the elliptic curves supported by the client.
// SupportedCurves is set only if the Supported Elliptic Curves
// Extension is being used (see
- // http://tools.ietf.org/html/rfc4492#section-5.1.1).
+ // https://tools.ietf.org/html/rfc4492#section-5.1.1).
SupportedCurves []CurveID
// SupportedPoints lists the point formats supported by the client.
// SupportedPoints is set only if the Supported Point Formats Extension
// is being used (see
- // http://tools.ietf.org/html/rfc4492#section-5.1.2).
+ // https://tools.ietf.org/html/rfc4492#section-5.1.2).
SupportedPoints []uint8
// SignatureSchemes lists the signature and hash schemes that the client
@@ -453,7 +466,8 @@ type Config struct {
PreferServerCipherSuites bool
// SessionTicketsDisabled may be set to true to disable session ticket
- // (resumption) support.
+ // (resumption) support. Note that on clients, session ticket support is
+ // also disabled if ClientSessionCache is nil.
SessionTicketsDisabled bool
// SessionTicketKey is used by TLS servers to provide session
@@ -467,7 +481,7 @@ type Config struct {
SessionTicketKey [32]byte
// ClientSessionCache is a cache of ClientSessionState entries for TLS
- // session resumption.
+ // session resumption. It is only used by clients.
ClientSessionCache ClientSessionCache
// MinVersion contains the minimum SSL/TLS version that is acceptable.
@@ -911,7 +925,19 @@ func defaultCipherSuites() []uint16 {
func initDefaultCipherSuites() {
var topCipherSuites []uint16
- if cipherhw.AESGCMSupport() {
+
+ // Check the cpu flags for each platform that has optimized GCM implementations.
+ // Worst case, these variables will just all be false
+ hasGCMAsmAMD64 := cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
+
+ hasGCMAsmARM64 := cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
+
+ // Keep in sync with crypto/aes/cipher_s390x.go.
+ hasGCMAsmS390X := cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
+
+ hasGCMAsm := hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X
+
+ if hasGCMAsm {
// If AES-GCM hardware is provided then prioritise AES-GCM
// cipher suites.
topCipherSuites = []uint16{
@@ -970,7 +996,9 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg
func signatureFromSignatureScheme(signatureAlgorithm SignatureScheme) uint8 {
switch signatureAlgorithm {
case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
- return signatureRSA
+ return signaturePKCS1v15
+ case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
+ return signatureRSAPSS
case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
return signatureECDSA
default:
diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go
index 31c5053..6e27e69 100644
--- a/libgo/go/crypto/tls/conn.go
+++ b/libgo/go/crypto/tls/conn.go
@@ -27,19 +27,16 @@ type Conn struct {
conn net.Conn
isClient bool
- // constant after handshake; protected by handshakeMutex
- handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
- // handshakeCond, if not nil, indicates that a goroutine is committed
- // to running the handshake for this Conn. Other goroutines that need
- // to wait for the handshake can wait on this, under handshakeMutex.
- handshakeCond *sync.Cond
- 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 transferring
+ // handshakeStatus is 1 if the connection is currently transferring
// application data (i.e. is not currently processing a handshake).
- handshakeComplete bool
+ // This field is only to be accessed with sync/atomic.
+ handshakeStatus uint32
+ // constant after handshake; protected by handshakeMutex
+ handshakeMutex sync.Mutex
+ handshakeErr error // error resulting from handshake
+ vers uint16 // TLS version
+ haveVers bool // version has been negotiated
+ config *Config // configuration passed to constructor
// handshakes counts the number of handshakes performed on the
// connection so far. If renegotiation is disabled then this is either
// zero or one.
@@ -58,6 +55,8 @@ type Conn struct {
// renegotiation extension. (This is meaningless as a server because
// renegotiation is not supported in that case.)
secureRenegotiation bool
+ // ekm is a closure for exporting keying material.
+ ekm func(label string, context []byte, length int) ([]byte, error)
// clientFinishedIsFirst is true if the client sent the first Finished
// message during the most recent handshake. This is recorded because
@@ -82,7 +81,7 @@ type Conn struct {
clientProtocolFallback bool
// input/output
- in, out halfConn // in.Mutex < out.Mutex
+ in, out halfConn
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
@@ -564,7 +563,6 @@ func (c *Conn) newRecordHeaderError(msg string) (err RecordHeaderError) {
// readRecord reads the next TLS record from the connection
// and updates the record layer state.
-// c.in.Mutex <= L; c.input == nil.
func (c *Conn) readRecord(want recordType) error {
// Caller must be in sync with connection:
// handshake data if handshake not yet completed,
@@ -574,12 +572,12 @@ func (c *Conn) readRecord(want recordType) error {
c.sendAlert(alertInternalError)
return c.in.setErrorLocked(errors.New("tls: unknown record type requested"))
case recordTypeHandshake, recordTypeChangeCipherSpec:
- if c.handshakeComplete {
+ if c.handshakeComplete() {
c.sendAlert(alertInternalError)
return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested while not in handshake"))
}
case recordTypeApplicationData:
- if !c.handshakeComplete {
+ if !c.handshakeComplete() {
c.sendAlert(alertInternalError)
return c.in.setErrorLocked(errors.New("tls: application data record requested while in handshake"))
}
@@ -736,7 +734,6 @@ Again:
}
// sendAlert sends a TLS alert message.
-// c.out.Mutex <= L.
func (c *Conn) sendAlertLocked(err alert) error {
switch err {
case alertNoRenegotiation, alertCloseNotify:
@@ -756,7 +753,6 @@ func (c *Conn) sendAlertLocked(err alert) error {
}
// sendAlert sends a TLS alert message.
-// L < c.out.Mutex.
func (c *Conn) sendAlert(err alert) error {
c.out.Lock()
defer c.out.Unlock()
@@ -793,8 +789,6 @@ const (
//
// 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
@@ -844,7 +838,6 @@ func (c *Conn) maxPayloadSizeForWrite(typ recordType, explicitIVLen int) int {
return n
}
-// c.out.Mutex <= L.
func (c *Conn) write(data []byte) (int, error) {
if c.buffering {
c.sendBuf = append(c.sendBuf, data...)
@@ -870,7 +863,6 @@ func (c *Conn) flush() (int, error) {
// 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)
@@ -946,7 +938,6 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
// 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()
@@ -956,7 +947,6 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {
// readHandshake reads the next handshake message from
// the record layer.
-// c.in.Mutex < L; c.out.Mutex < L.
func (c *Conn) readHandshake() (interface{}, error) {
for c.hand.Len() < 4 {
if err := c.in.err; err != nil {
@@ -1059,7 +1049,7 @@ func (c *Conn) Write(b []byte) (int, error) {
return 0, err
}
- if !c.handshakeComplete {
+ if !c.handshakeComplete() {
return 0, alertInternalError
}
@@ -1072,9 +1062,9 @@ func (c *Conn) Write(b []byte) (int, error) {
// This can be prevented by splitting each Application Data
// record into two records, effectively randomizing the IV.
//
- // http://www.openssl.org/~bodo/tls-cbc.txt
+ // https://www.openssl.org/~bodo/tls-cbc.txt
// https://bugzilla.mozilla.org/show_bug.cgi?id=665814
- // http://www.imperialviolet.org/2012/01/15/beastfollowup.html
+ // https://www.imperialviolet.org/2012/01/15/beastfollowup.html
var m int
if len(b) > 1 && c.vers <= VersionTLS10 {
@@ -1092,7 +1082,6 @@ func (c *Conn) Write(b []byte) (int, error) {
}
// handleRenegotiation processes a HelloRequest handshake message.
-// c.in.Mutex <= L
func (c *Conn) handleRenegotiation() error {
msg, err := c.readHandshake()
if err != nil {
@@ -1126,7 +1115,7 @@ func (c *Conn) handleRenegotiation() error {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
- c.handshakeComplete = false
+ atomic.StoreUint32(&c.handshakeStatus, 0)
if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil {
c.handshakes++
}
@@ -1227,11 +1216,9 @@ func (c *Conn) Close() error {
var alertErr error
- c.handshakeMutex.Lock()
- if c.handshakeComplete {
+ if c.handshakeComplete() {
alertErr = c.closeNotify()
}
- c.handshakeMutex.Unlock()
if err := c.conn.Close(); err != nil {
return err
@@ -1245,9 +1232,7 @@ var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake com
// called once the handshake has completed and does not call CloseWrite on the
// underlying connection. Most callers should just use Close.
func (c *Conn) CloseWrite() error {
- c.handshakeMutex.Lock()
- defer c.handshakeMutex.Unlock()
- if !c.handshakeComplete {
+ if !c.handshakeComplete() {
return errEarlyCloseWrite
}
@@ -1270,61 +1255,19 @@ func (c *Conn) closeNotify() 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 first take c.handshakeMutex to check whether a handshake is
- // needed.
- //
- // If so then, previously, this code would unlock handshakeMutex and
- // then lock c.in and handshakeMutex in the correct order to run the
- // handshake. The problem was that it was possible for a Read to
- // complete the handshake once handshakeMutex was unlocked and then
- // keep c.in while waiting for network data. Thus a concurrent
- // operation could be blocked on c.in.
- //
- // Thus handshakeCond is used to signal that a goroutine is committed
- // to running the handshake and other goroutines can wait on it if they
- // need. handshakeCond is protected by handshakeMutex.
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
- for {
- if err := c.handshakeErr; err != nil {
- return err
- }
- if c.handshakeComplete {
- return nil
- }
- if c.handshakeCond == nil {
- break
- }
-
- c.handshakeCond.Wait()
+ if err := c.handshakeErr; err != nil {
+ return err
+ }
+ if c.handshakeComplete() {
+ return nil
}
-
- // Set handshakeCond to indicate that this goroutine is committing to
- // running the handshake.
- c.handshakeCond = sync.NewCond(&c.handshakeMutex)
- c.handshakeMutex.Unlock()
c.in.Lock()
defer c.in.Unlock()
- c.handshakeMutex.Lock()
-
- // The handshake cannot have completed when handshakeMutex was unlocked
- // because this goroutine set handshakeCond.
- if c.handshakeErr != nil || c.handshakeComplete {
- panic("handshake should not have been able to complete after handshakeCond was set")
- }
-
if c.isClient {
c.handshakeErr = c.clientHandshake()
} else {
@@ -1338,15 +1281,10 @@ func (c *Conn) Handshake() error {
c.flush()
}
- if c.handshakeErr == nil && !c.handshakeComplete {
+ if c.handshakeErr == nil && !c.handshakeComplete() {
panic("handshake should have had a result.")
}
- // Wake any other goroutines that are waiting for this handshake to
- // complete.
- c.handshakeCond.Broadcast()
- c.handshakeCond = nil
-
return c.handshakeErr
}
@@ -1356,10 +1294,10 @@ func (c *Conn) ConnectionState() ConnectionState {
defer c.handshakeMutex.Unlock()
var state ConnectionState
- state.HandshakeComplete = c.handshakeComplete
+ state.HandshakeComplete = c.handshakeComplete()
state.ServerName = c.serverName
- if c.handshakeComplete {
+ if state.HandshakeComplete {
state.Version = c.vers
state.NegotiatedProtocol = c.clientProtocol
state.DidResume = c.didResume
@@ -1376,6 +1314,11 @@ func (c *Conn) ConnectionState() ConnectionState {
state.TLSUnique = c.serverFinished[:]
}
}
+ if c.config.Renegotiation != RenegotiateNever {
+ state.ekm = noExportedKeyingMaterial
+ } else {
+ state.ekm = c.ekm
+ }
}
return state
@@ -1399,7 +1342,7 @@ func (c *Conn) VerifyHostname(host string) error {
if !c.isClient {
return errors.New("tls: VerifyHostname called on TLS server connection")
}
- if !c.handshakeComplete {
+ if !c.handshakeComplete() {
return errors.New("tls: handshake has not yet been performed")
}
if len(c.verifiedChains) == 0 {
@@ -1407,3 +1350,7 @@ func (c *Conn) VerifyHostname(host string) error {
}
return c.peerCertificates[0].VerifyHostname(host)
}
+
+func (c *Conn) handshakeComplete() bool {
+ return atomic.LoadUint32(&c.handshakeStatus) == 1
+}
diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go
index 8ee2b59..8d012be 100644
--- a/libgo/go/crypto/tls/generate_cert.go
+++ b/libgo/go/crypto/tls/generate_cert.go
@@ -146,16 +146,24 @@ func main() {
if err != nil {
log.Fatalf("failed to open cert.pem for writing: %s", err)
}
- pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
- certOut.Close()
- log.Print("written cert.pem\n")
+ if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
+ log.Fatalf("failed to write data to cert.pem: %s", err)
+ }
+ if err := certOut.Close(); err != nil {
+ log.Fatalf("error closing cert.pem: %s", err)
+ }
+ log.Print("wrote cert.pem\n")
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Print("failed to open key.pem for writing:", err)
return
}
- pem.Encode(keyOut, pemBlockForKey(priv))
- keyOut.Close()
- log.Print("written key.pem\n")
+ if err := pem.Encode(keyOut, pemBlockForKey(priv)); err != nil {
+ log.Fatalf("failed to write data to key.pem: %s", err)
+ }
+ if err := keyOut.Close(); err != nil {
+ log.Fatalf("error closing key.pem: %s", err)
+ }
+ log.Print("wrote key.pem\n")
}
diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go
index e5e0df2..32fdc6d 100644
--- a/libgo/go/crypto/tls/handshake_client.go
+++ b/libgo/go/crypto/tls/handshake_client.go
@@ -17,6 +17,7 @@ import (
"net"
"strconv"
"strings"
+ "sync/atomic"
)
type clientHandshakeState struct {
@@ -91,7 +92,6 @@ NextCipherSuite:
return hello, nil
}
-// c.out.Mutex <= L; c.handshakeMutex <= L.
func (c *Conn) clientHandshake() error {
if c.config == nil {
c.config = defaultConfig()
@@ -265,8 +265,9 @@ func (hs *clientHandshakeState) handshake() error {
}
}
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
c.didResume = isResume
- c.handshakeComplete = true
+ atomic.StoreUint32(&c.handshakeStatus, 1)
return nil
}
@@ -479,31 +480,25 @@ func (hs *clientHandshakeState) doFullHandshake() error {
return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
}
- var signatureType uint8
- switch key.Public().(type) {
- case *ecdsa.PublicKey:
- signatureType = signatureECDSA
- case *rsa.PublicKey:
- signatureType = signatureRSA
- default:
+ signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, hs.hello.supportedSignatureAlgorithms, c.vers)
+ if err != nil {
c.sendAlert(alertInternalError)
- return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
+ return err
}
-
// SignatureAndHashAlgorithm was introduced in TLS 1.2.
if certVerify.hasSignatureAndHash {
- certVerify.signatureAlgorithm, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.supportedSignatureAlgorithms, signatureType)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
+ certVerify.signatureAlgorithm = signatureAlgorithm
}
- digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(signatureType, certVerify.signatureAlgorithm, hs.masterSecret)
+ digest, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret)
if err != nil {
c.sendAlert(alertInternalError)
return err
}
- certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
+ signOpts := crypto.SignerOpts(hashFunc)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
+ }
+ certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts)
if err != nil {
c.sendAlert(alertInternalError)
return err
diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go
index cc3ab71..1f1c93d 100644
--- a/libgo/go/crypto/tls/handshake_client_test.go
+++ b/libgo/go/crypto/tls/handshake_client_test.go
@@ -979,6 +979,24 @@ func TestRenegotiateTwiceRejected(t *testing.T) {
runClientTestTLS12(t, test)
}
+func TestHandshakeClientExportKeyingMaterial(t *testing.T) {
+ test := &clientTest{
+ name: "ExportKeyingMaterial",
+ command: []string{"openssl", "s_server"},
+ config: testConfig.Clone(),
+ validate: func(state ConnectionState) error {
+ if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
+ return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
+ } else if len(km) != 42 {
+ return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
+ }
+ return nil
+ },
+ }
+ runClientTestTLS10(t, test)
+ runClientTestTLS12(t, test)
+}
+
var hostnameInSNITests = []struct {
in, out string
}{
@@ -1578,3 +1596,61 @@ func TestGetClientCertificate(t *testing.T) {
}
}
}
+
+func TestRSAPSSKeyError(t *testing.T) {
+ // crypto/tls does not support the rsa_pss_pss_xxx SignatureSchemes. If support for
+ // public keys with OID RSASSA-PSS is added to crypto/x509, they will be misused with
+ // the rsa_pss_rsae_xxx SignatureSchemes. Assert that RSASSA-PSS certificates don't
+ // parse, or that they don't carry *rsa.PublicKey keys.
+ b, _ := pem.Decode([]byte(`
+-----BEGIN CERTIFICATE-----
+MIIDZTCCAhygAwIBAgIUCF2x0FyTgZG0CC9QTDjGWkB5vgEwPgYJKoZIhvcNAQEK
+MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC
+AgDeMBIxEDAOBgNVBAMMB1JTQS1QU1MwHhcNMTgwNjI3MjI0NDM2WhcNMTgwNzI3
+MjI0NDM2WjASMRAwDgYDVQQDDAdSU0EtUFNTMIIBIDALBgkqhkiG9w0BAQoDggEP
+ADCCAQoCggEBANxDm0f76JdI06YzsjB3AmmjIYkwUEGxePlafmIASFjDZl/elD0Z
+/a7xLX468b0qGxLS5al7XCcEprSdsDR6DF5L520+pCbpfLyPOjuOvGmk9KzVX4x5
+b05YXYuXdsQ0Kjxcx2i3jjCday6scIhMJVgBZxTEyMj1thPQM14SHzKCd/m6HmCL
+QmswpH2yMAAcBRWzRpp/vdH5DeOJEB3aelq7094no731mrLUCHRiZ1htq8BDB3ou
+czwqgwspbqZ4dnMXl2MvfySQ5wJUxQwILbiuAKO2lVVPUbFXHE9pgtznNoPvKwQT
+JNcX8ee8WIZc2SEGzofjk3NpjR+2ADB2u3sCAwEAAaNTMFEwHQYDVR0OBBYEFNEz
+AdyJ2f+fU+vSCS6QzohnOnprMB8GA1UdIwQYMBaAFNEzAdyJ2f+fU+vSCS6Qzohn
+OnprMA8GA1UdEwEB/wQFMAMBAf8wPgYJKoZIhvcNAQEKMDGgDTALBglghkgBZQME
+AgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQCAgDeA4IBAQCjEdrR5aab
+sZmCwrMeKidXgfkmWvfuLDE+TCbaqDZp7BMWcMQXT9O0UoUT5kqgKj2ARm2pEW0Z
+H3Z1vj3bbds72qcDIJXp+l0fekyLGeCrX/CbgnMZXEP7+/+P416p34ChR1Wz4dU1
+KD3gdsUuTKKeMUog3plxlxQDhRQmiL25ygH1LmjLd6dtIt0GVRGr8lj3euVeprqZ
+bZ3Uq5eLfsn8oPgfC57gpO6yiN+UURRTlK3bgYvLh4VWB3XXk9UaQZ7Mq1tpXjoD
+HYFybkWzibkZp4WRo+Fa28rirH+/wHt0vfeN7UCceURZEx4JaxIIfe4ku7uDRhJi
+RwBA9Xk1KBNF
+-----END CERTIFICATE-----`))
+ if b == nil {
+ t.Fatal("Failed to decode certificate")
+ }
+ cert, err := x509.ParseCertificate(b.Bytes)
+ if err != nil {
+ return
+ }
+ if _, ok := cert.PublicKey.(*rsa.PublicKey); ok {
+ t.Error("A RSA-PSS certificate was parsed like a PKCS1 one, and it will be mistakenly used with rsa_pss_rsae_xxx signature algorithms")
+ }
+}
+
+func TestCloseClientConnectionOnIdleServer(t *testing.T) {
+ clientConn, serverConn := net.Pipe()
+ client := Client(clientConn, testConfig.Clone())
+ go func() {
+ var b [1]byte
+ serverConn.Read(b[:])
+ client.Close()
+ }()
+ client.SetWriteDeadline(time.Now().Add(time.Second))
+ err := client.Handshake()
+ if err != nil {
+ if !strings.Contains(err.Error(), "read/write on closed pipe") {
+ t.Errorf("Error expected containing 'read/write on closed pipe' but got '%s'", err.Error())
+ }
+ } else {
+ t.Errorf("Error expected, but no error returned")
+ }
+}
diff --git a/libgo/go/crypto/tls/handshake_messages.go b/libgo/go/crypto/tls/handshake_messages.go
index f8c8d57..a5bf10e 100644
--- a/libgo/go/crypto/tls/handshake_messages.go
+++ b/libgo/go/crypto/tls/handshake_messages.go
@@ -192,7 +192,7 @@ func (m *clientHelloMsg) marshal() []byte {
z = z[9:]
}
if len(m.supportedCurves) > 0 {
- // http://tools.ietf.org/html/rfc4492#section-5.5.1
+ // https://tools.ietf.org/html/rfc4492#section-5.5.1
z[0] = byte(extensionSupportedCurves >> 8)
z[1] = byte(extensionSupportedCurves)
l := 2 + 2*len(m.supportedCurves)
@@ -209,7 +209,7 @@ func (m *clientHelloMsg) marshal() []byte {
}
}
if len(m.supportedPoints) > 0 {
- // http://tools.ietf.org/html/rfc4492#section-5.5.2
+ // https://tools.ietf.org/html/rfc4492#section-5.5.2
z[0] = byte(extensionSupportedPoints >> 8)
z[1] = byte(extensionSupportedPoints)
l := 1 + len(m.supportedPoints)
@@ -224,7 +224,7 @@ func (m *clientHelloMsg) marshal() []byte {
}
}
if m.ticketSupported {
- // http://tools.ietf.org/html/rfc5077#section-3.2
+ // https://tools.ietf.org/html/rfc5077#section-3.2
z[0] = byte(extensionSessionTicket >> 8)
z[1] = byte(extensionSessionTicket)
l := len(m.sessionTicket)
@@ -414,7 +414,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
case extensionStatusRequest:
m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
case extensionSupportedCurves:
- // http://tools.ietf.org/html/rfc4492#section-5.5.1
+ // https://tools.ietf.org/html/rfc4492#section-5.5.1
if length < 2 {
return false
}
@@ -430,7 +430,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
d = d[2:]
}
case extensionSupportedPoints:
- // http://tools.ietf.org/html/rfc4492#section-5.5.2
+ // https://tools.ietf.org/html/rfc4492#section-5.5.2
if length < 1 {
return false
}
@@ -441,7 +441,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
m.supportedPoints = make([]uint8, l)
copy(m.supportedPoints, data[1:])
case extensionSessionTicket:
- // http://tools.ietf.org/html/rfc5077#section-3.2
+ // https://tools.ietf.org/html/rfc5077#section-3.2
m.ticketSupported = true
m.sessionTicket = data[:length]
case extensionSignatureAlgorithms:
@@ -1224,7 +1224,7 @@ func (m *certificateRequestMsg) marshal() (x []byte) {
return m.raw
}
- // See http://tools.ietf.org/html/rfc4346#section-7.4.4
+ // See https://tools.ietf.org/html/rfc4346#section-7.4.4
length := 1 + len(m.certificateTypes) + 2
casLength := 0
for _, ca := range m.certificateAuthorities {
@@ -1374,7 +1374,7 @@ func (m *certificateVerifyMsg) marshal() (x []byte) {
return m.raw
}
- // See http://tools.ietf.org/html/rfc4346#section-7.4.8
+ // See https://tools.ietf.org/html/rfc4346#section-7.4.8
siglength := len(m.signature)
length := 2 + siglength
if m.hasSignatureAndHash {
@@ -1452,7 +1452,7 @@ func (m *newSessionTicketMsg) marshal() (x []byte) {
return m.raw
}
- // See http://tools.ietf.org/html/rfc5077#section-3.3
+ // See https://tools.ietf.org/html/rfc5077#section-3.3
ticketLen := len(m.ticket)
length := 2 + 4 + ticketLen
x = make([]byte, 4+length)
diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go
index 991b4e9..ac491ba 100644
--- a/libgo/go/crypto/tls/handshake_server.go
+++ b/libgo/go/crypto/tls/handshake_server.go
@@ -10,10 +10,10 @@ import (
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
- "encoding/asn1"
"errors"
"fmt"
"io"
+ "sync/atomic"
)
// serverHandshakeState contains details of a server handshake in progress.
@@ -36,7 +36,6 @@ type serverHandshakeState struct {
}
// serverHandshake performs a TLS handshake as a server.
-// c.out.Mutex <= L; c.handshakeMutex <= L.
func (c *Conn) serverHandshake() error {
// If this is the first server handshake, we generate a random key to
// encrypt the tickets with.
@@ -103,7 +102,9 @@ func (c *Conn) serverHandshake() error {
return err
}
}
- c.handshakeComplete = true
+
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
+ atomic.StoreUint32(&c.handshakeStatus, 1)
return nil
}
@@ -519,59 +520,15 @@ func (hs *serverHandshakeState) doFullHandshake() error {
}
// Determine the signature type.
- var signatureAlgorithm SignatureScheme
- var sigType uint8
- if certVerify.hasSignatureAndHash {
- signatureAlgorithm = certVerify.signatureAlgorithm
- if !isSupportedSignatureAlgorithm(signatureAlgorithm, supportedSignatureAlgorithms) {
- return errors.New("tls: unsupported hash function for client certificate")
- }
- sigType = signatureFromSignatureScheme(signatureAlgorithm)
- } else {
- // Before TLS 1.2 the signature algorithm was implicit
- // from the key type, and only one hash per signature
- // algorithm was possible. Leave signatureAlgorithm
- // unset.
- switch pub.(type) {
- case *ecdsa.PublicKey:
- sigType = signatureECDSA
- case *rsa.PublicKey:
- sigType = signatureRSA
- }
+ _, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, supportedSignatureAlgorithms, c.vers)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
}
- switch key := pub.(type) {
- case *ecdsa.PublicKey:
- if sigType != signatureECDSA {
- err = errors.New("tls: bad signature type for client's ECDSA certificate")
- break
- }
- ecdsaSig := new(ecdsaSignature)
- if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
- break
- }
- if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
- err = errors.New("tls: ECDSA signature contained zero or negative values")
- break
- }
- var digest []byte
- if digest, _, err = hs.finishedHash.hashForClientCertificate(sigType, signatureAlgorithm, hs.masterSecret); err != nil {
- break
- }
- if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
- err = errors.New("tls: ECDSA verification failure")
- }
- case *rsa.PublicKey:
- if sigType != signatureRSA {
- err = errors.New("tls: bad signature type for client's RSA certificate")
- break
- }
- var digest []byte
- var hashFunc crypto.Hash
- if digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(sigType, signatureAlgorithm, hs.masterSecret); err != nil {
- break
- }
- err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
+ var digest []byte
+ if digest, err = hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret); err == nil {
+ err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature)
}
if err != nil {
c.sendAlert(alertBadCertificate)
diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go
index 6716021..c366f47 100644
--- a/libgo/go/crypto/tls/handshake_server_test.go
+++ b/libgo/go/crypto/tls/handshake_server_test.go
@@ -194,9 +194,9 @@ func TestDontSelectRSAWithECDSAKey(t *testing.T) {
func TestRenegotiationExtension(t *testing.T) {
clientHello := &clientHelloMsg{
- vers: VersionTLS12,
- compressionMethods: []uint8{compressionNone},
- random: make([]byte, 32),
+ vers: VersionTLS12,
+ compressionMethods: []uint8{compressionNone},
+ random: make([]byte, 32),
secureRenegotiationSupported: true,
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
}
@@ -992,12 +992,30 @@ func TestFallbackSCSV(t *testing.T) {
name: "FallbackSCSV",
config: &serverConfig,
// OpenSSL 1.0.1j is needed for the -fallback_scsv option.
- command: []string{"openssl", "s_client", "-fallback_scsv"},
+ command: []string{"openssl", "s_client", "-fallback_scsv"},
expectHandshakeErrorIncluding: "inappropriate protocol fallback",
}
runServerTestTLS11(t, test)
}
+func TestHandshakeServerExportKeyingMaterial(t *testing.T) {
+ test := &serverTest{
+ name: "ExportKeyingMaterial",
+ command: []string{"openssl", "s_client"},
+ config: testConfig.Clone(),
+ validate: func(state ConnectionState) error {
+ if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
+ return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
+ } else if len(km) != 42 {
+ return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
+ }
+ return nil
+ },
+ }
+ runServerTestTLS10(t, test)
+ runServerTestTLS12(t, test)
+}
+
func benchmarkHandshakeServer(b *testing.B, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
config := testConfig.Clone()
config.CipherSuites = []uint16{cipherSuite}
@@ -1403,3 +1421,21 @@ var testECDSAPrivateKey = &ecdsa.PrivateKey{
}
var testP256PrivateKey, _ = x509.ParseECPrivateKey(fromHex("30770201010420012f3b52bc54c36ba3577ad45034e2e8efe1e6999851284cb848725cfe029991a00a06082a8648ce3d030107a14403420004c02c61c9b16283bbcc14956d886d79b358aa614596975f78cece787146abf74c2d5dc578c0992b4f3c631373479ebf3892efe53d21c4f4f1cc9a11c3536b7f75"))
+
+func TestCloseServerConnectionOnIdleClient(t *testing.T) {
+ clientConn, serverConn := net.Pipe()
+ server := Server(serverConn, testConfig.Clone())
+ go func() {
+ clientConn.Write([]byte{'0'})
+ server.Close()
+ }()
+ server.SetReadDeadline(time.Now().Add(time.Second))
+ err := server.Handshake()
+ if err != nil {
+ if !strings.Contains(err.Error(), "read/write on closed pipe") {
+ t.Errorf("Error expected containing 'read/write on closed pipe' but got '%s'", err.Error())
+ }
+ } else {
+ t.Errorf("Error expected, but no error returned")
+ }
+}
diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go
index 3f570b6..1e77fac 100644
--- a/libgo/go/crypto/tls/key_agreement.go
+++ b/libgo/go/crypto/tls/key_agreement.go
@@ -6,13 +6,11 @@ package tls
import (
"crypto"
- "crypto/ecdsa"
"crypto/elliptic"
"crypto/md5"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
- "encoding/asn1"
"errors"
"io"
"math/big"
@@ -110,58 +108,21 @@ func md5SHA1Hash(slices [][]byte) []byte {
}
// hashForServerKeyExchange hashes the given slices and returns their digest
-// and the identifier of the hash function used. The signatureAlgorithm argument
-// is only used for >= TLS 1.2 and identifies the hash function to use.
-func hashForServerKeyExchange(sigType uint8, signatureAlgorithm SignatureScheme, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
+// using the given hash function (for >= TLS 1.2) or using a default based on
+// the sigType (for earlier TLS versions).
+func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) ([]byte, error) {
if version >= VersionTLS12 {
- if !isSupportedSignatureAlgorithm(signatureAlgorithm, supportedSignatureAlgorithms) {
- return nil, crypto.Hash(0), errors.New("tls: unsupported hash function used by peer")
- }
- hashFunc, err := lookupTLSHash(signatureAlgorithm)
- if err != nil {
- return nil, crypto.Hash(0), err
- }
h := hashFunc.New()
for _, slice := range slices {
h.Write(slice)
}
digest := h.Sum(nil)
- return digest, hashFunc, nil
+ return digest, nil
}
if sigType == signatureECDSA {
- return sha1Hash(slices), crypto.SHA1, nil
- }
- return md5SHA1Hash(slices), crypto.MD5SHA1, nil
-}
-
-// pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
-// ServerKeyExchange given the signature type being used and the client's
-// advertised list of supported signature and hash combinations.
-func pickTLS12HashForSignature(sigType uint8, clientList []SignatureScheme) (SignatureScheme, error) {
- if len(clientList) == 0 {
- // If the client didn't specify any signature_algorithms
- // extension then we can assume that it supports SHA1. See
- // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
- switch sigType {
- case signatureRSA:
- return PKCS1WithSHA1, nil
- case signatureECDSA:
- return ECDSAWithSHA1, nil
- default:
- return 0, errors.New("tls: unknown signature algorithm")
- }
+ return sha1Hash(slices), nil
}
-
- for _, sigAlg := range clientList {
- if signatureFromSignatureScheme(sigAlg) != sigType {
- continue
- }
- if isSupportedSignatureAlgorithm(sigAlg, supportedSignatureAlgorithms) {
- return sigAlg, nil
- }
- }
-
- return 0, errors.New("tls: client doesn't support any common hash functions")
+ return md5SHA1Hash(slices), nil
}
func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
@@ -178,13 +139,13 @@ func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
}
-// ecdheRSAKeyAgreement implements a TLS key agreement where the server
+// ecdheKeyAgreement implements a TLS key agreement where the server
// generates an ephemeral EC public/private key pair and signs it. The
// pre-master secret is then calculated using ECDH. The signature may
// either be ECDSA or RSA.
type ecdheKeyAgreement struct {
version uint16
- sigType uint8
+ isRSA bool
privateKey []byte
curveid CurveID
@@ -239,7 +200,7 @@ NextCandidate:
ecdhePublic = elliptic.Marshal(curve, x, y)
}
- // http://tools.ietf.org/html/rfc4492#section-5.4
+ // https://tools.ietf.org/html/rfc4492#section-5.4
serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
serverECDHParams[0] = 3 // named curve
serverECDHParams[1] = byte(ka.curveid >> 8)
@@ -247,41 +208,29 @@ NextCandidate:
serverECDHParams[3] = byte(len(ecdhePublic))
copy(serverECDHParams[4:], ecdhePublic)
- var signatureAlgorithm SignatureScheme
-
- if ka.version >= VersionTLS12 {
- var err error
- signatureAlgorithm, err = pickTLS12HashForSignature(ka.sigType, clientHello.supportedSignatureAlgorithms)
- if err != nil {
- return nil, err
- }
+ priv, ok := cert.PrivateKey.(crypto.Signer)
+ if !ok {
+ return nil, errors.New("tls: certificate private key does not implement crypto.Signer")
}
- digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, signatureAlgorithm, ka.version, clientHello.random, hello.random, serverECDHParams)
+ signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(priv.Public(), clientHello.supportedSignatureAlgorithms, supportedSignatureAlgorithms, ka.version)
if err != nil {
return nil, err
}
+ if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
+ return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
+ }
- priv, ok := cert.PrivateKey.(crypto.Signer)
- if !ok {
- return nil, errors.New("tls: certificate private key does not implement crypto.Signer")
+ digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, hello.random, serverECDHParams)
+ if err != nil {
+ return nil, err
}
- var sig []byte
- switch ka.sigType {
- case signatureECDSA:
- _, ok := priv.Public().(*ecdsa.PublicKey)
- if !ok {
- 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("tls: ECDHE RSA requires a RSA server key")
- }
- default:
- return nil, errors.New("tls: unknown ECDHE signature algorithm")
+
+ signOpts := crypto.SignerOpts(hashFunc)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
}
- sig, err = priv.Sign(config.rand(), digest, hashFunc)
+ sig, err := priv.Sign(config.rand(), digest, signOpts)
if err != nil {
return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
}
@@ -380,53 +329,30 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
if ka.version >= VersionTLS12 {
// handle SignatureAndHashAlgorithm
signatureAlgorithm = SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])
- if signatureFromSignatureScheme(signatureAlgorithm) != ka.sigType {
- return errServerKeyExchange
- }
sig = sig[2:]
if len(sig) < 2 {
return errServerKeyExchange
}
}
+ _, sigType, hashFunc, err := pickSignatureAlgorithm(cert.PublicKey, []SignatureScheme{signatureAlgorithm}, clientHello.supportedSignatureAlgorithms, ka.version)
+ if err != nil {
+ return err
+ }
+ if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
+ return errServerKeyExchange
+ }
+
sigLen := int(sig[0])<<8 | int(sig[1])
if sigLen+2 != len(sig) {
return errServerKeyExchange
}
sig = sig[2:]
- digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, signatureAlgorithm, ka.version, clientHello.random, serverHello.random, serverECDHParams)
+ digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams)
if err != nil {
return err
}
- switch ka.sigType {
- case signatureECDSA:
- pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
- if !ok {
- 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("tls: ECDSA signature contained zero or negative values")
- }
- if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
- return errors.New("tls: ECDSA verification failure")
- }
- case signatureRSA:
- pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
- if !ok {
- 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("tls: unknown ECDHE signature algorithm")
- }
-
- return nil
+ return verifyHandshakeSignature(sigType, cert.PublicKey, hashFunc, digest, sig)
}
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
diff --git a/libgo/go/crypto/tls/prf.go b/libgo/go/crypto/tls/prf.go
index 74438f8..a8cf21d 100644
--- a/libgo/go/crypto/tls/prf.go
+++ b/libgo/go/crypto/tls/prf.go
@@ -140,7 +140,7 @@ func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, labe
}
// masterFromPreMasterSecret generates the master secret from the pre-master
-// secret. See http://tools.ietf.org/html/rfc5246#section-8.1
+// secret. See https://tools.ietf.org/html/rfc5246#section-8.1
func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
seed := make([]byte, 0, len(clientRandom)+len(serverRandom))
seed = append(seed, clientRandom...)
@@ -309,50 +309,35 @@ func (h finishedHash) serverSum(masterSecret []byte) []byte {
return out
}
-// selectClientCertSignatureAlgorithm returns a SignatureScheme to sign a
-// client's CertificateVerify with, or an error if none can be found.
-func (h finishedHash) selectClientCertSignatureAlgorithm(serverList []SignatureScheme, sigType uint8) (SignatureScheme, error) {
- for _, v := range serverList {
- if signatureFromSignatureScheme(v) == sigType && isSupportedSignatureAlgorithm(v, supportedSignatureAlgorithms) {
- return v, nil
- }
- }
- return 0, errors.New("tls: no supported signature algorithm found for signing client certificate")
-}
-
-// hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
-// id suitable for signing by a TLS client certificate.
-func (h finishedHash) hashForClientCertificate(sigType uint8, signatureAlgorithm SignatureScheme, masterSecret []byte) ([]byte, crypto.Hash, error) {
+// hashForClientCertificate returns a digest over the handshake messages so far,
+// suitable for signing by a TLS client certificate.
+func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) ([]byte, error) {
if (h.version == VersionSSL30 || h.version >= VersionTLS12) && h.buffer == nil {
panic("a handshake hash for a client-certificate was requested after discarding the handshake buffer")
}
if h.version == VersionSSL30 {
- if sigType != signatureRSA {
- return nil, 0, errors.New("tls: unsupported signature type for client certificate")
+ if sigType != signaturePKCS1v15 {
+ return nil, errors.New("tls: unsupported signature type for client certificate")
}
md5Hash := md5.New()
md5Hash.Write(h.buffer)
sha1Hash := sha1.New()
sha1Hash.Write(h.buffer)
- return finishedSum30(md5Hash, sha1Hash, masterSecret, nil), crypto.MD5SHA1, nil
+ return finishedSum30(md5Hash, sha1Hash, masterSecret, nil), nil
}
if h.version >= VersionTLS12 {
- hashAlg, err := lookupTLSHash(signatureAlgorithm)
- if err != nil {
- return nil, 0, err
- }
hash := hashAlg.New()
hash.Write(h.buffer)
- return hash.Sum(nil), hashAlg, nil
+ return hash.Sum(nil), nil
}
if sigType == signatureECDSA {
- return h.server.Sum(nil), crypto.SHA1, nil
+ return h.server.Sum(nil), nil
}
- return h.Sum(), crypto.MD5SHA1, nil
+ return h.Sum(), nil
}
// discardHandshakeBuffer is called when there is no more need to
@@ -360,3 +345,43 @@ func (h finishedHash) hashForClientCertificate(sigType uint8, signatureAlgorithm
func (h *finishedHash) discardHandshakeBuffer() {
h.buffer = nil
}
+
+// noExportedKeyingMaterial is used as a value of
+// ConnectionState.ekm when renegotation is enabled and thus
+// we wish to fail all key-material export requests.
+func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
+ return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
+}
+
+// ekmFromMasterSecret generates exported keying material as defined in
+// https://tools.ietf.org/html/rfc5705.
+func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {
+ return func(label string, context []byte, length int) ([]byte, error) {
+ switch label {
+ case "client finished", "server finished", "master secret", "key expansion":
+ // These values are reserved and may not be used.
+ return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label)
+ }
+
+ seedLen := len(serverRandom) + len(clientRandom)
+ if context != nil {
+ seedLen += 2 + len(context)
+ }
+ seed := make([]byte, 0, seedLen)
+
+ seed = append(seed, clientRandom...)
+ seed = append(seed, serverRandom...)
+
+ if context != nil {
+ if len(context) >= 1<<16 {
+ return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long")
+ }
+ seed = append(seed, byte(len(context)>>8), byte(len(context)))
+ seed = append(seed, context...)
+ }
+
+ keyMaterial := make([]byte, length)
+ prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)
+ return keyMaterial, nil
+ }
+}
diff --git a/libgo/go/crypto/tls/prf_test.go b/libgo/go/crypto/tls/prf_test.go
index 0a1b1bc..f201253 100644
--- a/libgo/go/crypto/tls/prf_test.go
+++ b/libgo/go/crypto/tls/prf_test.go
@@ -34,14 +34,15 @@ func TestSplitPreMasterSecret(t *testing.T) {
}
type testKeysFromTest struct {
- version uint16
- suite *cipherSuite
- preMasterSecret string
- clientRandom, serverRandom string
- masterSecret string
- clientMAC, serverMAC string
- clientKey, serverKey string
- macLen, keyLen int
+ version uint16
+ suite *cipherSuite
+ preMasterSecret string
+ clientRandom, serverRandom string
+ masterSecret string
+ clientMAC, serverMAC string
+ clientKey, serverKey string
+ macLen, keyLen int
+ contextKeyingMaterial, noContextKeyingMaterial string
}
func TestKeysFromPreMasterSecret(t *testing.T) {
@@ -67,6 +68,22 @@ func TestKeysFromPreMasterSecret(t *testing.T) {
serverKeyString != test.serverKey {
t.Errorf("#%d: got: (%s, %s, %s, %s) want: (%s, %s, %s, %s)", i, clientMACString, serverMACString, clientKeyString, serverKeyString, test.clientMAC, test.serverMAC, test.clientKey, test.serverKey)
}
+
+ ekm := ekmFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom)
+ contextKeyingMaterial, err := ekm("label", []byte("context"), 32)
+ if err != nil {
+ t.Fatalf("ekmFromMasterSecret failed: %v", err)
+ }
+
+ noContextKeyingMaterial, err := ekm("label", nil, 32)
+ if err != nil {
+ t.Fatalf("ekmFromMasterSecret failed: %v", err)
+ }
+
+ if hex.EncodeToString(contextKeyingMaterial) != test.contextKeyingMaterial ||
+ hex.EncodeToString(noContextKeyingMaterial) != test.noContextKeyingMaterial {
+ t.Errorf("#%d: got keying material: (%s, %s) want: (%s, %s)", i, contextKeyingMaterial, noContextKeyingMaterial, test.contextKeyingMaterial, test.noContextKeyingMaterial)
+ }
}
}
@@ -94,6 +111,8 @@ var testKeysFromTests = []testKeysFromTest{
"e076e33206b30507a85c32855acd0919",
20,
16,
+ "4d1bb6fc278c37d27aa6e2a13c2e079095d143272c2aa939da33d88c1c0cec22",
+ "93fba89599b6321ae538e27c6548ceb8b46821864318f5190d64a375e5d69d41",
},
{
VersionTLS10,
@@ -108,6 +127,8 @@ var testKeysFromTests = []testKeysFromTest{
"df3f94f6e1eacc753b815fe16055cd43",
20,
16,
+ "2c9f8961a72b97cbe76553b5f954caf8294fc6360ef995ac1256fe9516d0ce7f",
+ "274f19c10291d188857ad8878e2119f5aa437d4da556601cf1337aff23154016",
},
{
VersionTLS10,
@@ -122,6 +143,8 @@ var testKeysFromTests = []testKeysFromTest{
"ff07edde49682b45466bd2e39464b306",
20,
16,
+ "678b0d43f607de35241dc7e9d1a7388a52c35033a1a0336d4d740060a6638fe2",
+ "f3b4ac743f015ef21d79978297a53da3e579ee047133f38c234d829c0f907dab",
},
{
VersionSSL30,
@@ -136,5 +159,7 @@ var testKeysFromTests = []testKeysFromTest{
"2b9d4b4a60cb7f396780ebff50650419",
20,
16,
+ "d230d8fc4f695be60368635e5268c414ca3ae0995dd93aba9f877272049f35bf",
+ "6b5e9646e04df8e99482a9b22dbfbe42ddd4725e4b041d02d11e4ef44ad13120",
},
}
diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
new file mode 100644
index 0000000..571769e
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
@@ -0,0 +1,89 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 95 01 00 00 91 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 2c cc a8 |.............,..|
+00000030 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#|
+00000040 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5|
+00000050 c0 12 00 0a 00 05 c0 11 c0 07 01 00 00 3c 00 05 |.............<..|
+00000060 00 05 01 00 00 00 00 00 0a 00 0a 00 08 00 1d 00 |................|
+00000070 17 00 18 00 19 00 0b 00 02 01 00 00 0d 00 12 00 |................|
+00000080 10 04 01 04 03 05 01 05 03 06 01 06 03 02 01 02 |................|
+00000090 03 ff 01 00 01 00 00 12 00 00 |..........|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 59 02 00 00 55 03 01 67 4f 02 da 87 |....Y...U..gO...|
+00000010 52 30 9a f0 3b e0 63 42 bf 6c 18 58 00 06 70 cf |R0..;.cB.l.X..p.|
+00000020 2a 27 5a 00 a7 57 49 fe 03 dd 3b 20 7c 2c 74 00 |*'Z..WI...; |,t.|
+00000030 6e b2 35 ca 1b b5 8c 46 f7 78 ab 11 92 43 8c f6 |n.5....F.x...C..|
+00000040 97 d3 b8 07 4c 9c 95 2b 08 fe e8 82 c0 13 00 00 |....L..+........|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 01 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
+00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
+00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
+00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
+000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
+000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
+000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
+000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
+000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
+000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
+00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
+00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
+00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
+00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
+00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
+00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
+00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
+00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
+00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
+00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
+000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
+000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
+000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
+000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
+000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
+000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
+00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
+00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
+00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
+00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
+00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
+00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
+00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
+00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
+00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
+00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
+000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
+000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 |.=.`.\!.;.......|
+000002c0 aa 0c 00 00 a6 03 00 1d 20 a0 0e 1d 92 2d b0 a5 |........ ....-..|
+000002d0 f0 ab d5 79 a0 bb 12 ff 23 46 bc 27 0d 73 ff 3e |...y....#F.'.s.>|
+000002e0 ad 06 d6 57 6b c2 11 76 2d 00 80 77 bf cd 2b cb |...Wk..v-..w..+.|
+000002f0 66 c2 fa 30 ed b1 e7 44 79 1b 28 e6 89 62 17 07 |f..0...Dy.(..b..|
+00000300 82 c1 5f dc b2 20 4e 42 ed 54 d6 28 3a 2a e3 a3 |.._.. NB.T.(:*..|
+00000310 79 06 e3 08 3c c1 3e b9 c6 41 71 2f d0 29 82 36 |y...<.>..Aq/.).6|
+00000320 ef 8d 67 c8 77 d0 32 d3 33 5f 77 92 dd 98 bb 03 |..g.w.2.3_w.....|
+00000330 cc 0b a6 75 8f 4a 1d f5 6e 1b 06 5b 4a 8b 16 a4 |...u.J..n..[J...|
+00000340 c1 ce 11 9d 70 bc 62 7f 58 a5 86 76 91 3d 3a 04 |....p.b.X..v.=:.|
+00000350 93 92 89 42 9b a7 7d 9d 75 25 6d 98 f3 e6 68 7e |...B..}.u%m...h~|
+00000360 a8 c6 b1 db a7 95 63 39 94 5a 05 16 03 01 00 04 |......c9.Z......|
+00000370 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 01 00 01 01 |....._X.;t......|
+00000030 16 03 01 00 30 73 ad 46 66 66 e8 bd 44 e4 bf 71 |....0s.Fff..D..q|
+00000040 a2 d4 87 e2 4b a3 4a b2 a0 ca ed ac 61 8c 1e 7f |....K.J.....a...|
+00000050 68 bf 6f 98 b1 fb 10 1a 5a e6 36 61 91 ac c4 55 |h.o.....Z.6a...U|
+00000060 a3 4d 69 66 6e |.Mifn|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 57 aa 5c d5 dc |..........0W.\..|
+00000010 83 4b 23 80 34 4e 36 e8 d6 f3 40 7e ae 12 44 a6 |.K#.4N6...@~..D.|
+00000020 c7 48 99 99 0a 85 3c 59 75 32 4e 88 3c 98 a0 23 |.H....<Yu2N.<..#|
+00000030 78 c8 a7 2b 43 25 6a ad d1 78 54 |x..+C%j..xT|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 e4 9c f4 fa 6b e8 85 87 6f 20 45 |.... ....k...o E|
+00000010 71 d3 e2 9e e3 14 2a 7c 64 e8 11 53 fd 93 c1 4a |q.....*|d..S...J|
+00000020 1b 94 f8 48 78 17 03 01 00 20 b9 41 32 1d e8 70 |...Hx.... .A2..p|
+00000030 87 5f 2c c6 67 d1 77 3c 30 83 0c 66 35 eb 1d da |._,.g.w<0..f5...|
+00000040 6e dd 30 ff 82 05 5f f1 cd e7 15 03 01 00 20 6c |n.0..._....... l|
+00000050 47 82 5e 90 5b 84 15 78 05 bd 48 63 d5 46 2f 7e |G.^.[..x..Hc.F/~|
+00000060 83 49 ce 3c 0f 04 92 52 5b e7 d5 cf 2c bf 65 |.I.<...R[...,.e|
diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
new file mode 100644
index 0000000..29964f0
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 95 01 00 00 91 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 2c cc a8 |.............,..|
+00000030 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#|
+00000040 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5|
+00000050 c0 12 00 0a 00 05 c0 11 c0 07 01 00 00 3c 00 05 |.............<..|
+00000060 00 05 01 00 00 00 00 00 0a 00 0a 00 08 00 1d 00 |................|
+00000070 17 00 18 00 19 00 0b 00 02 01 00 00 0d 00 12 00 |................|
+00000080 10 04 01 04 03 05 01 05 03 06 01 06 03 02 01 02 |................|
+00000090 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 fc 37 e8 a4 e3 |....Y...U...7...|
+00000010 5d da a5 95 0b fb e0 c3 d9 78 8b 91 bd 5c 1c b1 |]........x...\..|
+00000020 c6 8d 69 62 f9 c6 0f 12 da 46 ba 20 34 a3 22 f2 |..ib.....F. 4.".|
+00000030 a9 f7 da 3a c4 5f 6f f7 4b be df 03 e5 b6 d0 ff |...:._o.K.......|
+00000040 ca 54 68 59 57 53 63 a5 2f 91 1d 1e cc a8 00 00 |.ThYWSc./.......|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
+00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
+00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
+00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
+000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
+000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
+000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
+000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
+000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
+000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
+00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
+00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
+00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
+00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
+00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
+00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
+00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
+00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
+00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
+00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
+000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
+000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
+000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
+000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
+000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
+000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
+00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
+00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
+00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
+00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
+00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
+00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
+00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
+00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
+00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
+00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
+000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
+000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
+000002c0 ac 0c 00 00 a8 03 00 1d 20 cc e9 71 f5 36 52 5a |........ ..q.6RZ|
+000002d0 d8 19 ce e4 0d 41 8d a6 9b f3 19 56 8d 81 fe 84 |.....A.....V....|
+000002e0 71 2f d7 fb e7 86 23 4c 04 04 01 00 80 90 da 29 |q/....#L.......)|
+000002f0 79 18 70 e8 81 66 83 70 97 f1 d1 5f dc 1d a2 0a |y.p..f.p..._....|
+00000300 94 d8 e8 b8 32 4f 03 34 0b af e8 2d 94 b2 eb 30 |....2O.4...-...0|
+00000310 57 b5 a5 92 9e 9a df a6 bc 3e 25 0e 18 cb ea 84 |W........>%.....|
+00000320 34 89 08 8a d4 be 16 a3 5d 3a 7d 32 10 9b 41 1c |4.......]:}2..A.|
+00000330 2a 1e 05 68 5f fa d9 56 30 b6 44 08 b0 a5 25 5a |*..h_..V0.D...%Z|
+00000340 c3 60 c0 9a 98 fd 48 5f a4 18 d0 15 0f fb b3 ea |.`....H_........|
+00000350 b9 c4 e3 c6 0c 27 51 64 01 de 65 78 c7 a0 57 df |.....'Qd..ex..W.|
+00000360 9b de 2f 74 bc 72 e5 e0 57 7c 59 e6 ae 16 03 03 |../t.r..W|Y.....|
+00000370 00 04 0e 00 00 00 |......|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 92 0a 4e aa 2d b3 9b c8 b9 80 28 |.... ..N.-.....(|
+00000040 f3 22 e2 57 15 ff a1 9a 33 9b e8 4c 5c dc f4 29 |.".W....3..L\..)|
+00000050 7d 25 d7 df bc |}%...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 91 85 06 0e 00 |.......... .....|
+00000010 ad 96 2e 1c a5 4d f7 63 f9 84 1c 6e da 54 0b e0 |.....M.c...n.T..|
+00000020 44 37 6a 90 4c fd f5 e8 45 1d ce |D7j.L...E..|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 4c e8 8a e0 a6 95 f3 df 37 8a 2d |.....L.......7.-|
+00000010 4f 11 ce a6 53 16 2c b0 bb c5 7f 15 03 03 00 12 |O...S.,.........|
+00000020 4e 91 d8 67 c5 16 d2 4e cc b8 0a 00 76 91 68 7a |N..g...N....v.hz|
+00000030 85 2e |..|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
new file mode 100644
index 0000000..84e0e37
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
@@ -0,0 +1,92 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 61 01 00 00 5d 03 01 f4 ec 99 73 ec |....a...].....s.|
+00000010 36 30 c7 0b 26 33 a2 c4 26 8e 9f 04 f7 5b e7 4f |60..&3..&....[.O|
+00000020 86 85 14 bf f7 49 96 a4 ae c9 1d 00 00 12 c0 0a |.....I..........|
+00000030 c0 14 00 39 c0 09 c0 13 00 33 00 35 00 2f 00 ff |...9.....3.5./..|
+00000040 01 00 00 22 00 0b 00 04 03 00 01 02 00 0a 00 0a |..."............|
+00000050 00 08 00 1d 00 17 00 19 00 18 00 23 00 00 00 16 |...........#....|
+00000060 00 00 00 17 00 00 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 35 02 00 00 31 03 01 00 00 00 00 00 |....5...1.......|
+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 c0 14 00 00 |................|
+00000030 09 00 23 00 00 ff 01 00 01 00 16 03 01 02 59 0b |..#...........Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 01 00 aa 0c 00 00 |.\!.;...........|
+000002a0 a6 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da |.... /.}.G.bC.(.|
+000002b0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........|
+000002c0 5f 58 cb 3b 74 00 80 8e fe 28 f2 06 d8 b9 d6 74 |_X.;t....(.....t|
+000002d0 72 34 dc fa 00 38 56 1a fc a1 68 e8 ca 8f 7a 61 |r4...8V...h...za|
+000002e0 92 e2 2a 63 ce 4d 96 c6 bb 84 82 41 2d 97 35 13 |..*c.M.....A-.5.|
+000002f0 e1 ff 4c ec f2 e6 62 16 15 35 da 8a 57 55 cb 28 |..L...b..5..WU.(|
+00000300 26 35 e6 86 00 b0 92 44 b7 40 7b 6a c4 b0 b8 10 |&5.....D.@{j....|
+00000310 b7 16 97 a7 26 eb 1e 0b 99 b3 22 4a 6b 7f 0b 69 |....&....."Jk..i|
+00000320 0d 21 1e 33 6d fd 78 b5 62 68 53 db 62 69 ba b4 |.!.3m.x.bhS.bi..|
+00000330 bc 74 b3 d4 ce a2 41 d7 ba 62 aa cc b2 39 65 86 |.t....A..b...9e.|
+00000340 5f 00 68 e2 16 a5 13 16 03 01 00 04 0e 00 00 00 |_.h.............|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 81 08 e4 37 1d 03 |....%...! ...7..|
+00000010 87 5a 00 68 ae 49 76 08 4a e2 20 82 0b e5 7c 3e |.Z.h.Iv.J. ...|>|
+00000020 90 49 9b c3 b9 c7 c9 3c 29 24 14 03 01 00 01 01 |.I.....<)$......|
+00000030 16 03 01 00 30 33 07 d5 08 ca ae f9 70 50 93 0a |....03......pP..|
+00000040 55 2e e0 df 1d 88 ae 1e 06 17 47 64 a3 52 36 37 |U.........Gd.R67|
+00000050 d5 ca f1 b1 d2 76 7b f8 89 59 13 e9 ab b1 cb dc |.....v{..Y......|
+00000060 1f a8 89 f4 2f |..../|
+>>> Flow 4 (server to client)
+00000000 16 03 01 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6d ec a4 83 61 a4 a1 9c 14 de f8 59 c8 c7 f0 10 |m...a......Y....|
+00000040 08 fe c9 37 29 ed 47 05 d2 bd a8 4c 05 b9 8c f8 |...7).G....L....|
+00000050 b5 4d e4 a6 30 0f 49 4a b1 73 1f 89 73 c8 bb 36 |.M..0.IJ.s..s..6|
+00000060 14 9d d2 95 70 33 94 fb 82 e6 fe 3e 64 8c 9d e8 |....p3.....>d...|
+00000070 e3 e5 93 3d fe 4e 23 a3 97 8a a3 91 80 c9 00 01 |...=.N#.........|
+00000080 a6 f0 47 cf 11 a6 90 14 03 01 00 01 01 16 03 01 |..G.............|
+00000090 00 30 1f 70 17 a1 30 82 5a 32 e7 aa a1 7f 1b f6 |.0.p..0.Z2......|
+000000a0 d8 aa 6a 51 64 1b 4a f1 94 12 08 2f 5d 95 fe 83 |..jQd.J..../]...|
+000000b0 52 c8 3b d4 58 73 50 19 b8 08 61 b3 3a 5d f6 d3 |R.;.XsP...a.:]..|
+000000c0 67 e6 17 03 01 00 20 bd 79 44 08 9d 86 cf 5e e9 |g..... .yD....^.|
+000000d0 e4 3c 80 ed b7 18 10 07 0f 42 85 ca a4 51 fd 9b |.<.......B...Q..|
+000000e0 38 3e 04 7e 72 6e 80 17 03 01 00 30 2c 46 c2 71 |8>.~rn.....0,F.q|
+000000f0 4a 83 46 eb 63 87 f5 83 b4 72 70 4f a3 59 b3 ff |J.F.c....rpO.Y..|
+00000100 3c 00 74 12 db 33 51 4c 7c e0 c1 27 44 20 68 25 |<.t..3QL|..'D h%|
+00000110 95 f1 37 2a 24 f1 85 a3 5a e4 50 fe 15 03 01 00 |..7*$...Z.P.....|
+00000120 20 72 01 cc 74 d5 b4 6b 05 ce de f0 b4 fe 4f 6b | r..t..k......Ok|
+00000130 a8 8f ad 5a c2 7d 40 65 d6 a2 57 52 b8 8a c5 4f |...Z.}@e..WR...O|
+00000140 d9 |.|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
new file mode 100644
index 0000000..6415c42
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
@@ -0,0 +1,92 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ab 01 00 00 a7 03 03 7a 49 9d 20 62 |...........zI. b|
+00000010 45 8d 0c 1e 8e eb b1 5e 73 62 6d 48 61 31 cb 1a |E......^sbmHa1..|
+00000020 89 b2 68 1b 2c cb 35 87 2a 17 fb 00 00 38 c0 2c |..h.,.5.*....8.,|
+00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..|
+00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....|
+00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<|
+00000060 00 35 00 2f 00 ff 01 00 00 46 00 0b 00 04 03 00 |.5./.....F......|
+00000070 01 02 00 0a 00 0a 00 08 00 1d 00 17 00 19 00 18 |................|
+00000080 00 23 00 00 00 16 00 00 00 17 00 00 00 0d 00 20 |.#............. |
+00000090 00 1e 06 01 06 02 06 03 05 01 05 02 05 03 04 01 |................|
+000000a0 04 02 04 03 03 01 03 02 03 03 02 01 02 02 02 03 |................|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+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 c0 30 00 00 |.............0..|
+00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 00 |.\!.;...........|
+000002a0 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da |.... /.}.G.bC.(.|
+000002b0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........|
+000002c0 5f 58 cb 3b 74 06 01 00 80 7f ee dd 6b 38 23 29 |_X.;t.......k8#)|
+000002d0 56 ff d2 c2 08 86 52 b6 e3 8a d5 fe 47 79 5e ef |V.....R.....Gy^.|
+000002e0 99 7a 0b d7 44 84 b9 2f 7a 2c 64 4f b3 7c aa 44 |.z..D../z,dO.|.D|
+000002f0 aa 38 5d 1b 69 16 9f f2 7d f8 24 43 47 ad 31 bc |.8].i...}.$CG.1.|
+00000300 f5 3d b8 c8 33 6e 3f 6f 2b ea 19 a2 30 32 2b 2a |.=..3n?o+...02+*|
+00000310 81 64 3c ee ed 78 4c fa 80 fd e7 5f ef 85 98 d4 |.d<..xL...._....|
+00000320 48 06 b8 f5 5e 1e e6 f3 42 a8 2f 99 5f ea b3 ba |H...^...B./._...|
+00000330 8e a8 31 99 85 f2 46 11 a3 d2 c6 81 4b f1 22 7d |..1...F.....K."}|
+00000340 d7 45 04 f1 a6 d6 7e 8f 9d 16 03 03 00 04 0e 00 |.E....~.........|
+00000350 00 00 |..|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 22 e7 e7 61 a9 27 |....%...! "..a.'|
+00000010 7b 93 d1 42 76 dd 16 32 e8 92 37 37 2f fd 0d 92 |{..Bv..2..77/...|
+00000020 1f 8e b7 c5 69 40 d3 1a 7d 06 14 03 03 00 01 01 |....i@..}.......|
+00000030 16 03 03 00 28 4e 7f b2 a2 20 5d cf a1 5a de 42 |....(N... ]..Z.B|
+00000040 c5 72 c3 ef c3 23 a7 2c f3 5b 3d a4 81 21 ac db |.r...#.,.[=..!..|
+00000050 44 1c f3 a1 83 aa a1 b7 85 9a c7 23 03 |D..........#.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f ec 80 83 61 3f 55 e3 9d ab 39 87 5b d0 ba 44 |o...a?U...9.[..D|
+00000040 07 91 a8 d0 37 8a 7e 51 0d 00 97 ec 1b 61 f3 3b |....7.~Q.....a.;|
+00000050 9f 29 24 d5 98 f7 4d 3b 80 ef 2f 4d aa 02 98 93 |.)$...M;../M....|
+00000060 81 03 87 d8 06 33 94 f5 ed 5d cc 8f 57 97 70 26 |.....3...]..W.p&|
+00000070 00 dc 0d d2 96 16 a2 6d fc be 8d 4b fa 5f b3 04 |.......m...K._..|
+00000080 ce bb 48 ee c0 75 23 14 03 03 00 01 01 16 03 03 |..H..u#.........|
+00000090 00 28 00 00 00 00 00 00 00 00 3a 69 e0 40 e2 d1 |.(........:i.@..|
+000000a0 a6 96 33 0f b3 58 5a dc 41 ea d1 80 44 66 9f 2e |..3..XZ.A...Df..|
+000000b0 00 e4 9e 10 13 56 b4 1b c9 42 17 03 03 00 25 00 |.....V...B....%.|
+000000c0 00 00 00 00 00 00 01 88 f3 d9 5b ed 6b 3c 70 0c |..........[.k<p.|
+000000d0 df 36 9d 1c f6 f6 83 38 53 ad e2 06 47 3c e2 9f |.6.....8S...G<..|
+000000e0 42 87 d7 8a 15 03 03 00 1a 00 00 00 00 00 00 00 |B...............|
+000000f0 02 df 4a 92 13 c4 e6 ac 76 25 c6 72 27 be d6 09 |..J.....v%.r'...|
+00000100 eb 90 ed |...|
diff --git a/libgo/go/crypto/tls/testdata/example-cert.pem b/libgo/go/crypto/tls/testdata/example-cert.pem
new file mode 100644
index 0000000..e0bf7db
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/example-cert.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
+DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
+EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
+7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
+5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
+BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
+NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
+Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
+6MF9+Yw1Yy0t
+-----END CERTIFICATE-----
diff --git a/libgo/go/crypto/tls/testdata/example-key.pem b/libgo/go/crypto/tls/testdata/example-key.pem
new file mode 100644
index 0000000..104fb09
--- /dev/null
+++ b/libgo/go/crypto/tls/testdata/example-key.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
+AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
+EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
+-----END EC PRIVATE KEY-----
diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go
index 615d1e5..8fd4294 100644
--- a/libgo/go/crypto/tls/tls.go
+++ b/libgo/go/crypto/tls/tls.go
@@ -237,15 +237,14 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
}
- var err error
- cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
+ // We don't need to parse the public key for TLS, but we so do anyway
+ // to check that it looks sane and matches the private key.
+ x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return fail(err)
}
- // We don't need to parse the public key for TLS, but we so do anyway
- // to check that it looks sane and matches the private key.
- x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
+ cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
if err != nil {
return fail(err)
}
diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go
index 97934cc..7542699 100644
--- a/libgo/go/crypto/tls/tls_test.go
+++ b/libgo/go/crypto/tls/tls_test.go
@@ -7,6 +7,7 @@ package tls
import (
"bytes"
"crypto/x509"
+ "encoding/json"
"errors"
"fmt"
"internal/testenv"
@@ -907,3 +908,11 @@ func BenchmarkLatency(b *testing.B) {
}
}
}
+
+func TestConnectionStateMarshal(t *testing.T) {
+ cs := &ConnectionState{}
+ _, err := json.Marshal(cs)
+ if err != nil {
+ t.Errorf("json.Marshal failed on ConnectionState: %v", err)
+ }
+}
diff --git a/libgo/go/crypto/x509/cert_pool.go b/libgo/go/crypto/x509/cert_pool.go
index 71ffbdf..a1646b9 100644
--- a/libgo/go/crypto/x509/cert_pool.go
+++ b/libgo/go/crypto/x509/cert_pool.go
@@ -25,16 +25,43 @@ func NewCertPool() *CertPool {
}
}
+func (s *CertPool) copy() *CertPool {
+ p := &CertPool{
+ bySubjectKeyId: make(map[string][]int, len(s.bySubjectKeyId)),
+ byName: make(map[string][]int, len(s.byName)),
+ certs: make([]*Certificate, len(s.certs)),
+ }
+ for k, v := range s.bySubjectKeyId {
+ indexes := make([]int, len(v))
+ copy(indexes, v)
+ p.bySubjectKeyId[k] = indexes
+ }
+ for k, v := range s.byName {
+ indexes := make([]int, len(v))
+ copy(indexes, v)
+ p.byName[k] = indexes
+ }
+ copy(p.certs, s.certs)
+ return p
+}
+
// 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.
+//
+// New changes in the the system cert pool might not be reflected
+// in subsequent calls.
func SystemCertPool() (*CertPool, error) {
if runtime.GOOS == "windows" {
// Issue 16736, 18609:
return nil, errors.New("crypto/x509: system root pool is not available on Windows")
}
+ if sysRoots := systemRootsPool(); sysRoots != nil {
+ return sysRoots.copy(), nil
+ }
+
return loadSystemRoots()
}
diff --git a/libgo/go/crypto/x509/name_constraints_test.go b/libgo/go/crypto/x509/name_constraints_test.go
index 95d55fd..4c9bc1b 100644
--- a/libgo/go/crypto/x509/name_constraints_test.go
+++ b/libgo/go/crypto/x509/name_constraints_test.go
@@ -46,6 +46,7 @@ type nameConstraintsTest struct {
requestedEKUs []ExtKeyUsage
expectedError string
noOpenSSL bool
+ ignoreCN bool
}
type constraintsSpec struct {
@@ -57,6 +58,7 @@ type constraintsSpec struct {
type leafSpec struct {
sans []string
ekus []string
+ cn string
}
var nameConstraintsTests = []nameConstraintsTest{
@@ -633,7 +635,7 @@ var nameConstraintsTests = []nameConstraintsTest{
},
},
- // #30: without SANs, a certificate is rejected in a constrained chain.
+ // #30: without SANs, a certificate with a CN is rejected in a constrained chain.
nameConstraintsTest{
roots: []constraintsSpec{
constraintsSpec{
@@ -647,9 +649,9 @@ var nameConstraintsTests = []nameConstraintsTest{
},
leaf: leafSpec{
sans: []string{},
+ cn: "foo.com",
},
expectedError: "leaf doesn't have a SAN extension",
- noOpenSSL: true, // OpenSSL doesn't require SANs in this case.
},
// #31: IPv6 addresses work in constraints: roots can permit them as
@@ -1580,6 +1582,80 @@ var nameConstraintsTests = []nameConstraintsTest{
ekus: []string{"email", "serverAuth"},
},
},
+
+ // #82: a certificate without SANs and CN is accepted in a constrained chain.
+ nameConstraintsTest{
+ roots: []constraintsSpec{
+ constraintsSpec{
+ ok: []string{"dns:foo.com", "dns:.foo.com"},
+ },
+ },
+ intermediates: [][]constraintsSpec{
+ []constraintsSpec{
+ constraintsSpec{},
+ },
+ },
+ leaf: leafSpec{
+ sans: []string{},
+ },
+ },
+
+ // #83: a certificate without SANs and with a CN that does not parse as a
+ // hostname is accepted in a constrained chain.
+ nameConstraintsTest{
+ roots: []constraintsSpec{
+ constraintsSpec{
+ ok: []string{"dns:foo.com", "dns:.foo.com"},
+ },
+ },
+ intermediates: [][]constraintsSpec{
+ []constraintsSpec{
+ constraintsSpec{},
+ },
+ },
+ leaf: leafSpec{
+ sans: []string{},
+ cn: "foo,bar",
+ },
+ },
+
+ // #84: a certificate with SANs and CN is accepted in a constrained chain.
+ nameConstraintsTest{
+ roots: []constraintsSpec{
+ constraintsSpec{
+ ok: []string{"dns:foo.com", "dns:.foo.com"},
+ },
+ },
+ intermediates: [][]constraintsSpec{
+ []constraintsSpec{
+ constraintsSpec{},
+ },
+ },
+ leaf: leafSpec{
+ sans: []string{"dns:foo.com"},
+ cn: "foo.bar",
+ },
+ },
+
+ // #85: without SANs, a certificate with a valid CN is accepted in a
+ // constrained chain if x509ignoreCN is set.
+ nameConstraintsTest{
+ roots: []constraintsSpec{
+ constraintsSpec{
+ ok: []string{"dns:foo.com", "dns:.foo.com"},
+ },
+ },
+ intermediates: [][]constraintsSpec{
+ []constraintsSpec{
+ constraintsSpec{},
+ },
+ },
+ leaf: leafSpec{
+ sans: []string{},
+ cn: "foo.com",
+ },
+ ignoreCN: true,
+ },
}
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
@@ -1625,9 +1701,8 @@ func makeConstraintsLeafCert(leaf leafSpec, key *ecdsa.PrivateKey, parent *Certi
template := &Certificate{
SerialNumber: new(big.Int).SetBytes(serialBytes[:]),
Subject: pkix.Name{
- // Don't set a CommonName because OpenSSL (at least) will try to
- // match it against name constraints.
OrganizationalUnit: []string{"Leaf"},
+ CommonName: leaf.cn,
},
NotBefore: time.Unix(1000, 0),
NotAfter: time.Unix(2000, 0),
@@ -1831,6 +1906,10 @@ func parseEKUs(ekuStrs []string) (ekus []ExtKeyUsage, unknowns []asn1.ObjectIden
}
func TestConstraintCases(t *testing.T) {
+ defer func(savedIgnoreCN bool) {
+ ignoreCN = savedIgnoreCN
+ }(ignoreCN)
+
privateKeys := sync.Pool{
New: func() interface{} {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
@@ -1899,7 +1978,9 @@ func TestConstraintCases(t *testing.T) {
t.Fatalf("#%d: cannot create leaf: %s", i, err)
}
- if !test.noOpenSSL && testNameConstraintsAgainstOpenSSL {
+ // Skip tests with CommonName set because OpenSSL will try to match it
+ // against name constraints, while we ignore it when it's not hostname-looking.
+ if !test.noOpenSSL && testNameConstraintsAgainstOpenSSL && test.leaf.cn == "" {
output, err := testChainAgainstOpenSSL(leafCert, intermediatePool, rootPool)
if err == nil && len(test.expectedError) > 0 {
t.Errorf("#%d: unexpectedly succeeded against OpenSSL", i)
@@ -1912,7 +1993,7 @@ func TestConstraintCases(t *testing.T) {
if _, ok := err.(*exec.ExitError); !ok {
t.Errorf("#%d: OpenSSL failed to run: %s", i, err)
} else if len(test.expectedError) == 0 {
- t.Errorf("#%d: OpenSSL unexpectedly failed: %q", i, output)
+ t.Errorf("#%d: OpenSSL unexpectedly failed: %v", i, output)
if debugOpenSSLFailure {
return
}
@@ -1920,6 +2001,7 @@ func TestConstraintCases(t *testing.T) {
}
}
+ ignoreCN = test.ignoreCN
verifyOpts := VerifyOptions{
Roots: rootPool,
Intermediates: intermediatePool,
@@ -1949,7 +2031,7 @@ func TestConstraintCases(t *testing.T) {
certAsPEM := func(cert *Certificate) string {
var buf bytes.Buffer
pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
- return string(buf.Bytes())
+ return buf.String()
}
t.Errorf("#%d: root:\n%s", i, certAsPEM(rootPool.certs[0]))
t.Errorf("#%d: leaf:\n%s", i, certAsPEM(leafCert))
@@ -2012,7 +2094,7 @@ func testChainAgainstOpenSSL(leaf *Certificate, intermediates, roots *CertPool)
cmd.Stderr = &output
err := cmd.Run()
- return string(output.Bytes()), err
+ return output.String(), err
}
var rfc2821Tests = []struct {
diff --git a/libgo/go/crypto/x509/pkcs8.go b/libgo/go/crypto/x509/pkcs8.go
index eb051b6..fb1340c 100644
--- a/libgo/go/crypto/x509/pkcs8.go
+++ b/libgo/go/crypto/x509/pkcs8.go
@@ -56,7 +56,7 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
}
// MarshalPKCS8PrivateKey converts a private key to PKCS#8 encoded form.
-// The following key types are supported: *rsa.PrivateKey, *ecdsa.PublicKey.
+// The following key types are supported: *rsa.PrivateKey, *ecdsa.PrivateKey.
// Unsupported key types result in an error.
//
// See RFC 5208.
diff --git a/libgo/go/crypto/x509/pkix/pkix.go b/libgo/go/crypto/x509/pkix/pkix.go
index 7b32220..3cc4d58 100644
--- a/libgo/go/crypto/x509/pkix/pkix.go
+++ b/libgo/go/crypto/x509/pkix/pkix.go
@@ -95,7 +95,7 @@ func (r RDNSequence) String() string {
type RelativeDistinguishedNameSET []AttributeTypeAndValue
// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
-// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
+// https://tools.ietf.org/html/rfc5280#section-4.1.2.4
type AttributeTypeAndValue struct {
Type asn1.ObjectIdentifier
Value interface{}
diff --git a/libgo/go/crypto/x509/root.go b/libgo/go/crypto/x509/root.go
index 787d955..24029624 100644
--- a/libgo/go/crypto/x509/root.go
+++ b/libgo/go/crypto/x509/root.go
@@ -19,4 +19,7 @@ func systemRootsPool() *CertPool {
func initSystemRoots() {
systemRoots, systemRootsErr = loadSystemRoots()
+ if systemRootsErr != nil {
+ systemRoots = nil
+ }
}
diff --git a/libgo/go/crypto/x509/root_cgo_darwin.go b/libgo/go/crypto/x509/root_cgo_darwin.go
index 80cd250..a02ac3c 100644
--- a/libgo/go/crypto/x509/root_cgo_darwin.go
+++ b/libgo/go/crypto/x509/root_cgo_darwin.go
@@ -7,7 +7,7 @@
package x509
/*
-#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1080
+#cgo CFLAGS: -mmacosx-version-min=10.10 -D__MAC_OS_X_VERSION_MAX_ALLOWED=101300
#cgo LDFLAGS: -framework CoreFoundation -framework Security
#include <errno.h>
@@ -16,59 +16,6 @@ package x509
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
-// FetchPEMRoots_MountainLion is the version of FetchPEMRoots from Go 1.6
-// which still works on OS X 10.8 (Mountain Lion).
-// It lacks support for admin & user cert domains.
-// See golang.org/issue/16473
-int FetchPEMRoots_MountainLion(CFDataRef *pemRoots) {
- if (pemRoots == NULL) {
- return -1;
- }
- CFArrayRef certs = NULL;
- OSStatus err = SecTrustCopyAnchorCertificates(&certs);
- if (err != noErr) {
- 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);
- if (err != noErr) {
- continue;
- }
- if (data != NULL) {
- CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
- CFRelease(data);
- }
- }
- CFRelease(certs);
- *pemRoots = combinedData;
- return 0;
-}
-
-// useOldCode reports whether the running machine is OS X 10.8 Mountain Lion
-// or older. We only support Mountain Lion and higher, but we'll at least try our
-// best on older machines and continue to use the old code path.
-//
-// See golang.org/issue/16473
-int useOldCode() {
- char str[256];
- size_t size = sizeof(str);
- memset(str, 0, size);
- sysctlbyname("kern.osrelease", str, &size, NULL, 0);
- // OS X 10.8 is osrelease "12.*", 10.7 is 11.*, 10.6 is 10.*.
- // We never supported things before that.
- return memcmp(str, "12.", 3) == 0 || memcmp(str, "11.", 3) == 0 || memcmp(str, "10.", 3) == 0;
-}
-
// FetchPEMRoots fetches the system's list of trusted X.509 root certificates.
//
// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
@@ -78,9 +25,7 @@ int useOldCode() {
// Note: The CFDataRef returned in pemRoots and untrustedPemRoots must
// be released (using CFRelease) after we've consumed its content.
int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
- if (useOldCode()) {
- return FetchPEMRoots_MountainLion(pemRoots);
- }
+ int i;
// Get certificates from all domains, not just System, this lets
// the user add CAs to their "login" keychain, and Admins to add
@@ -101,7 +46,8 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
CFMutableDataRef combinedUntrustedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
- for (int i = 0; i < numDomains; i++) {
+ for (i = 0; i < numDomains; i++) {
+ int j;
CFArrayRef certs = NULL;
OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs);
if (err != noErr) {
@@ -109,7 +55,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
}
CFIndex numCerts = CFArrayGetCount(certs);
- for (int j = 0; j < numCerts; j++) {
+ for (j = 0; j < numCerts; j++) {
CFDataRef data = NULL;
CFErrorRef errRef = NULL;
CFArrayRef trustSettings = NULL;
@@ -124,6 +70,9 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
if (i == 0) {
trustAsRoot = 1;
} else {
+ int k;
+ CFIndex m;
+
// Certs found in the system domain are always trusted. If the user
// configures "Never Trust" on such a cert, it will also be found in the
// admin or user domain, causing it to be added to untrustedPemRoots. The
@@ -133,7 +82,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
// SecTrustServer.c, "user trust settings overrule admin trust settings",
// so take the last trust settings array we find.
// Skip the system domain since it is always trusted.
- for (int k = i; k < numDomains; k++) {
+ for (k = i; k < numDomains; k++) {
CFArrayRef domainTrustSettings = NULL;
err = SecTrustSettingsCopyTrustSettings(cert, domains[k], &domainTrustSettings);
if (err == errSecSuccess && domainTrustSettings != NULL) {
@@ -147,9 +96,9 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
// "this certificate must be verified to a known trusted certificate"; aka not a root.
continue;
}
- for (CFIndex k = 0; k < CFArrayGetCount(trustSettings); k++) {
+ for (m = 0; m < CFArrayGetCount(trustSettings); m++) {
CFNumberRef cfNum;
- CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, k);
+ CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m);
if (CFDictionaryGetValueIfPresent(tSetting, policy, (const void**)&cfNum)){
SInt32 result = 0;
CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result);
@@ -187,10 +136,7 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
}
}
- // 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);
+ err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
if (err != noErr) {
continue;
}
diff --git a/libgo/go/crypto/x509/root_darwin.go b/libgo/go/crypto/x509/root_darwin.go
index bc35a1c..9d7b3a6 100644
--- a/libgo/go/crypto/x509/root_darwin.go
+++ b/libgo/go/crypto/x509/root_darwin.go
@@ -181,12 +181,12 @@ func verifyCertWithSystem(block *pem.Block, cert *Certificate) bool {
}
if err := cmd.Run(); err != nil {
if debugExecDarwinRoots {
- println(fmt.Sprintf("crypto/x509: verify-cert rejected %s: %q", cert.Subject.CommonName, bytes.TrimSpace(stderr.Bytes())))
+ println(fmt.Sprintf("crypto/x509: verify-cert rejected %s: %q", cert.Subject, bytes.TrimSpace(stderr.Bytes())))
}
return false
}
if debugExecDarwinRoots {
- println(fmt.Sprintf("crypto/x509: verify-cert approved %s", cert.Subject.CommonName))
+ println(fmt.Sprintf("crypto/x509: verify-cert approved %s", cert.Subject))
}
return true
}
diff --git a/libgo/go/crypto/x509/root_js.go b/libgo/go/crypto/x509/root_js.go
new file mode 100644
index 0000000..70abb73
--- /dev/null
+++ b/libgo/go/crypto/x509/root_js.go
@@ -0,0 +1,10 @@
+// Copyright 2018 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 js,wasm
+
+package x509
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{}
diff --git a/libgo/go/crypto/x509/root_plan9.go b/libgo/go/crypto/x509/root_plan9.go
index ebeb7df..09f0e23 100644
--- a/libgo/go/crypto/x509/root_plan9.go
+++ b/libgo/go/crypto/x509/root_plan9.go
@@ -33,5 +33,8 @@ func loadSystemRoots() (*CertPool, error) {
bestErr = err
}
}
+ if bestErr == nil {
+ return roots, nil
+ }
return nil, bestErr
}
diff --git a/libgo/go/crypto/x509/root_unix.go b/libgo/go/crypto/x509/root_unix.go
index 0547460..48de50b 100644
--- a/libgo/go/crypto/x509/root_unix.go
+++ b/libgo/go/crypto/x509/root_unix.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 aix dragonfly freebsd linux nacl netbsd openbsd solaris
+// +build aix dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris
package x509
@@ -81,7 +81,7 @@ func loadSystemRoots() (*CertPool, error) {
}
}
- if len(roots.certs) > 0 {
+ if len(roots.certs) > 0 || firstErr == nil {
return roots, nil
}
diff --git a/libgo/go/crypto/x509/root_unix_test.go b/libgo/go/crypto/x509/root_unix_test.go
index 03f935d..9e22019 100644
--- a/libgo/go/crypto/x509/root_unix_test.go
+++ b/libgo/go/crypto/x509/root_unix_test.go
@@ -103,10 +103,6 @@ func TestEnvVars(t *testing.T) {
}
if r == nil {
- if tc.cns == nil {
- // Expected nil
- return
- }
t.Fatal("nil roots")
}
diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go
index 3621a93..74d395d 100644
--- a/libgo/go/crypto/x509/root_windows.go
+++ b/libgo/go/crypto/x509/root_windows.go
@@ -95,12 +95,6 @@ func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) e
return nil
}
-type _CertChainPolicyPara struct {
- Size uint32
- Flags uint32
- ExtraPolicyPara unsafe.Pointer
-}
-
// checkChainSSLServerPolicy checks that the certificate chain in chainCtx is valid for
// use as a certificate chain for a SSL/TLS server.
func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) error {
@@ -114,13 +108,13 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex
}
sslPara.Size = uint32(unsafe.Sizeof(*sslPara))
- para := &_CertChainPolicyPara{
- ExtraPolicyPara: unsafe.Pointer(sslPara),
+ para := &syscall.CertChainPolicyPara{
+ ExtraPolicyPara: (syscall.Pointer)(unsafe.Pointer(sslPara)),
}
para.Size = uint32(unsafe.Sizeof(*para))
status := syscall.CertChainPolicyStatus{}
- err = syscall.CertVerifyCertificateChainPolicy(syscall.CERT_CHAIN_POLICY_SSL, chainCtx, (*syscall.CertChainPolicyPara)(unsafe.Pointer(para)), &status)
+ err = syscall.CertVerifyCertificateChainPolicy(syscall.CERT_CHAIN_POLICY_SSL, chainCtx, para, &status)
if err != nil {
return err
}
diff --git a/libgo/go/crypto/x509/sha2_windows_test.go b/libgo/go/crypto/x509/sha2_windows_test.go
deleted file mode 100644
index 79dc685..0000000
--- a/libgo/go/crypto/x509/sha2_windows_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 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 x509
-
-import "syscall"
-
-func init() {
- v, err := syscall.GetVersion()
- if err != nil {
- return
- }
- if major := byte(v); major < 6 {
- // Windows XP SP2 and Windows 2003 do not support SHA2.
- // http://blogs.technet.com/b/pki/archive/2010/09/30/sha2-and-windows.aspx
- supportSHA2 = false
- }
-}
diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go
index 60e415b..210db4c 100644
--- a/libgo/go/crypto/x509/verify.go
+++ b/libgo/go/crypto/x509/verify.go
@@ -6,19 +6,21 @@ package x509
import (
"bytes"
- "encoding/asn1"
"errors"
"fmt"
"net"
"net/url"
+ "os"
"reflect"
"runtime"
- "strconv"
"strings"
"time"
"unicode/utf8"
)
+// ignoreCN disables interpreting Common Name as a hostname. See issue 24151.
+var ignoreCN = strings.Contains(os.Getenv("GODEBUG"), "x509ignoreCN=1")
+
type InvalidReason int
const (
@@ -43,13 +45,18 @@ const (
NameMismatch
// NameConstraintsWithoutSANs results when a leaf certificate doesn't
// contain a Subject Alternative Name extension, but a CA certificate
- // contains name constraints.
+ // contains name constraints, and the Common Name can be interpreted as
+ // a hostname.
+ //
+ // You can avoid this error by setting the experimental GODEBUG environment
+ // variable to "x509ignoreCN=1", disabling Common Name matching entirely.
+ // This behavior might become the default in the future.
NameConstraintsWithoutSANs
// UnconstrainedName results when a CA certificate contains permitted
// name constraints, but leaf certificate contains a name of an
// unsupported or unconstrained type.
UnconstrainedName
- // TooManyConstraints results when the number of comparision operations
+ // TooManyConstraints results when the number of comparison operations
// needed to check a certificate exceeds the limit set by
// VerifyOptions.MaxConstraintComparisions. This limit exists to
// prevent pathological certificates can consuming excessive amounts of
@@ -102,6 +109,12 @@ type HostnameError struct {
func (h HostnameError) Error() string {
c := h.Certificate
+ if !c.hasSANExtension() && !validHostname(c.Subject.CommonName) &&
+ matchHostnames(toLowerCaseASCII(c.Subject.CommonName), toLowerCaseASCII(h.Host)) {
+ // This would have validated, if it weren't for the validHostname check on Common Name.
+ return "x509: Common Name is not a valid hostname: " + c.Subject.CommonName
+ }
+
var valid string
if ip := net.ParseIP(h.Host); ip != nil {
// Trying to validate an IP
@@ -115,10 +128,10 @@ func (h HostnameError) Error() string {
valid += san.String()
}
} else {
- if c.hasSANExtension() {
- valid = strings.Join(c.DNSNames, ", ")
- } else {
+ if c.commonNameAsHostname() {
valid = c.Subject.CommonName
+ } else {
+ valid = strings.Join(c.DNSNames, ", ")
}
}
@@ -189,7 +202,7 @@ type VerifyOptions struct {
KeyUsages []ExtKeyUsage
// MaxConstraintComparisions is the maximum number of comparisons to
// perform when checking a given certificate's name constraints. If
- // zero, a sensible default is used. This limit prevents pathalogical
+ // zero, a sensible default is used. This limit prevents pathological
// certificates from consuming excessive amounts of CPU time when
// validating.
MaxConstraintComparisions int
@@ -583,17 +596,16 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
leaf = currentChain[0]
}
- if (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() {
- sanExtension, ok := leaf.getSANExtension()
- if !ok {
- // This is the deprecated, legacy case of depending on
- // the CN as a hostname. Chains modern enough to be
- // using name constraints should not be depending on
- // CNs.
- return CertificateInvalidError{c, NameConstraintsWithoutSANs, ""}
- }
-
- err := forEachSAN(sanExtension, func(tag int, data []byte) error {
+ checkNameConstraints := (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints()
+ if checkNameConstraints && leaf.commonNameAsHostname() {
+ // This is the deprecated, legacy case of depending on the commonName as
+ // a hostname. We don't enforce name constraints against the CN, but
+ // VerifyHostname will look for hostnames in there if there are no SANs.
+ // In order to ensure VerifyHostname will not accept an unchecked name,
+ // return an error here.
+ return CertificateInvalidError{c, NameConstraintsWithoutSANs, ""}
+ } else if checkNameConstraints && leaf.hasSANExtension() {
+ err := forEachSAN(leaf.getSANExtension(), func(tag int, data []byte) error {
switch tag {
case nameTypeEmail:
name := string(data)
@@ -692,18 +704,6 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return nil
}
-// formatOID formats an ASN.1 OBJECT IDENTIFER in the common, dotted style.
-func formatOID(oid asn1.ObjectIdentifier) string {
- ret := ""
- for i, v := range oid {
- if i > 0 {
- ret += "."
- }
- ret += strconv.Itoa(v)
- }
- return ret
-}
-
// Verify attempts to verify c by building one or more chains from c to a
// certificate in opts.Roots, using certificates in opts.Intermediates if
// needed. If successful, it returns one or more chains where the first
@@ -860,6 +860,64 @@ nextIntermediate:
return
}
+// validHostname returns whether host is a valid hostname that can be matched or
+// matched against according to RFC 6125 2.2, with some leniency to accomodate
+// legacy values.
+func validHostname(host string) bool {
+ host = strings.TrimSuffix(host, ".")
+
+ if len(host) == 0 {
+ return false
+ }
+
+ for i, part := range strings.Split(host, ".") {
+ if part == "" {
+ // Empty label.
+ return false
+ }
+ if i == 0 && part == "*" {
+ // Only allow full left-most wildcards, as those are the only ones
+ // we match, and matching literal '*' characters is probably never
+ // the expected behavior.
+ continue
+ }
+ for j, c := range part {
+ if 'a' <= c && c <= 'z' {
+ continue
+ }
+ if '0' <= c && c <= '9' {
+ continue
+ }
+ if 'A' <= c && c <= 'Z' {
+ continue
+ }
+ if c == '-' && j != 0 {
+ continue
+ }
+ if c == '_' {
+ // _ is not a valid character in hostnames, but it's commonly
+ // found in deployments outside the WebPKI.
+ continue
+ }
+ return false
+ }
+ }
+
+ return true
+}
+
+// commonNameAsHostname reports whether the Common Name field should be
+// considered the hostname that the certificate is valid for. This is a legacy
+// behavior, disabled if the Subject Alt Name extension is present.
+//
+// It applies the strict validHostname check to the Common Name field, so that
+// certificates without SANs can still be validated against CAs with name
+// constraints if there is no risk the CN would be matched as a hostname.
+// See NameConstraintsWithoutSANs and issue 24151.
+func (c *Certificate) commonNameAsHostname() bool {
+ return !ignoreCN && !c.hasSANExtension() && validHostname(c.Subject.CommonName)
+}
+
func matchHostnames(pattern, host string) bool {
host = strings.TrimSuffix(host, ".")
pattern = strings.TrimSuffix(pattern, ".")
@@ -940,15 +998,16 @@ func (c *Certificate) VerifyHostname(h string) error {
lowered := toLowerCaseASCII(h)
- if c.hasSANExtension() {
+ if c.commonNameAsHostname() {
+ if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
+ return nil
+ }
+ } else {
for _, match := range c.DNSNames {
if matchHostnames(toLowerCaseASCII(match), lowered) {
return nil
}
}
- // If Subject Alt Name is given, we ignore the common name.
- } else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
- return nil
}
return HostnameError{c, h}
diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go
index bd3df47..7684145 100644
--- a/libgo/go/crypto/x509/verify_test.go
+++ b/libgo/go/crypto/x509/verify_test.go
@@ -15,8 +15,6 @@ import (
"time"
)
-var supportSHA2 = true
-
type verifyTest struct {
leaf string
intermediates []string
@@ -27,6 +25,7 @@ type verifyTest struct {
keyUsages []ExtKeyUsage
testSystemRootsError bool
sha2 bool
+ ignoreCN bool
errorCallback func(*testing.T, int, error) bool
expectedChains [][]string
@@ -73,7 +72,16 @@ var verifyTests = []verifyTest{
currentTime: 1395785200,
dnsName: "www.example.com",
- errorCallback: expectHostnameError,
+ errorCallback: expectHostnameError("certificate is valid for"),
+ },
+ {
+ leaf: googleLeaf,
+ intermediates: []string{giag2Intermediate},
+ roots: []string{geoTrustRoot},
+ currentTime: 1395785200,
+ dnsName: "1.2.3.4",
+
+ errorCallback: expectHostnameError("doesn't contain any IP SANs"),
},
{
leaf: googleLeaf,
@@ -250,7 +258,7 @@ var verifyTests = []verifyTest{
dnsName: "notfoo.example",
systemSkip: true,
- errorCallback: expectHostnameError,
+ errorCallback: expectHostnameError("certificate is valid for"),
},
{
// The issuer name in the leaf doesn't exactly match the
@@ -283,7 +291,7 @@ var verifyTests = []verifyTest{
currentTime: 1486684488,
systemSkip: true,
- errorCallback: expectHostnameError,
+ errorCallback: expectHostnameError("certificate is not valid for any names"),
},
{
// Test that excluded names are respected.
@@ -320,19 +328,77 @@ var verifyTests = []verifyTest{
errorCallback: expectUnhandledCriticalExtension,
},
+ {
+ // Test that invalid CN are ignored.
+ leaf: invalidCNWithoutSAN,
+ dnsName: "foo,invalid",
+ roots: []string{invalidCNRoot},
+ currentTime: 1540000000,
+ systemSkip: true,
+
+ errorCallback: expectHostnameError("Common Name is not a valid hostname"),
+ },
+ {
+ // Test that valid CN are respected.
+ leaf: validCNWithoutSAN,
+ dnsName: "foo.example.com",
+ roots: []string{invalidCNRoot},
+ currentTime: 1540000000,
+ systemSkip: true,
+
+ expectedChains: [][]string{
+ {"foo.example.com", "Test root"},
+ },
+ },
+ // Replicate CN tests with ignoreCN = true
+ {
+ leaf: ignoreCNWithSANLeaf,
+ dnsName: "foo.example.com",
+ roots: []string{ignoreCNWithSANRoot},
+ currentTime: 1486684488,
+ systemSkip: true,
+ ignoreCN: true,
+
+ errorCallback: expectHostnameError("certificate is not valid for any names"),
+ },
+ {
+ leaf: invalidCNWithoutSAN,
+ dnsName: "foo,invalid",
+ roots: []string{invalidCNRoot},
+ currentTime: 1540000000,
+ systemSkip: true,
+ ignoreCN: true,
+
+ errorCallback: expectHostnameError("Common Name is not a valid hostname"),
+ },
+ {
+ leaf: validCNWithoutSAN,
+ dnsName: "foo.example.com",
+ roots: []string{invalidCNRoot},
+ currentTime: 1540000000,
+ systemSkip: true,
+ ignoreCN: true,
+
+ errorCallback: expectHostnameError("not valid for any names"),
+ },
}
-func expectHostnameError(t *testing.T, i int, err error) (ok bool) {
- if _, ok := err.(HostnameError); !ok {
- t.Errorf("#%d: error was not a HostnameError: %s", i, err)
- return false
+func expectHostnameError(msg string) func(*testing.T, int, error) bool {
+ return func(t *testing.T, i int, err error) (ok bool) {
+ if _, ok := err.(HostnameError); !ok {
+ t.Errorf("#%d: error was not a HostnameError: %v", i, err)
+ return false
+ }
+ if !strings.Contains(err.Error(), msg) {
+ t.Errorf("#%d: HostnameError did not contain %q: %v", i, msg, err)
+ }
+ return true
}
- return true
}
func expectExpired(t *testing.T, i int, err error) (ok bool) {
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != Expired {
- t.Errorf("#%d: error was not Expired: %s", i, err)
+ t.Errorf("#%d: error was not Expired: %v", i, err)
return false
}
return true
@@ -340,7 +406,7 @@ func expectExpired(t *testing.T, i int, err error) (ok bool) {
func expectUsageError(t *testing.T, i int, err error) (ok bool) {
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != IncompatibleUsage {
- t.Errorf("#%d: error was not IncompatibleUsage: %s", i, err)
+ t.Errorf("#%d: error was not IncompatibleUsage: %v", i, err)
return false
}
return true
@@ -349,11 +415,11 @@ func expectUsageError(t *testing.T, i int, err error) (ok bool) {
func expectAuthorityUnknown(t *testing.T, i int, err error) (ok bool) {
e, ok := err.(UnknownAuthorityError)
if !ok {
- t.Errorf("#%d: error was not UnknownAuthorityError: %s", i, err)
+ t.Errorf("#%d: error was not UnknownAuthorityError: %v", i, err)
return false
}
if e.Cert == nil {
- t.Errorf("#%d: error was UnknownAuthorityError, but missing Cert: %s", i, err)
+ t.Errorf("#%d: error was UnknownAuthorityError, but missing Cert: %v", i, err)
return false
}
return true
@@ -361,7 +427,7 @@ func expectAuthorityUnknown(t *testing.T, i int, err error) (ok bool) {
func expectSystemRootsError(t *testing.T, i int, err error) bool {
if _, ok := err.(SystemRootsError); !ok {
- t.Errorf("#%d: error was not SystemRootsError: %s", i, err)
+ t.Errorf("#%d: error was not SystemRootsError: %v", i, err)
return false
}
return true
@@ -373,7 +439,7 @@ func expectHashError(t *testing.T, i int, err error) bool {
return false
}
if expected := "algorithm unimplemented"; !strings.Contains(err.Error(), expected) {
- t.Errorf("#%d: error resulting from invalid hash didn't contain '%s', rather it was: %s", i, expected, err)
+ t.Errorf("#%d: error resulting from invalid hash didn't contain '%s', rather it was: %v", i, expected, err)
return false
}
return true
@@ -381,7 +447,7 @@ func expectHashError(t *testing.T, i int, err error) bool {
func expectSubjectIssuerMismatcthError(t *testing.T, i int, err error) (ok bool) {
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NameMismatch {
- t.Errorf("#%d: error was not a NameMismatch: %s", i, err)
+ t.Errorf("#%d: error was not a NameMismatch: %v", i, err)
return false
}
return true
@@ -389,7 +455,7 @@ func expectSubjectIssuerMismatcthError(t *testing.T, i int, err error) (ok bool)
func expectNameConstraintsError(t *testing.T, i int, err error) (ok bool) {
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != CANotAuthorizedForThisName {
- t.Errorf("#%d: error was not a CANotAuthorizedForThisName: %s", i, err)
+ t.Errorf("#%d: error was not a CANotAuthorizedForThisName: %v", i, err)
return false
}
return true
@@ -397,7 +463,7 @@ func expectNameConstraintsError(t *testing.T, i int, err error) (ok bool) {
func expectNotAuthorizedError(t *testing.T, i int, err error) (ok bool) {
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NotAuthorizedToSign {
- t.Errorf("#%d: error was not a NotAuthorizedToSign: %s", i, err)
+ t.Errorf("#%d: error was not a NotAuthorizedToSign: %v", i, err)
return false
}
return true
@@ -405,7 +471,7 @@ func expectNotAuthorizedError(t *testing.T, i int, err error) (ok bool) {
func expectUnhandledCriticalExtension(t *testing.T, i int, err error) (ok bool) {
if _, ok := err.(UnhandledCriticalExtension); !ok {
- t.Errorf("#%d: error was not an UnhandledCriticalExtension: %s", i, err)
+ t.Errorf("#%d: error was not an UnhandledCriticalExtension: %v", i, err)
return false
}
return true
@@ -420,6 +486,9 @@ func certificateFromPEM(pemBytes string) (*Certificate, error) {
}
func testVerify(t *testing.T, useSystemRoots bool) {
+ defer func(savedIgnoreCN bool) {
+ ignoreCN = savedIgnoreCN
+ }(ignoreCN)
for i, test := range verifyTests {
if useSystemRoots && test.systemSkip {
continue
@@ -427,10 +496,8 @@ func testVerify(t *testing.T, useSystemRoots bool) {
if runtime.GOOS == "windows" && test.testSystemRootsError {
continue
}
- if useSystemRoots && !supportSHA2 && test.sha2 {
- continue
- }
+ ignoreCN = test.ignoreCN
opts := VerifyOptions{
Intermediates: NewCertPool(),
DNSName: test.dnsName,
@@ -459,7 +526,7 @@ func testVerify(t *testing.T, useSystemRoots bool) {
leaf, err := certificateFromPEM(test.leaf)
if err != nil {
- t.Errorf("#%d: failed to parse leaf: %s", i, err)
+ t.Errorf("#%d: failed to parse leaf: %v", i, err)
return
}
@@ -477,7 +544,7 @@ func testVerify(t *testing.T, useSystemRoots bool) {
}
if test.errorCallback == nil && err != nil {
- t.Errorf("#%d: unexpected error: %s", i, err)
+ t.Errorf("#%d: unexpected error: %v", i, err)
}
if test.errorCallback != nil {
if !test.errorCallback(t, i, err) {
@@ -1518,6 +1585,95 @@ yU1yRHUqUYpN0DWFpsPbBqgM6uUAVO2ayBFhPgWUaqkmSbZ/Nq7isGvknaTmcIwT
+NQCZDd5eFeU8PpNX7rgaYE4GPq+EEmLVCBYmdctr8QVdqJ//8Xu3+1phjDy
-----END CERTIFICATE-----`
+const invalidCNRoot = `
+-----BEGIN CERTIFICATE-----
+MIIBFjCBvgIJAIsu4r+jb70UMAoGCCqGSM49BAMCMBQxEjAQBgNVBAsMCVRlc3Qg
+cm9vdDAeFw0xODA3MTExODMyMzVaFw0yODA3MDgxODMyMzVaMBQxEjAQBgNVBAsM
+CVRlc3Qgcm9vdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABF6oDgMg0LV6YhPj
+QXaPXYCc2cIyCdqp0ROUksRz0pOLTc5iY2nraUheRUD1vRRneq7GeXOVNn7uXONg
+oCGMjNwwCgYIKoZIzj0EAwIDRwAwRAIgDSiwgIn8g1lpruYH0QD1GYeoWVunfmrI
+XzZZl0eW/ugCICgOfXeZ2GGy3wIC0352BaC3a8r5AAb2XSGNe+e9wNN6
+-----END CERTIFICATE-----
+`
+
+const invalidCNWithoutSAN = `
+Certificate:
+ Data:
+ Version: 1 (0x0)
+ Serial Number:
+ 07:ba:bc:b7:d9:ab:0c:02:fe:50:1d:4e:15:a3:0d:e4:11:16:14:a2
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: OU = Test root
+ Validity
+ Not Before: Jul 11 18:35:21 2018 GMT
+ Not After : Jul 8 18:35:21 2028 GMT
+ Subject: CN = "foo,invalid"
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:a7:a6:7c:22:33:a7:47:7f:08:93:2d:5f:61:35:
+ 2e:da:45:67:76:f2:97:73:18:b0:01:12:4a:1a:d5:
+ b7:6f:41:3c:bb:05:69:f4:06:5d:ff:eb:2b:a7:85:
+ 0b:4c:f7:45:4e:81:40:7a:a9:c6:1d:bb:ba:d9:b9:
+ 26:b3:ca:50:90
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:45:02:21:00:85:96:75:b6:72:3c:67:12:a0:7f:86:04:81:
+ d2:dd:c8:67:50:d7:5f:85:c0:54:54:fc:e6:6b:45:08:93:d3:
+ 2a:02:20:60:86:3e:d6:28:a6:4e:da:dd:6e:95:89:cc:00:76:
+ 78:1c:03:80:85:a6:5a:0b:eb:c5:f3:9c:2e:df:ef:6e:fa
+-----BEGIN CERTIFICATE-----
+MIIBJDCBywIUB7q8t9mrDAL+UB1OFaMN5BEWFKIwCgYIKoZIzj0EAwIwFDESMBAG
+A1UECwwJVGVzdCByb290MB4XDTE4MDcxMTE4MzUyMVoXDTI4MDcwODE4MzUyMVow
+FjEUMBIGA1UEAwwLZm9vLGludmFsaWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AASnpnwiM6dHfwiTLV9hNS7aRWd28pdzGLABEkoa1bdvQTy7BWn0Bl3/6yunhQtM
+90VOgUB6qcYdu7rZuSazylCQMAoGCCqGSM49BAMCA0gAMEUCIQCFlnW2cjxnEqB/
+hgSB0t3IZ1DXX4XAVFT85mtFCJPTKgIgYIY+1iimTtrdbpWJzAB2eBwDgIWmWgvr
+xfOcLt/vbvo=
+-----END CERTIFICATE-----
+`
+
+const validCNWithoutSAN = `
+Certificate:
+ Data:
+ Version: 1 (0x0)
+ Serial Number:
+ 07:ba:bc:b7:d9:ab:0c:02:fe:50:1d:4e:15:a3:0d:e4:11:16:14:a4
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: OU = Test root
+ Validity
+ Not Before: Jul 11 18:47:24 2018 GMT
+ Not After : Jul 8 18:47:24 2028 GMT
+ Subject: CN = foo.example.com
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:a7:a6:7c:22:33:a7:47:7f:08:93:2d:5f:61:35:
+ 2e:da:45:67:76:f2:97:73:18:b0:01:12:4a:1a:d5:
+ b7:6f:41:3c:bb:05:69:f4:06:5d:ff:eb:2b:a7:85:
+ 0b:4c:f7:45:4e:81:40:7a:a9:c6:1d:bb:ba:d9:b9:
+ 26:b3:ca:50:90
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:44:02:20:53:6c:d7:b7:59:61:51:72:a5:18:a3:4b:0d:52:
+ ea:15:fa:d0:93:30:32:54:4b:ed:0f:58:85:b8:a8:1a:82:3b:
+ 02:20:14:77:4b:0e:7e:4f:0a:4f:64:26:97:dc:d0:ed:aa:67:
+ 1d:37:85:da:b4:87:ba:25:1c:2a:58:f7:23:11:8b:3d
+-----BEGIN CERTIFICATE-----
+MIIBJzCBzwIUB7q8t9mrDAL+UB1OFaMN5BEWFKQwCgYIKoZIzj0EAwIwFDESMBAG
+A1UECwwJVGVzdCByb290MB4XDTE4MDcxMTE4NDcyNFoXDTI4MDcwODE4NDcyNFow
+GjEYMBYGA1UEAwwPZm9vLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
+AQcDQgAEp6Z8IjOnR38Iky1fYTUu2kVndvKXcxiwARJKGtW3b0E8uwVp9AZd/+sr
+p4ULTPdFToFAeqnGHbu62bkms8pQkDAKBggqhkjOPQQDAgNHADBEAiBTbNe3WWFR
+cqUYo0sNUuoV+tCTMDJUS+0PWIW4qBqCOwIgFHdLDn5PCk9kJpfc0O2qZx03hdq0
+h7olHCpY9yMRiz0=
+-----END CERTIFICATE-----
+`
+
var unknownAuthorityErrorTests = []struct {
cert string
expected string
@@ -1535,7 +1691,7 @@ func TestUnknownAuthorityError(t *testing.T) {
}
c, err := ParseCertificate(der.Bytes)
if err != nil {
- t.Errorf("#%d: Unable to parse certificate -> %s", i, err)
+ t.Errorf("#%d: Unable to parse certificate -> %v", i, err)
}
uae := &UnknownAuthorityError{
Cert: c,
@@ -1707,3 +1863,28 @@ UNhY4JhezH9gQYqvDMWrWDAbBgNVHSMEFDASgBArF29S5Bnqw7de8GzGA1nfMAoG
CCqGSM49BAMCA0gAMEUCIQClA3d4tdrDu9Eb5ZBpgyC+fU1xTZB0dKQHz6M5fPZA
2AIgN96lM+CPGicwhN24uQI6flOsO3H0TJ5lNzBYLtnQtlc=
-----END CERTIFICATE-----`
+
+func TestValidHostname(t *testing.T) {
+ tests := []struct {
+ host string
+ want bool
+ }{
+ {"example.com", true},
+ {"eXample123-.com", true},
+ {"-eXample123-.com", false},
+ {"", false},
+ {".", false},
+ {"example..com", false},
+ {".example.com", false},
+ {"*.example.com", true},
+ {"*foo.example.com", false},
+ {"foo.*.example.com", false},
+ {"exa_mple.com", true},
+ {"foo,bar", false},
+ }
+ for _, tt := range tests {
+ if got := validHostname(tt.host); got != tt.want {
+ t.Errorf("validHostname(%q) = %v, want %v", tt.host, got, tt.want)
+ }
+ }
+}
diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go
index ee08dd9..2e72471 100644
--- a/libgo/go/crypto/x509/x509.go
+++ b/libgo/go/crypto/x509/x509.go
@@ -420,10 +420,10 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm
// https://tools.ietf.org/html/rfc3447#section-8.1), that the
// salt length matches the hash length, and that the trailer
// field has the default value.
- if !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes) ||
+ if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
!params.MGF.Algorithm.Equal(oidMGF1) ||
!mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
- !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes) ||
+ (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
params.TrailerField != 1 {
return UnknownSignatureAlgorithm
}
@@ -843,23 +843,16 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature
}
func (c *Certificate) hasNameConstraints() bool {
- for _, e := range c.Extensions {
- if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 && e.Id[3] == 30 {
- return true
- }
- }
-
- return false
+ return oidInExtensions(oidExtensionNameConstraints, c.Extensions)
}
-func (c *Certificate) getSANExtension() ([]byte, bool) {
+func (c *Certificate) getSANExtension() []byte {
for _, e := range c.Extensions {
- if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 && e.Id[3] == 17 {
- return e.Value, true
+ if e.Id.Equal(oidExtensionSubjectAltName) {
+ return e.Value
}
}
-
- return nil, false
+ return nil
}
func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm, pubKey interface{}) error {
@@ -1056,7 +1049,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
namedCurveOID := new(asn1.ObjectIdentifier)
rest, err := asn1.Unmarshal(paramsData, namedCurveOID)
if err != nil {
- return nil, err
+ return nil, errors.New("x509: failed to parse ECDSA parameters as named curve")
}
if len(rest) != 0 {
return nil, errors.New("x509: trailing data after ECDSA parameters")
@@ -1952,7 +1945,8 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId
}
// Adding another extension here? Remember to update the maximum number
- // of elements in the make() at the top of the function.
+ // of elements in the make() at the top of the function and the list of
+ // template fields used in CreateCertificate documentation.
return append(ret[:n], template.ExtraExtensions...), nil
}
@@ -2039,11 +2033,39 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori
var emptyASN1Subject = []byte{0x30, 0}
// CreateCertificate creates a new X.509v3 certificate based on a template.
-// The following members of template are used: AuthorityKeyId,
-// BasicConstraintsValid, DNSNames, ExcludedDNSDomains, ExtKeyUsage,
-// IsCA, KeyUsage, MaxPathLen, MaxPathLenZero, NotAfter, NotBefore,
-// PermittedDNSDomains, PermittedDNSDomainsCritical, SerialNumber,
-// SignatureAlgorithm, Subject, SubjectKeyId, and UnknownExtKeyUsage.
+// The following members of template are used:
+//
+// - AuthorityKeyId
+// - BasicConstraintsValid
+// - CRLDistributionPoints
+// - DNSNames
+// - EmailAddresses
+// - ExcludedDNSDomains
+// - ExcludedEmailAddresses
+// - ExcludedIPRanges
+// - ExcludedURIDomains
+// - ExtKeyUsage
+// - ExtraExtensions
+// - IsCA
+// - IssuingCertificateURL
+// - KeyUsage
+// - MaxPathLen
+// - MaxPathLenZero
+// - NotAfter
+// - NotBefore
+// - OCSPServer
+// - PermittedDNSDomains
+// - PermittedDNSDomainsCritical
+// - PermittedEmailAddresses
+// - PermittedIPRanges
+// - PermittedURIDomains
+// - PolicyIdentifiers
+// - SerialNumber
+// - SignatureAlgorithm
+// - Subject
+// - SubjectKeyId
+// - URIs
+// - UnknownExtKeyUsage
//
// The certificate is signed by parent. If parent is equal to template then the
// certificate is self-signed. The parameter pub is the public key of the
@@ -2317,7 +2339,7 @@ func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn1.RawVal
return rawAttributes, nil
}
-// parseRawAttributes Unmarshals RawAttributes intos AttributeTypeAndValueSETs.
+// parseRawAttributes Unmarshals RawAttributes into AttributeTypeAndValueSETs.
func parseRawAttributes(rawAttributes []asn1.RawValue) []pkix.AttributeTypeAndValueSET {
var attributes []pkix.AttributeTypeAndValueSET
for _, rawAttr := range rawAttributes {
@@ -2365,9 +2387,18 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error)
}
// CreateCertificateRequest creates a new certificate request based on a
-// template. The following members of template are used: Attributes, DNSNames,
-// EmailAddresses, ExtraExtensions, IPAddresses, URIs, SignatureAlgorithm, and
-// Subject. The private key is the private key of the signer.
+// template. The following members of template are used:
+//
+// - Attributes
+// - DNSNames
+// - EmailAddresses
+// - ExtraExtensions
+// - IPAddresses
+// - URIs
+// - SignatureAlgorithm
+// - Subject
+//
+// The private key is the private key of the signer.
//
// The returned slice is the certificate request in DER encoding.
//
@@ -2410,77 +2441,96 @@ func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv
extensions = append(extensions, template.ExtraExtensions...)
- var attributes []pkix.AttributeTypeAndValueSET
- attributes = append(attributes, template.Attributes...)
+ // Make a copy of template.Attributes because we may alter it below.
+ attributes := make([]pkix.AttributeTypeAndValueSET, 0, len(template.Attributes))
+ for _, attr := range template.Attributes {
+ values := make([][]pkix.AttributeTypeAndValue, len(attr.Value))
+ copy(values, attr.Value)
+ attributes = append(attributes, pkix.AttributeTypeAndValueSET{
+ Type: attr.Type,
+ Value: values,
+ })
+ }
+ extensionsAppended := false
if len(extensions) > 0 {
- // specifiedExtensions contains all the extensions that we
- // found specified via template.Attributes.
- specifiedExtensions := make(map[string]bool)
-
- for _, atvSet := range template.Attributes {
- if !atvSet.Type.Equal(oidExtensionRequest) {
+ // Append the extensions to an existing attribute if possible.
+ for _, atvSet := range attributes {
+ if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
continue
}
+ // specifiedExtensions contains all the extensions that we
+ // found specified via template.Attributes.
+ specifiedExtensions := make(map[string]bool)
+
for _, atvs := range atvSet.Value {
for _, atv := range atvs {
specifiedExtensions[atv.Type.String()] = true
}
}
- }
- atvs := make([]pkix.AttributeTypeAndValue, 0, len(extensions))
- for _, e := range extensions {
- if specifiedExtensions[e.Id.String()] {
- // Attributes already contained a value for
- // this extension and it takes priority.
- continue
- }
+ newValue := make([]pkix.AttributeTypeAndValue, 0, len(atvSet.Value[0])+len(extensions))
+ newValue = append(newValue, atvSet.Value[0]...)
- atvs = append(atvs, pkix.AttributeTypeAndValue{
- // There is no place for the critical flag in a CSR.
- Type: e.Id,
- Value: e.Value,
- })
- }
+ for _, e := range extensions {
+ if specifiedExtensions[e.Id.String()] {
+ // Attributes already contained a value for
+ // this extension and it takes priority.
+ continue
+ }
- // Append the extensions to an existing attribute if possible.
- appended := false
- for _, atvSet := range attributes {
- if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
- continue
+ newValue = append(newValue, pkix.AttributeTypeAndValue{
+ // There is no place for the critical
+ // flag in an AttributeTypeAndValue.
+ Type: e.Id,
+ Value: e.Value,
+ })
}
- atvSet.Value[0] = append(atvSet.Value[0], atvs...)
- appended = true
+ atvSet.Value[0] = newValue
+ extensionsAppended = true
break
}
+ }
- // Otherwise, add a new attribute for the extensions.
- if !appended {
- attributes = append(attributes, pkix.AttributeTypeAndValueSET{
- Type: oidExtensionRequest,
- Value: [][]pkix.AttributeTypeAndValue{
- atvs,
- },
- })
+ rawAttributes, err := newRawAttributes(attributes)
+ if err != nil {
+ return
+ }
+
+ // If not included in attributes, add a new attribute for the
+ // extensions.
+ if len(extensions) > 0 && !extensionsAppended {
+ attr := struct {
+ Type asn1.ObjectIdentifier
+ Value [][]pkix.Extension `asn1:"set"`
+ }{
+ Type: oidExtensionRequest,
+ Value: [][]pkix.Extension{extensions},
}
+
+ b, err := asn1.Marshal(attr)
+ if err != nil {
+ return nil, errors.New("x509: failed to serialise extensions attribute: " + err.Error())
+ }
+
+ var rawValue asn1.RawValue
+ if _, err := asn1.Unmarshal(b, &rawValue); err != nil {
+ return nil, err
+ }
+
+ rawAttributes = append(rawAttributes, rawValue)
}
asn1Subject := template.RawSubject
if len(asn1Subject) == 0 {
asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
if err != nil {
- return
+ return nil, err
}
}
- rawAttributes, err := newRawAttributes(attributes)
- if err != nil {
- return
- }
-
tbsCSR := tbsCertificateRequest{
Version: 0, // PKCS #10, RFC 2986
Subject: asn1.RawValue{FullBytes: asn1Subject},
diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go
index 7d75727..388156e 100644
--- a/libgo/go/crypto/x509/x509_test.go
+++ b/libgo/go/crypto/x509/x509_test.go
@@ -551,7 +551,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
UnknownExtKeyUsage: testUnknownExtKeyUsage,
BasicConstraintsValid: true,
- IsCA: true,
+ IsCA: true,
OCSPServer: []string{"http://ocsp.example.com"},
IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
@@ -946,19 +946,52 @@ qsGZWxzFvvkXUkQSl0dQQ5jO/FtUJcAVXVVp20LxPemfatAHpW31WdJYeWSQWky2
+f9b5TXKXVyjlUL7uHxowWrT2AtTchDH22wTEtqLEF9Z3Q==
-----END CERTIFICATE-----`
+// openssl req -newkey rsa:2048 -keyout test.key -sha256 -sigopt \
+// rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -sigopt rsa_mgf1_md:sha256 \
+// -x509 -days 3650 -nodes -subj '/C=US/ST=CA/L=SF/O=Test/CN=Test' -out \
+// test.pem
+var rsaPSSSelfSignedOpenSSL110PEM = `-----BEGIN CERTIFICATE-----
+MIIDwDCCAnigAwIBAgIJAM9LAMHTE5xpMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZI
+AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgMEUxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCU0YxDTALBgNVBAoMBFRlc3Qx
+DTALBgNVBAMMBFRlc3QwHhcNMTgwMjIyMjIxMzE4WhcNMjgwMjIwMjIxMzE4WjBF
+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMQ0wCwYDVQQK
+DARUZXN0MQ0wCwYDVQQDDARUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA4Zrsydod+GoTAJLLutWNF87qhhVPBsK1zB1Gj+NAAe4+VbrZ1E41H1wp
+qITx7DA8DRtJEf+NqrTAnAdZWBG/tAOA5LfXVax0ZSQtLnYLSeylLoMtDyY3eFAj
+TmuTOoyVy6raktowCnHCh01NsstqqTfrx6SbmzOmDmKTkq/I+7K0MCVsn41xRDVM
++ShD0WGFGioEGoiWnFSWupxJDA3Q6jIDEygVwNKHwnhv/2NgG2kqZzrZSQA67en0
+iKAXtoDNPpmyD5oS9YbEJ+2Nbm7oLeON30i6kZvXKIzJXx+UWViazHZqnsi5rQ8G
+RHF+iVFXsqd0MzDKmkKOT5FDhrsbKQIDAQABo1MwUTAdBgNVHQ4EFgQU9uFY/nlg
+gLH00NBnr/o7QvpN9ugwHwYDVR0jBBgwFoAU9uFY/nlggLH00NBnr/o7QvpN9ugw
+DwYDVR0TAQH/BAUwAwEB/zA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEa
+MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiAwIBIAOCAQEAhJzpwxBNGKvzKWDe
+WLqv6RMrl/q4GcH3b7M9wjxe0yOm4F+Tb2zJ7re4h+D39YkJf8cX1NV9UQVu6z4s
+Fvo2kmlR0qZOXAg5augmCQ1xS0WHFoF6B52anNzHkZQbAIYJ3kGoFsUHzs7Sz7F/
+656FsRpHA9UzJQ3avPPMrA4Y4aoJ7ANJ6XIwTrdWrhULOVuvYRLCl4CdTVztVFX6
+wxX8nS1ISYd8jXPUMgsBKVbWufvLoIymMJW8CZbpprVZel5zFn0bmPrON8IHS30w
+Gs+ITJjKEnZgXmAQ25SLKVzkZkBcGANs2GsdHNJ370Puisy0FIPD2NXR5uASAf7J
++w9fjQ==
+-----END CERTIFICATE-----`
+
func TestRSAPSSSelfSigned(t *testing.T) {
- der, _ := pem.Decode([]byte(rsaPSSSelfSignedPEM))
- if der == nil {
- t.Fatal("Failed to find PEM block")
- }
+ for i, pemBlock := range []string{rsaPSSSelfSignedPEM, rsaPSSSelfSignedOpenSSL110PEM} {
+ der, _ := pem.Decode([]byte(pemBlock))
+ if der == nil {
+ t.Errorf("#%d: failed to find PEM block", i)
+ continue
+ }
- cert, err := ParseCertificate(der.Bytes)
- if err != nil {
- t.Fatal(err)
- }
+ cert, err := ParseCertificate(der.Bytes)
+ if err != nil {
+ t.Errorf("#%d: failed to parse: %s", i, err)
+ continue
+ }
- if err = cert.CheckSignatureFrom(cert); err != nil {
- t.Fatal(err)
+ if err = cert.CheckSignatureFrom(cert); err != nil {
+ t.Errorf("#%d: signature check failed: %s", i, err)
+ continue
+ }
}
}
@@ -1207,8 +1240,9 @@ func TestCertificateRequestOverrides(t *testing.T) {
// template.
ExtraExtensions: []pkix.Extension{
{
- Id: oidExtensionSubjectAltName,
- Value: sanContents,
+ Id: oidExtensionSubjectAltName,
+ Value: sanContents,
+ Critical: true,
},
},
}
@@ -1219,6 +1253,10 @@ func TestCertificateRequestOverrides(t *testing.T) {
t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames)
}
+ if len(csr.Extensions) != 1 || !csr.Extensions[0].Id.Equal(oidExtensionSubjectAltName) || !csr.Extensions[0].Critical {
+ t.Errorf("SAN extension was not faithfully copied, got %#v", csr.Extensions)
+ }
+
// If there is already an attribute with X.509 extensions then the
// extra extensions should be added to it rather than creating a CSR
// with two extension attributes.
@@ -1361,7 +1399,7 @@ func TestMaxPathLen(t *testing.T) {
NotAfter: time.Unix(100000, 0),
BasicConstraintsValid: true,
- IsCA: true,
+ IsCA: true,
}
cert1 := serialiseAndParse(t, template)
@@ -1402,8 +1440,8 @@ func TestNoAuthorityKeyIdInSelfSignedCert(t *testing.T) {
NotAfter: time.Unix(100000, 0),
BasicConstraintsValid: true,
- IsCA: true,
- SubjectKeyId: []byte{1, 2, 3, 4},
+ IsCA: true,
+ SubjectKeyId: []byte{1, 2, 3, 4},
}
if cert := serialiseAndParse(t, template); len(cert.AuthorityKeyId) != 0 {
@@ -1618,10 +1656,43 @@ func TestSystemCertPool(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("not implemented on Windows; Issue 16736, 18609")
}
- _, err := SystemCertPool()
+ a, err := SystemCertPool()
if err != nil {
t.Fatal(err)
}
+ b, err := SystemCertPool()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(a, b) {
+ t.Fatal("two calls to SystemCertPool had different results")
+ }
+ if ok := b.AppendCertsFromPEM([]byte(`
+-----BEGIN CERTIFICATE-----
+MIIDBjCCAe6gAwIBAgIRANXM5I3gjuqDfTp/PYrs+u8wDQYJKoZIhvcNAQELBQAw
+EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODAzMjcxOTU2MjFaFw0xOTAzMjcxOTU2
+MjFaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDK+9m3rjsO2Djes6bIYQZ3eV29JF09ZrjOrEHLtaKrD6/acsoSoTsf
+cQr+rzzztdB5ijWXCS64zo/0OiqBeZUNZ67jVdToa9qW5UYe2H0Y+ZNdfA5GYMFD
+yk/l3/uBu3suTZPfXiW2TjEi27Q8ruNUIZ54DpTcs6y2rBRFzadPWwn/VQMlvRXM
+jrzl8Y08dgnYmaAHprxVzwMXcQ/Brol+v9GvjaH1DooHqkn8O178wsPQNhdtvN01
+IXL46cYdcUwWrE/GX5u+9DaSi+0KWxAPQ+NVD5qUI0CKl4714yGGh7feXMjJdHgl
+VG4QJZlJvC4FsURgCHJT6uHGIelnSwhbAgMBAAGjVzBVMA4GA1UdDwEB/wQEAwIF
+oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMCAGA1UdEQQZMBeC
+FVRlc3RTeXN0ZW1DZXJ0UG9vbC5nbzANBgkqhkiG9w0BAQsFAAOCAQEAwuSRx/VR
+BKh2ICxZjL6jBwk/7UlU1XKbhQD96RqkidDNGEc6eLZ90Z5XXTurEsXqdm5jQYPs
+1cdcSW+fOSMl7MfW9e5tM66FaIPZl9rKZ1r7GkOfgn93xdLAWe8XHd19xRfDreub
+YC8DVqgLASOEYFupVSl76ktPfxkU5KCvmUf3P2PrRybk1qLGFytGxfyice2gHSNI
+gify3K/+H/7wCkyFW4xYvzl7WW4mXxoqPRPjQt1J423DhnnQ4G1P8V/vhUpXNXOq
+N9IEPnWuihC09cyx/WMQIUlWnaQLHdfpPS04Iez3yy2PdfXJzwfPrja7rNE+skK6
+pa/O1nF0AfWOpw==
+-----END CERTIFICATE-----
+ `)); !ok {
+ t.Fatal("AppendCertsFromPEM failed")
+ }
+ if reflect.DeepEqual(a, b) {
+ t.Fatal("changing one pool modified the other")
+ }
}
const emptyNameConstraintsPEM = `