diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-06 19:49:01 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-06 19:49:01 +0000 |
commit | 0ce10ea1348e9afd5d0eec6bca986bfe58bac5ac (patch) | |
tree | 39530b071991b2326f881b2a30a2d82d6c133fd6 /libgo/go/crypto | |
parent | 57a8bf1b0c6057ccbacb0cf79eb84d1985c2c1fe (diff) | |
download | gcc-0ce10ea1348e9afd5d0eec6bca986bfe58bac5ac.tar.gz |
libgo: Update to October 24 version of master library.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204466 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/crypto')
60 files changed, 9047 insertions, 754 deletions
diff --git a/libgo/go/crypto/cipher/cbc.go b/libgo/go/crypto/cipher/cbc.go index 913a5643f22..4189677e390 100644 --- a/libgo/go/crypto/cipher/cbc.go +++ b/libgo/go/crypto/cipher/cbc.go @@ -61,6 +61,13 @@ func (x *cbcEncrypter) CryptBlocks(dst, src []byte) { } } +func (x *cbcEncrypter) SetIV(iv []byte) { + if len(iv) != len(x.iv) { + panic("cipher: incorrect length IV") + } + copy(x.iv, iv) +} + type cbcDecrypter cbc // NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining @@ -94,3 +101,10 @@ func (x *cbcDecrypter) CryptBlocks(dst, src []byte) { dst = dst[x.blockSize:] } } + +func (x *cbcDecrypter) SetIV(iv []byte) { + if len(iv) != len(x.iv) { + panic("cipher: incorrect length IV") + } + copy(x.iv, iv) +} diff --git a/libgo/go/crypto/cipher/gcm.go b/libgo/go/crypto/cipher/gcm.go new file mode 100644 index 00000000000..2bcb469852b --- /dev/null +++ b/libgo/go/crypto/cipher/gcm.go @@ -0,0 +1,350 @@ +// 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. + +package cipher + +import ( + "crypto/subtle" + "errors" +) + +// AEAD is a cipher mode providing authenticated encryption with associated +// data. +type AEAD interface { + // NonceSize returns the size of the nonce that must be passed to Seal + // and Open. + NonceSize() int + + // Overhead returns the maximum difference between the lengths of a + // plaintext and ciphertext. + Overhead() int + + // Seal encrypts and authenticates plaintext, authenticates the + // additional data and appends the result to dst, returning the updated + // slice. The nonce must be NonceSize() bytes long and unique for all + // time, for a given key. + // + // The plaintext and dst may alias exactly or not at all. + Seal(dst, nonce, plaintext, data []byte) []byte + + // Open decrypts and authenticates ciphertext, authenticates the + // additional data and, if successful, appends the resulting plaintext + // to dst, returning the updated slice and true. On error, nil and + // false is returned. The nonce must be NonceSize() bytes long and both + // it and the additional data must match the value passed to Seal. + // + // The ciphertext and dst may alias exactly or not at all. + Open(dst, nonce, ciphertext, data []byte) ([]byte, error) +} + +// gcmFieldElement represents a value in GF(2¹²⁸). In order to reflect the GCM +// standard and make getUint64 suitable for marshaling these values, the bits +// are stored backwards. For example: +// the coefficient of x⁰ can be obtained by v.low >> 63. +// the coefficient of x⁶³ can be obtained by v.low & 1. +// the coefficient of x⁶⁴ can be obtained by v.high >> 63. +// the coefficient of x¹²⁷ can be obtained by v.high & 1. +type gcmFieldElement struct { + low, high uint64 +} + +// 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 +type gcm struct { + cipher Block + // productTable contains the first sixteen powers of the key, H. + // However, they are in bit reversed order. See NewGCM. + productTable [16]gcmFieldElement +} + +// NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode. +func NewGCM(cipher Block) (AEAD, error) { + if cipher.BlockSize() != gcmBlockSize { + return nil, errors.New("cipher: NewGCM requires 128-bit block cipher") + } + + var key [gcmBlockSize]byte + cipher.Encrypt(key[:], key[:]) + + g := &gcm{cipher: cipher} + + // We precompute 16 multiples of |key|. However, when we do lookups + // into this table we'll be using bits from a field element and + // therefore the bits will be in the reverse order. So normally one + // would expect, say, 4*key to be in index 4 of the table but due to + // this bit ordering it will actually be in index 0010 (base 2) = 2. + x := gcmFieldElement{ + getUint64(key[:8]), + getUint64(key[8:]), + } + g.productTable[reverseBits(1)] = x + + for i := 2; i < 16; i += 2 { + g.productTable[reverseBits(i)] = gcmDouble(&g.productTable[reverseBits(i/2)]) + g.productTable[reverseBits(i+1)] = gcmAdd(&g.productTable[reverseBits(i)], &x) + } + + return g, nil +} + +const ( + gcmBlockSize = 16 + gcmTagSize = 16 + gcmNonceSize = 12 +) + +func (*gcm) NonceSize() int { + return gcmNonceSize +} + +func (*gcm) Overhead() int { + return gcmTagSize +} + +func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte { + if len(nonce) != gcmNonceSize { + panic("cipher: incorrect nonce length given to GCM") + } + + ret, out := sliceForAppend(dst, len(plaintext)+gcmTagSize) + + // See GCM spec, section 7.1. + var counter, tagMask [gcmBlockSize]byte + copy(counter[:], nonce) + counter[gcmBlockSize-1] = 1 + + g.cipher.Encrypt(tagMask[:], counter[:]) + gcmInc32(&counter) + + g.counterCrypt(out, plaintext, &counter) + g.auth(out[len(plaintext):], out[:len(plaintext)], data, &tagMask) + + return ret +} + +var errOpen = errors.New("cipher: message authentication failed") + +func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { + if len(nonce) != gcmNonceSize { + panic("cipher: incorrect nonce length given to GCM") + } + + if len(ciphertext) < gcmTagSize { + return nil, errOpen + } + tag := ciphertext[len(ciphertext)-gcmTagSize:] + ciphertext = ciphertext[:len(ciphertext)-gcmTagSize] + + // See GCM spec, section 7.1. + var counter, tagMask [gcmBlockSize]byte + copy(counter[:], nonce) + counter[gcmBlockSize-1] = 1 + + g.cipher.Encrypt(tagMask[:], counter[:]) + gcmInc32(&counter) + + var expectedTag [gcmTagSize]byte + g.auth(expectedTag[:], ciphertext, data, &tagMask) + + if subtle.ConstantTimeCompare(expectedTag[:], tag) != 1 { + return nil, errOpen + } + + ret, out := sliceForAppend(dst, len(ciphertext)) + g.counterCrypt(out, ciphertext, &counter) + + return ret, nil +} + +// reverseBits reverses the order of the bits of 4-bit number in i. +func reverseBits(i int) int { + i = ((i << 2) & 0xc) | ((i >> 2) & 0x3) + i = ((i << 1) & 0xa) | ((i >> 1) & 0x5) + return i +} + +// gcmAdd adds two elements of GF(2¹²⁸) and returns the sum. +func gcmAdd(x, y *gcmFieldElement) gcmFieldElement { + // Addition in a characteristic 2 field is just XOR. + return gcmFieldElement{x.low ^ y.low, x.high ^ y.high} +} + +// gcmDouble returns the result of doubling an element of GF(2¹²⁸). +func gcmDouble(x *gcmFieldElement) (double gcmFieldElement) { + msbSet := x.high&1 == 1 + + // Because of the bit-ordering, doubling is actually a right shift. + double.high = x.high >> 1 + double.high |= x.low << 63 + double.low = x.low >> 1 + + // If the most-significant bit was set before shifting then it, + // conceptually, becomes a term of x^128. This is greater than the + // irreducible polynomial so the result has to be reduced. The + // irreducible polynomial is 1+x+x^2+x^7+x^128. We can subtract that to + // eliminate the term at x^128 which also means subtracting the other + // four terms. In characteristic 2 fields, subtraction == addition == + // XOR. + if msbSet { + double.low ^= 0xe100000000000000 + } + + return +} + +var gcmReductionTable = []uint16{ + 0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0, +} + +// mul sets y to y*H, where H is the GCM key, fixed during NewGCM. +func (g *gcm) mul(y *gcmFieldElement) { + var z gcmFieldElement + + for i := 0; i < 2; i++ { + word := y.high + if i == 1 { + word = y.low + } + + // Multiplication works by multiplying z by 16 and adding in + // one of the precomputed multiples of H. + for j := 0; j < 64; j += 4 { + msw := z.high & 0xf + z.high >>= 4 + z.high |= z.low << 60 + z.low >>= 4 + z.low ^= uint64(gcmReductionTable[msw]) << 48 + + // the values in |table| are ordered for + // little-endian bit positions. See the comment + // in NewGCM. + t := &g.productTable[word&0xf] + + z.low ^= t.low + z.high ^= t.high + word >>= 4 + } + } + + *y = z +} + +// updateBlocks extends y with more polynomial terms from blocks, based on +// Horner's rule. There must be a multiple of gcmBlockSize bytes in blocks. +func (g *gcm) updateBlocks(y *gcmFieldElement, blocks []byte) { + for len(blocks) > 0 { + y.low ^= getUint64(blocks) + y.high ^= getUint64(blocks[8:]) + g.mul(y) + blocks = blocks[gcmBlockSize:] + } +} + +// update extends y with more polynomial terms from data. If data is not a +// multiple of gcmBlockSize bytes long then the remainder is zero padded. +func (g *gcm) update(y *gcmFieldElement, data []byte) { + fullBlocks := (len(data) >> 4) << 4 + g.updateBlocks(y, data[:fullBlocks]) + + if len(data) != fullBlocks { + var partialBlock [gcmBlockSize]byte + copy(partialBlock[:], data[fullBlocks:]) + g.updateBlocks(y, partialBlock[:]) + } +} + +// gcmInc32 treats the final four bytes of counterBlock as a big-endian value +// and increments it. +func gcmInc32(counterBlock *[16]byte) { + c := 1 + for i := gcmBlockSize - 1; i >= gcmBlockSize-4; i-- { + c += int(counterBlock[i]) + counterBlock[i] = byte(c) + c >>= 8 + } +} + +// sliceForAppend takes a slice and a requested number of bytes. It returns a +// slice with the contents of the given slice followed by that many bytes and a +// second slice that aliases into it and contains only the extra bytes. If the +// original slice has sufficient capacity then no allocation is performed. +func sliceForAppend(in []byte, n int) (head, tail []byte) { + if total := len(in) + n; cap(in) >= total { + head = in[:total] + } else { + head = make([]byte, total) + copy(head, in) + } + tail = head[len(in):] + return +} + +// counterCrypt crypts in to out using g.cipher in counter mode. +func (g *gcm) counterCrypt(out, in []byte, counter *[gcmBlockSize]byte) { + var mask [gcmBlockSize]byte + + for len(in) >= gcmBlockSize { + g.cipher.Encrypt(mask[:], counter[:]) + gcmInc32(counter) + + for i := range mask { + out[i] = in[i] ^ mask[i] + } + out = out[gcmBlockSize:] + in = in[gcmBlockSize:] + } + + if len(in) > 0 { + g.cipher.Encrypt(mask[:], counter[:]) + gcmInc32(counter) + + for i := range in { + out[i] = in[i] ^ mask[i] + } + } +} + +// auth calculates GHASH(ciphertext, additionalData), masks the result with +// tagMask and writes the result to out. +func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize]byte) { + var y gcmFieldElement + g.update(&y, additionalData) + g.update(&y, ciphertext) + + y.low ^= uint64(len(additionalData)) * 8 + y.high ^= uint64(len(ciphertext)) * 8 + + g.mul(&y) + + putUint64(out, y.low) + putUint64(out[8:], y.high) + + for i := range tagMask { + out[i] ^= tagMask[i] + } +} + +func getUint64(data []byte) uint64 { + r := uint64(data[0])<<56 | + uint64(data[1])<<48 | + uint64(data[2])<<40 | + uint64(data[3])<<32 | + uint64(data[4])<<24 | + uint64(data[5])<<16 | + uint64(data[6])<<8 | + uint64(data[7]) + return r +} + +func putUint64(out []byte, v uint64) { + out[0] = byte(v >> 56) + out[1] = byte(v >> 48) + out[2] = byte(v >> 40) + out[3] = byte(v >> 32) + out[4] = byte(v >> 24) + out[5] = byte(v >> 16) + out[6] = byte(v >> 8) + out[7] = byte(v) +} diff --git a/libgo/go/crypto/cipher/gcm_test.go b/libgo/go/crypto/cipher/gcm_test.go new file mode 100644 index 00000000000..02d42159006 --- /dev/null +++ b/libgo/go/crypto/cipher/gcm_test.go @@ -0,0 +1,175 @@ +// 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. + +package cipher_test + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "encoding/hex" + "testing" +) + +// AES-GCM test vectors taken from gcmEncryptExtIV128.rsp from +// http://csrc.nist.gov/groups/STM/cavp/index.html. +var aesGCMTests = []struct { + key, nonce, plaintext, ad, result string +}{ + { + "11754cd72aec309bf52f7687212e8957", + "3c819d9a9bed087615030b65", + "", + "", + "250327c674aaf477aef2675748cf6971", + }, + { + "ca47248ac0b6f8372a97ac43508308ed", + "ffd2b598feabc9019262d2be", + "", + "", + "60d20404af527d248d893ae495707d1a", + }, + { + "77be63708971c4e240d1cb79e8d77feb", + "e0e00f19fed7ba0136a797f3", + "", + "7a43ec1d9c0a5a78a0b16533a6213cab", + "209fcc8d3675ed938e9c7166709dd946", + }, + { + "7680c5d3ca6154758e510f4d25b98820", + "f8f105f9c3df4965780321f8", + "", + "c94c410194c765e3dcc7964379758ed3", + "94dca8edfcf90bb74b153c8d48a17930", + }, + { + "7fddb57453c241d03efbed3ac44e371c", + "ee283a3fc75575e33efd4887", + "d5de42b461646c255c87bd2962d3b9a2", + "", + "2ccda4a5415cb91e135c2a0f78c9b2fdb36d1df9b9d5e596f83e8b7f52971cb3", + }, + { + "ab72c77b97cb5fe9a382d9fe81ffdbed", + "54cc7dc2c37ec006bcc6d1da", + "007c5e5b3e59df24a7c355584fc1518d", + "", + "0e1bde206a07a9c2c1b65300f8c649972b4401346697138c7a4891ee59867d0c", + }, + { + "fe47fcce5fc32665d2ae399e4eec72ba", + "5adb9609dbaeb58cbd6e7275", + "7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1b840382c4bccaf3bafb4ca8429bea063", + "88319d6e1d3ffa5f987199166c8a9b56c2aeba5a", + "98f4826f05a265e6dd2be82db241c0fbbbf9ffb1c173aa83964b7cf5393043736365253ddbc5db8778371495da76d269e5db3e291ef1982e4defedaa2249f898556b47", + }, + { + "ec0c2ba17aa95cd6afffe949da9cc3a8", + "296bce5b50b7d66096d627ef", + "b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987b764b9611f6c0f8641843d5d58f3a242", + "f8d00f05d22bf68599bcdeb131292ad6e2df5d14", + "a7443d31c26bdf2a1c945e29ee4bd344a99cfaf3aa71f8b3f191f83c2adfc7a07162995506fde6309ffc19e716eddf1a828c5a890147971946b627c40016da1ecf3e77", + }, + { + "2c1f21cf0f6fb3661943155c3e3d8492", + "23cb5ff362e22426984d1907", + "42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d68b5615ba7c1220ff6510e259f06655d8", + "5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f4488f33cfb5e979e42b6e1cfc0a60238982a7aec", + "81824f0e0d523db30d3da369fdc0d60894c7a0a20646dd015073ad2732bd989b14a222b6ad57af43e1895df9dca2a5344a62cc57a3ee28136e94c74838997ae9823f3a", + }, + { + "d9f7d2411091f947b4d6f1e2d1f0fb2e", + "e1934f5db57cc983e6b180e7", + "73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490c2c6f6166f4a59431e182663fcaea05a", + "0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a20115d2e51398344b16bee1ed7c499b353d6c597af8", + "aaadbd5c92e9151ce3db7210b8714126b73e43436d242677afa50384f2149b831f1d573c7891c2a91fbc48db29967ec9542b2321b51ca862cb637cdd03b99a0f93b134", + }, + { + "fe9bb47deb3a61e423c2231841cfd1fb", + "4d328eb776f500a2f7fb47aa", + "f1cc3818e421876bb6b8bbd6c9", + "", + "b88c5c1977b35b517b0aeae96743fd4727fe5cdb4b5b42818dea7ef8c9", + }, + { + "6703df3701a7f54911ca72e24dca046a", + "12823ab601c350ea4bc2488c", + "793cd125b0b84a043e3ac67717", + "", + "b2051c80014f42f08735a7b0cd38e6bcd29962e5f2c13626b85a877101", + }, +} + +func TestAESGCM(t *testing.T) { + for i, test := range aesGCMTests { + key, _ := hex.DecodeString(test.key) + aes, err := aes.NewCipher(key) + if err != nil { + t.Fatal(err) + } + + nonce, _ := hex.DecodeString(test.nonce) + plaintext, _ := hex.DecodeString(test.plaintext) + ad, _ := hex.DecodeString(test.ad) + aesgcm, err := cipher.NewGCM(aes) + if err != nil { + t.Fatal(err) + } + + ct := aesgcm.Seal(nil, nonce, plaintext, ad) + if ctHex := hex.EncodeToString(ct); ctHex != test.result { + t.Errorf("#%d: got %s, want %s", i, ctHex, test.result) + continue + } + + plaintext2, err := aesgcm.Open(nil, nonce, ct, ad) + if err != nil { + t.Errorf("#%d: Open failed", i) + continue + } + + if !bytes.Equal(plaintext, plaintext2) { + t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext) + continue + } + + if len(ad) > 0 { + ad[0] ^= 0x80 + if _, err := aesgcm.Open(nil, nonce, ct, ad); err == nil { + t.Errorf("#%d: Open was successful after altering additional data", i) + } + ad[0] ^= 0x80 + } + + nonce[0] ^= 0x80 + if _, err := aesgcm.Open(nil, nonce, ct, ad); err == nil { + t.Errorf("#%d: Open was successful after altering nonce", i) + } + nonce[0] ^= 0x80 + + ct[0] ^= 0x80 + if _, err := aesgcm.Open(nil, nonce, ct, ad); err == nil { + t.Errorf("#%d: Open was successful after altering ciphertext", i) + } + ct[0] ^= 0x80 + } +} + +func BenchmarkAESGCM(b *testing.B) { + buf := make([]byte, 1024) + b.SetBytes(int64(len(buf))) + + var key [16]byte + var nonce [12]byte + aes, _ := aes.NewCipher(key[:]) + aesgcm, _ := cipher.NewGCM(aes) + var out []byte + + b.ResetTimer() + for i := 0; i < b.N; i++ { + out = aesgcm.Seal(out[:0], nonce[:], buf, nonce[:]) + } +} diff --git a/libgo/go/crypto/cipher/io.go b/libgo/go/crypto/cipher/io.go index 807e8daeaf4..3938c0a4c88 100644 --- a/libgo/go/crypto/cipher/io.go +++ b/libgo/go/crypto/cipher/io.go @@ -25,6 +25,8 @@ func (r StreamReader) Read(dst []byte) (n int, err error) { // StreamWriter wraps a Stream into an io.Writer. It calls XORKeyStream // to process each slice of data which passes through. If any Write call // returns short then the StreamWriter is out of sync and must be discarded. +// A StreamWriter has no internal buffering; Close does not need +// to be called to flush write data. type StreamWriter struct { S Stream W io.Writer @@ -43,8 +45,11 @@ func (w StreamWriter) Write(src []byte) (n int, err error) { return } +// Close closes the underlying Writer and returns its Close return value, if the Writer +// is also an io.Closer. Otherwise it returns nil. func (w StreamWriter) Close() error { - // This saves us from either requiring a WriteCloser or having a - // StreamWriterCloser. - return w.W.(io.Closer).Close() + if c, ok := w.W.(io.Closer); ok { + return c.Close() + } + return nil } diff --git a/libgo/go/crypto/crypto.go b/libgo/go/crypto/crypto.go index ecefc657254..4b03628e692 100644 --- a/libgo/go/crypto/crypto.go +++ b/libgo/go/crypto/crypto.go @@ -7,6 +7,7 @@ package crypto import ( "hash" + "strconv" ) // Hash identifies a cryptographic hash function that is implemented in another @@ -59,7 +60,7 @@ func (h Hash) New() hash.Hash { return f() } } - panic("crypto: requested hash function is unavailable") + panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable") } // Available reports whether the given hash function is linked into the binary. @@ -77,5 +78,8 @@ func RegisterHash(h Hash, f func() hash.Hash) { hashes[h] = f } +// PublicKey represents a public key using an unspecified algorithm. +type PublicKey interface{} + // PrivateKey represents a private key using an unspecified algorithm. type PrivateKey interface{} diff --git a/libgo/go/crypto/des/block.go b/libgo/go/crypto/des/block.go index c11c62cd723..26355a22e71 100644 --- a/libgo/go/crypto/des/block.go +++ b/libgo/go/crypto/des/block.go @@ -10,7 +10,7 @@ import ( func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) { b := binary.BigEndian.Uint64(src) - b = permuteBlock(b, initialPermutation[:]) + b = permuteInitialBlock(b) left, right := uint32(b>>32), uint32(b) var subkey uint64 @@ -25,7 +25,7 @@ func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) { } // switch left & right and perform final permutation preOutput := (uint64(right) << 32) | uint64(left) - binary.BigEndian.PutUint64(dst, permuteBlock(preOutput, finalPermutation[:])) + binary.BigEndian.PutUint64(dst, permuteFinalBlock(preOutput)) } // Encrypt one block from src into dst, using the subkeys. @@ -40,20 +40,24 @@ func decryptBlock(subkeys []uint64, dst, src []byte) { // DES Feistel function func feistel(right uint32, key uint64) (result uint32) { - sBoxLocations := key ^ permuteBlock(uint64(right), expansionFunction[:]) + sBoxLocations := key ^ expandBlock(right) var sBoxResult uint32 for i := uint8(0); i < 8; i++ { sBoxLocation := uint8(sBoxLocations>>42) & 0x3f sBoxLocations <<= 6 // row determined by 1st and 6th bit - row := (sBoxLocation & 0x1) | ((sBoxLocation & 0x20) >> 4) // column is middle four bits + row := (sBoxLocation & 0x1) | ((sBoxLocation & 0x20) >> 4) column := (sBoxLocation >> 1) & 0xf - sBoxResult |= uint32(sBoxes[i][row][column]) << (4 * (7 - i)) + sBoxResult ^= feistelBox[i][16*row+column] } - return uint32(permuteBlock(uint64(sBoxResult), permutationFunction[:])) + return sBoxResult } +// feistelBox[s][16*i+j] contains the output of permutationFunction +// for sBoxes[s][i][j] << 4*(7-s) +var feistelBox [8][64]uint32 + // general purpose function to perform DES block permutations func permuteBlock(src uint64, permutation []uint8) (block uint64) { for position, n := range permutation { @@ -63,6 +67,127 @@ func permuteBlock(src uint64, permutation []uint8) (block uint64) { return } +func init() { + for s := range sBoxes { + for i := 0; i < 4; i++ { + for j := 0; j < 16; j++ { + f := uint64(sBoxes[s][i][j]) << (4 * (7 - uint(s))) + f = permuteBlock(uint64(f), permutationFunction[:]) + feistelBox[s][16*i+j] = uint32(f) + } + } + } +} + +// expandBlock expands an input block of 32 bits, +// producing an output block of 48 bits. +func expandBlock(src uint32) (block uint64) { + // rotate the 5 highest bits to the right. + src = (src << 5) | (src >> 27) + for i := 0; i < 8; i++ { + block <<= 6 + // take the 6 bits on the right + block |= uint64(src) & (1<<6 - 1) + // advance by 4 bits. + src = (src << 4) | (src >> 28) + } + return +} + +// permuteInitialBlock is equivalent to the permutation defined +// by initialPermutation. +func permuteInitialBlock(block uint64) uint64 { + // block = b7 b6 b5 b4 b3 b2 b1 b0 (8 bytes) + b1 := block >> 48 + b2 := block << 48 + block ^= b1 ^ b2 ^ b1<<48 ^ b2>>48 + + // block = b1 b0 b5 b4 b3 b2 b7 b6 + b1 = block >> 32 & 0xff00ff + b2 = (block & 0xff00ff00) + block ^= b1<<32 ^ b2 ^ b1<<8 ^ b2<<24 // exchange b0 b4 with b3 b7 + + // block is now b1 b3 b5 b7 b0 b2 b4 b7, the permutation: + // ... 8 + // ... 24 + // ... 40 + // ... 56 + // 7 6 5 4 3 2 1 0 + // 23 22 21 20 19 18 17 16 + // ... 32 + // ... 48 + + // exchange 4,5,6,7 with 32,33,34,35 etc. + b1 = block & 0x0f0f00000f0f0000 + b2 = block & 0x0000f0f00000f0f0 + block ^= b1 ^ b2 ^ b1>>12 ^ b2<<12 + + // block is the permutation: + // + // [+8] [+40] + // + // 7 6 5 4 + // 23 22 21 20 + // 3 2 1 0 + // 19 18 17 16 [+32] + + // exchange 0,1,4,5 with 18,19,22,23 + b1 = block & 0x3300330033003300 + b2 = block & 0x00cc00cc00cc00cc + block ^= b1 ^ b2 ^ b1>>6 ^ b2<<6 + + // block is the permutation: + // 15 14 + // 13 12 + // 11 10 + // 9 8 + // 7 6 + // 5 4 + // 3 2 + // 1 0 [+16] [+32] [+64] + + // exchange 0,2,4,6 with 9,11,13,15: + b1 = block & 0xaaaaaaaa55555555 + block ^= b1 ^ b1>>33 ^ b1<<33 + + // block is the permutation: + // 6 14 22 30 38 46 54 62 + // 4 12 20 28 36 44 52 60 + // 2 10 18 26 34 42 50 58 + // 0 8 16 24 32 40 48 56 + // 7 15 23 31 39 47 55 63 + // 5 13 21 29 37 45 53 61 + // 3 11 19 27 35 43 51 59 + // 1 9 17 25 33 41 49 57 + return block +} + +// permuteInitialBlock is equivalent to the permutation defined +// by finalPermutation. +func permuteFinalBlock(block uint64) uint64 { + // Perform the same bit exchanges as permuteInitialBlock + // but in reverse order. + b1 := block & 0xaaaaaaaa55555555 + block ^= b1 ^ b1>>33 ^ b1<<33 + + b1 = block & 0x3300330033003300 + b2 := block & 0x00cc00cc00cc00cc + block ^= b1 ^ b2 ^ b1>>6 ^ b2<<6 + + b1 = block & 0x0f0f00000f0f0000 + b2 = block & 0x0000f0f00000f0f0 + block ^= b1 ^ b2 ^ b1>>12 ^ b2<<12 + + b1 = block >> 32 & 0xff00ff + b2 = (block & 0xff00ff00) + block ^= b1<<32 ^ b2 ^ b1<<8 ^ b2<<24 + + b1 = block >> 48 + b2 = block << 48 + block ^= b1 ^ b2 ^ b1<<48 ^ b2>>48 + return block +} + // creates 16 28-bit blocks rotated according // to the rotation schedule func ksRotate(in uint32) (out []uint32) { diff --git a/libgo/go/crypto/des/des_test.go b/libgo/go/crypto/des/des_test.go index 2e87e99b67f..2bd525afecc 100644 --- a/libgo/go/crypto/des/des_test.go +++ b/libgo/go/crypto/des/des_test.go @@ -1504,20 +1504,63 @@ func TestSubstitutionTableKnownAnswerDecrypt(t *testing.T) { } } -func ExampleNewTripleDESCipher() { - // NewTripleDESCipher can also be used when EDE2 is required by - // duplicating the first 8 bytes of the 16-byte key. - ede2Key := []byte("example key 1234") +func TestInitialPermute(t *testing.T) { + for i := uint(0); i < 64; i++ { + bit := uint64(1) << i + got := permuteInitialBlock(bit) + want := uint64(1) << finalPermutation[63-i] + if got != want { + t.Errorf("permute(%x) = %x, want %x", bit, got, want) + } + } +} - var tripleDESKey []byte - tripleDESKey = append(tripleDESKey, ede2Key[:16]...) - tripleDESKey = append(tripleDESKey, ede2Key[:8]...) +func TestFinalPermute(t *testing.T) { + for i := uint(0); i < 64; i++ { + bit := uint64(1) << i + got := permuteFinalBlock(bit) + want := uint64(1) << initialPermutation[63-i] + if got != want { + t.Errorf("permute(%x) = %x, want %x", bit, got, want) + } + } +} - _, err := NewTripleDESCipher(tripleDESKey) +func TestExpandBlock(t *testing.T) { + for i := uint(0); i < 32; i++ { + bit := uint32(1) << i + got := expandBlock(bit) + want := permuteBlock(uint64(bit), expansionFunction[:]) + if got != want { + t.Errorf("expand(%x) = %x, want %x", bit, got, want) + } + } +} + +func BenchmarkEncrypt(b *testing.B) { + tt := encryptDESTests[0] + c, err := NewCipher(tt.key) if err != nil { - panic(err) + b.Fatal("NewCipher:", err) + } + out := make([]byte, len(tt.in)) + b.SetBytes(int64(len(out))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + c.Encrypt(out, tt.in) } +} - // See crypto/cipher for how to use a cipher.Block for encryption and - // decryption. +func BenchmarkDecrypt(b *testing.B) { + tt := encryptDESTests[0] + c, err := NewCipher(tt.key) + if err != nil { + b.Fatal("NewCipher:", err) + } + out := make([]byte, len(tt.out)) + b.SetBytes(int64(len(out))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + c.Decrypt(out, tt.out) + } } diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go index 25500022939..d02f15c34d9 100644 --- a/libgo/go/crypto/ecdsa/ecdsa.go +++ b/libgo/go/crypto/ecdsa/ecdsa.go @@ -123,8 +123,8 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err return } -// Verify verifies the signature in r, s of hash using the public key, pub. It -// returns true iff the signature is valid. +// Verify verifies the signature in r, s of hash using the public key, pub. Its +// return value records whether the signature is valid. func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { // See [NSA] 3.4.2 c := pub.Curve diff --git a/libgo/go/crypto/elliptic/elliptic.go b/libgo/go/crypto/elliptic/elliptic.go index 7a4ff6614c1..ba673f80ca6 100644 --- a/libgo/go/crypto/elliptic/elliptic.go +++ b/libgo/go/crypto/elliptic/elliptic.go @@ -322,7 +322,6 @@ func Unmarshal(curve Curve, data []byte) (x, y *big.Int) { } var initonce sync.Once -var p256 *CurveParams var p384 *CurveParams var p521 *CurveParams @@ -333,17 +332,6 @@ func initAll() { initP521() } -func initP256() { - // See FIPS 186-3, section D.2.3 - p256 = new(CurveParams) - p256.P, _ = new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10) - p256.N, _ = new(big.Int).SetString("115792089210356248762697446949407573529996955224135760342422259061068512044369", 10) - p256.B, _ = new(big.Int).SetString("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16) - p256.Gx, _ = new(big.Int).SetString("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16) - p256.Gy, _ = new(big.Int).SetString("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16) - p256.BitSize = 256 -} - func initP384() { // See FIPS 186-3, section D.2.4 p384 = new(CurveParams) diff --git a/libgo/go/crypto/elliptic/elliptic_test.go b/libgo/go/crypto/elliptic/elliptic_test.go index 58f903966ce..4dc27c92bf4 100644 --- a/libgo/go/crypto/elliptic/elliptic_test.go +++ b/libgo/go/crypto/elliptic/elliptic_test.go @@ -322,6 +322,52 @@ func TestGenericBaseMult(t *testing.T) { } } +func TestP256BaseMult(t *testing.T) { + p256 := P256() + p256Generic := p256.Params() + + scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1) + for _, e := range p224BaseMultTests { + k, _ := new(big.Int).SetString(e.k, 10) + scalars = append(scalars, k) + } + k := new(big.Int).SetInt64(1) + k.Lsh(k, 500) + scalars = append(scalars, k) + + for i, k := range scalars { + x, y := p256.ScalarBaseMult(k.Bytes()) + x2, y2 := p256Generic.ScalarBaseMult(k.Bytes()) + if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 { + t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2) + } + + if testing.Short() && i > 5 { + break + } + } +} + +func TestP256Mult(t *testing.T) { + p256 := P256() + p256Generic := p256.Params() + + for i, e := range p224BaseMultTests { + x, _ := new(big.Int).SetString(e.x, 16) + y, _ := new(big.Int).SetString(e.y, 16) + k, _ := new(big.Int).SetString(e.k, 10) + + xx, yy := p256.ScalarMult(x, y, k.Bytes()) + xx2, yy2 := p256Generic.ScalarMult(x, y, k.Bytes()) + if xx.Cmp(xx2) != 0 || yy.Cmp(yy2) != 0 { + t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, xx2, yy2) + } + if testing.Short() && i > 5 { + break + } + } +} + func TestInfinity(t *testing.T) { tests := []struct { name string @@ -371,6 +417,17 @@ func BenchmarkBaseMult(b *testing.B) { } } +func BenchmarkBaseMultP256(b *testing.B) { + b.ResetTimer() + p256 := P256() + e := p224BaseMultTests[25] + k, _ := new(big.Int).SetString(e.k, 10) + b.StartTimer() + for i := 0; i < b.N; i++ { + p256.ScalarBaseMult(k.Bytes()) + } +} + func TestMarshal(t *testing.T) { p224 := P224() _, x, y, err := GenerateKey(p224, rand.Reader) diff --git a/libgo/go/crypto/elliptic/p256.go b/libgo/go/crypto/elliptic/p256.go new file mode 100644 index 00000000000..82be51e62cd --- /dev/null +++ b/libgo/go/crypto/elliptic/p256.go @@ -0,0 +1,1186 @@ +// 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. + +package elliptic + +// This file contains a constant-time, 32-bit implementation of P256. + +import ( + "math/big" +) + +type p256Curve struct { + *CurveParams +} + +var ( + p256 p256Curve + // RInverse contains 1/R mod p - the inverse of the Montgomery constant + // (2**257). + p256RInverse *big.Int +) + +func initP256() { + // See FIPS 186-3, section D.2.3 + p256.CurveParams = new(CurveParams) + p256.P, _ = new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10) + p256.N, _ = new(big.Int).SetString("115792089210356248762697446949407573529996955224135760342422259061068512044369", 10) + p256.B, _ = new(big.Int).SetString("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16) + p256.Gx, _ = new(big.Int).SetString("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16) + p256.Gy, _ = new(big.Int).SetString("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16) + p256.BitSize = 256 + + p256RInverse, _ = new(big.Int).SetString("7fffffff00000001fffffffe8000000100000000ffffffff0000000180000000", 16) +} + +func (curve p256Curve) Params() *CurveParams { + return curve.CurveParams +} + +// p256GetScalar endian-swaps the big-endian scalar value from in and writes it +// to out. If the scalar is equal or greater than the order of the group, it's +// reduced modulo that order. +func p256GetScalar(out *[32]byte, in []byte) { + n := new(big.Int).SetBytes(in) + var scalarBytes []byte + + if n.Cmp(p256.N) >= 0 { + n.Mod(n, p256.N) + scalarBytes = n.Bytes() + } else { + scalarBytes = in + } + + for i, v := range scalarBytes { + out[len(scalarBytes)-(1+i)] = v + } +} + +func (p256Curve) ScalarBaseMult(scalar []byte) (x, y *big.Int) { + var scalarReversed [32]byte + p256GetScalar(&scalarReversed, scalar) + + var x1, y1, z1 [p256Limbs]uint32 + p256ScalarBaseMult(&x1, &y1, &z1, &scalarReversed) + return p256ToAffine(&x1, &y1, &z1) +} + +func (p256Curve) ScalarMult(bigX, bigY *big.Int, scalar []byte) (x, y *big.Int) { + var scalarReversed [32]byte + p256GetScalar(&scalarReversed, scalar) + + var px, py, x1, y1, z1 [p256Limbs]uint32 + p256FromBig(&px, bigX) + p256FromBig(&py, bigY) + p256ScalarMult(&x1, &y1, &z1, &px, &py, &scalarReversed) + return p256ToAffine(&x1, &y1, &z1) +} + +// Field elements are represented as nine, unsigned 32-bit words. +// +// The value of an field element is: +// x[0] + (x[1] * 2**29) + (x[2] * 2**57) + ... + (x[8] * 2**228) +// +// That is, each limb is alternately 29 or 28-bits wide in little-endian +// order. +// +// This means that a field element hits 2**257, rather than 2**256 as we would +// like. A 28, 29, ... pattern would cause us to hit 2**256, but that causes +// problems when multiplying as terms end up one bit short of a limb which +// would require much bit-shifting to correct. +// +// Finally, the values stored in a field element are in Montgomery form. So the +// value |y| is stored as (y*R) mod p, where p is the P-256 prime and R is +// 2**257. + +const ( + p256Limbs = 9 + bottom29Bits = 0x1fffffff +) + +var ( + // p256One is the number 1 as a field element. + p256One = [p256Limbs]uint32{2, 0, 0, 0xffff800, 0x1fffffff, 0xfffffff, 0x1fbfffff, 0x1ffffff, 0} + p256Zero = [p256Limbs]uint32{0, 0, 0, 0, 0, 0, 0, 0, 0} + // p256P is the prime modulus as a field element. + p256P = [p256Limbs]uint32{0x1fffffff, 0xfffffff, 0x1fffffff, 0x3ff, 0, 0, 0x200000, 0xf000000, 0xfffffff} + // p2562P is the twice prime modulus as a field element. + p2562P = [p256Limbs]uint32{0x1ffffffe, 0xfffffff, 0x1fffffff, 0x7ff, 0, 0, 0x400000, 0xe000000, 0x1fffffff} +) + +// p256Precomputed contains precomputed values to aid the calculation of scalar +// multiples of the base point, G. It's actually two, equal length, tables +// concatenated. +// +// The first table contains (x,y) field element pairs for 16 multiples of the +// base point, G. +// +// Index | Index (binary) | Value +// 0 | 0000 | 0G (all zeros, omitted) +// 1 | 0001 | G +// 2 | 0010 | 2**64G +// 3 | 0011 | 2**64G + G +// 4 | 0100 | 2**128G +// 5 | 0101 | 2**128G + G +// 6 | 0110 | 2**128G + 2**64G +// 7 | 0111 | 2**128G + 2**64G + G +// 8 | 1000 | 2**192G +// 9 | 1001 | 2**192G + G +// 10 | 1010 | 2**192G + 2**64G +// 11 | 1011 | 2**192G + 2**64G + G +// 12 | 1100 | 2**192G + 2**128G +// 13 | 1101 | 2**192G + 2**128G + G +// 14 | 1110 | 2**192G + 2**128G + 2**64G +// 15 | 1111 | 2**192G + 2**128G + 2**64G + G +// +// The second table follows the same style, but the terms are 2**32G, +// 2**96G, 2**160G, 2**224G. +// +// This is ~2KB of data. +var p256Precomputed = [p256Limbs * 2 * 15 * 2]uint32{ + 0x11522878, 0xe730d41, 0xdb60179, 0x4afe2ff, 0x12883add, 0xcaddd88, 0x119e7edc, 0xd4a6eab, 0x3120bee, + 0x1d2aac15, 0xf25357c, 0x19e45cdd, 0x5c721d0, 0x1992c5a5, 0xa237487, 0x154ba21, 0x14b10bb, 0xae3fe3, + 0xd41a576, 0x922fc51, 0x234994f, 0x60b60d3, 0x164586ae, 0xce95f18, 0x1fe49073, 0x3fa36cc, 0x5ebcd2c, + 0xb402f2f, 0x15c70bf, 0x1561925c, 0x5a26704, 0xda91e90, 0xcdc1c7f, 0x1ea12446, 0xe1ade1e, 0xec91f22, + 0x26f7778, 0x566847e, 0xa0bec9e, 0x234f453, 0x1a31f21a, 0xd85e75c, 0x56c7109, 0xa267a00, 0xb57c050, + 0x98fb57, 0xaa837cc, 0x60c0792, 0xcfa5e19, 0x61bab9e, 0x589e39b, 0xa324c5, 0x7d6dee7, 0x2976e4b, + 0x1fc4124a, 0xa8c244b, 0x1ce86762, 0xcd61c7e, 0x1831c8e0, 0x75774e1, 0x1d96a5a9, 0x843a649, 0xc3ab0fa, + 0x6e2e7d5, 0x7673a2a, 0x178b65e8, 0x4003e9b, 0x1a1f11c2, 0x7816ea, 0xf643e11, 0x58c43df, 0xf423fc2, + 0x19633ffa, 0x891f2b2, 0x123c231c, 0x46add8c, 0x54700dd, 0x59e2b17, 0x172db40f, 0x83e277d, 0xb0dd609, + 0xfd1da12, 0x35c6e52, 0x19ede20c, 0xd19e0c0, 0x97d0f40, 0xb015b19, 0x449e3f5, 0xe10c9e, 0x33ab581, + 0x56a67ab, 0x577734d, 0x1dddc062, 0xc57b10d, 0x149b39d, 0x26a9e7b, 0xc35df9f, 0x48764cd, 0x76dbcca, + 0xca4b366, 0xe9303ab, 0x1a7480e7, 0x57e9e81, 0x1e13eb50, 0xf466cf3, 0x6f16b20, 0x4ba3173, 0xc168c33, + 0x15cb5439, 0x6a38e11, 0x73658bd, 0xb29564f, 0x3f6dc5b, 0x53b97e, 0x1322c4c0, 0x65dd7ff, 0x3a1e4f6, + 0x14e614aa, 0x9246317, 0x1bc83aca, 0xad97eed, 0xd38ce4a, 0xf82b006, 0x341f077, 0xa6add89, 0x4894acd, + 0x9f162d5, 0xf8410ef, 0x1b266a56, 0xd7f223, 0x3e0cb92, 0xe39b672, 0x6a2901a, 0x69a8556, 0x7e7c0, + 0x9b7d8d3, 0x309a80, 0x1ad05f7f, 0xc2fb5dd, 0xcbfd41d, 0x9ceb638, 0x1051825c, 0xda0cf5b, 0x812e881, + 0x6f35669, 0x6a56f2c, 0x1df8d184, 0x345820, 0x1477d477, 0x1645db1, 0xbe80c51, 0xc22be3e, 0xe35e65a, + 0x1aeb7aa0, 0xc375315, 0xf67bc99, 0x7fdd7b9, 0x191fc1be, 0x61235d, 0x2c184e9, 0x1c5a839, 0x47a1e26, + 0xb7cb456, 0x93e225d, 0x14f3c6ed, 0xccc1ac9, 0x17fe37f3, 0x4988989, 0x1a90c502, 0x2f32042, 0xa17769b, + 0xafd8c7c, 0x8191c6e, 0x1dcdb237, 0x16200c0, 0x107b32a1, 0x66c08db, 0x10d06a02, 0x3fc93, 0x5620023, + 0x16722b27, 0x68b5c59, 0x270fcfc, 0xfad0ecc, 0xe5de1c2, 0xeab466b, 0x2fc513c, 0x407f75c, 0xbaab133, + 0x9705fe9, 0xb88b8e7, 0x734c993, 0x1e1ff8f, 0x19156970, 0xabd0f00, 0x10469ea7, 0x3293ac0, 0xcdc98aa, + 0x1d843fd, 0xe14bfe8, 0x15be825f, 0x8b5212, 0xeb3fb67, 0x81cbd29, 0xbc62f16, 0x2b6fcc7, 0xf5a4e29, + 0x13560b66, 0xc0b6ac2, 0x51ae690, 0xd41e271, 0xf3e9bd4, 0x1d70aab, 0x1029f72, 0x73e1c35, 0xee70fbc, + 0xad81baf, 0x9ecc49a, 0x86c741e, 0xfe6be30, 0x176752e7, 0x23d416, 0x1f83de85, 0x27de188, 0x66f70b8, + 0x181cd51f, 0x96b6e4c, 0x188f2335, 0xa5df759, 0x17a77eb6, 0xfeb0e73, 0x154ae914, 0x2f3ec51, 0x3826b59, + 0xb91f17d, 0x1c72949, 0x1362bf0a, 0xe23fddf, 0xa5614b0, 0xf7d8f, 0x79061, 0x823d9d2, 0x8213f39, + 0x1128ae0b, 0xd095d05, 0xb85c0c2, 0x1ecb2ef, 0x24ddc84, 0xe35e901, 0x18411a4a, 0xf5ddc3d, 0x3786689, + 0x52260e8, 0x5ae3564, 0x542b10d, 0x8d93a45, 0x19952aa4, 0x996cc41, 0x1051a729, 0x4be3499, 0x52b23aa, + 0x109f307e, 0x6f5b6bb, 0x1f84e1e7, 0x77a0cfa, 0x10c4df3f, 0x25a02ea, 0xb048035, 0xe31de66, 0xc6ecaa3, + 0x28ea335, 0x2886024, 0x1372f020, 0xf55d35, 0x15e4684c, 0xf2a9e17, 0x1a4a7529, 0xcb7beb1, 0xb2a78a1, + 0x1ab21f1f, 0x6361ccf, 0x6c9179d, 0xb135627, 0x1267b974, 0x4408bad, 0x1cbff658, 0xe3d6511, 0xc7d76f, + 0x1cc7a69, 0xe7ee31b, 0x54fab4f, 0x2b914f, 0x1ad27a30, 0xcd3579e, 0xc50124c, 0x50daa90, 0xb13f72, + 0xb06aa75, 0x70f5cc6, 0x1649e5aa, 0x84a5312, 0x329043c, 0x41c4011, 0x13d32411, 0xb04a838, 0xd760d2d, + 0x1713b532, 0xbaa0c03, 0x84022ab, 0x6bcf5c1, 0x2f45379, 0x18ae070, 0x18c9e11e, 0x20bca9a, 0x66f496b, + 0x3eef294, 0x67500d2, 0xd7f613c, 0x2dbbeb, 0xb741038, 0xe04133f, 0x1582968d, 0xbe985f7, 0x1acbc1a, + 0x1a6a939f, 0x33e50f6, 0xd665ed4, 0xb4b7bd6, 0x1e5a3799, 0x6b33847, 0x17fa56ff, 0x65ef930, 0x21dc4a, + 0x2b37659, 0x450fe17, 0xb357b65, 0xdf5efac, 0x15397bef, 0x9d35a7f, 0x112ac15f, 0x624e62e, 0xa90ae2f, + 0x107eecd2, 0x1f69bbe, 0x77d6bce, 0x5741394, 0x13c684fc, 0x950c910, 0x725522b, 0xdc78583, 0x40eeabb, + 0x1fde328a, 0xbd61d96, 0xd28c387, 0x9e77d89, 0x12550c40, 0x759cb7d, 0x367ef34, 0xae2a960, 0x91b8bdc, + 0x93462a9, 0xf469ef, 0xb2e9aef, 0xd2ca771, 0x54e1f42, 0x7aaa49, 0x6316abb, 0x2413c8e, 0x5425bf9, + 0x1bed3e3a, 0xf272274, 0x1f5e7326, 0x6416517, 0xea27072, 0x9cedea7, 0x6e7633, 0x7c91952, 0xd806dce, + 0x8e2a7e1, 0xe421e1a, 0x418c9e1, 0x1dbc890, 0x1b395c36, 0xa1dc175, 0x1dc4ef73, 0x8956f34, 0xe4b5cf2, + 0x1b0d3a18, 0x3194a36, 0x6c2641f, 0xe44124c, 0xa2f4eaa, 0xa8c25ba, 0xf927ed7, 0x627b614, 0x7371cca, + 0xba16694, 0x417bc03, 0x7c0a7e3, 0x9c35c19, 0x1168a205, 0x8b6b00d, 0x10e3edc9, 0x9c19bf2, 0x5882229, + 0x1b2b4162, 0xa5cef1a, 0x1543622b, 0x9bd433e, 0x364e04d, 0x7480792, 0x5c9b5b3, 0xe85ff25, 0x408ef57, + 0x1814cfa4, 0x121b41b, 0xd248a0f, 0x3b05222, 0x39bb16a, 0xc75966d, 0xa038113, 0xa4a1769, 0x11fbc6c, + 0x917e50e, 0xeec3da8, 0x169d6eac, 0x10c1699, 0xa416153, 0xf724912, 0x15cd60b7, 0x4acbad9, 0x5efc5fa, + 0xf150ed7, 0x122b51, 0x1104b40a, 0xcb7f442, 0xfbb28ff, 0x6ac53ca, 0x196142cc, 0x7bf0fa9, 0x957651, + 0x4e0f215, 0xed439f8, 0x3f46bd5, 0x5ace82f, 0x110916b6, 0x6db078, 0xffd7d57, 0xf2ecaac, 0xca86dec, + 0x15d6b2da, 0x965ecc9, 0x1c92b4c2, 0x1f3811, 0x1cb080f5, 0x2d8b804, 0x19d1c12d, 0xf20bd46, 0x1951fa7, + 0xa3656c3, 0x523a425, 0xfcd0692, 0xd44ddc8, 0x131f0f5b, 0xaf80e4a, 0xcd9fc74, 0x99bb618, 0x2db944c, + 0xa673090, 0x1c210e1, 0x178c8d23, 0x1474383, 0x10b8743d, 0x985a55b, 0x2e74779, 0x576138, 0x9587927, + 0x133130fa, 0xbe05516, 0x9f4d619, 0xbb62570, 0x99ec591, 0xd9468fe, 0x1d07782d, 0xfc72e0b, 0x701b298, + 0x1863863b, 0x85954b8, 0x121a0c36, 0x9e7fedf, 0xf64b429, 0x9b9d71e, 0x14e2f5d8, 0xf858d3a, 0x942eea8, + 0xda5b765, 0x6edafff, 0xa9d18cc, 0xc65e4ba, 0x1c747e86, 0xe4ea915, 0x1981d7a1, 0x8395659, 0x52ed4e2, + 0x87d43b7, 0x37ab11b, 0x19d292ce, 0xf8d4692, 0x18c3053f, 0x8863e13, 0x4c146c0, 0x6bdf55a, 0x4e4457d, + 0x16152289, 0xac78ec2, 0x1a59c5a2, 0x2028b97, 0x71c2d01, 0x295851f, 0x404747b, 0x878558d, 0x7d29aa4, + 0x13d8341f, 0x8daefd7, 0x139c972d, 0x6b7ea75, 0xd4a9dde, 0xff163d8, 0x81d55d7, 0xa5bef68, 0xb7b30d8, + 0xbe73d6f, 0xaa88141, 0xd976c81, 0x7e7a9cc, 0x18beb771, 0xd773cbd, 0x13f51951, 0x9d0c177, 0x1c49a78, +} + +// Field element operations: + +// nonZeroToAllOnes returns: +// 0xffffffff for 0 < x <= 2**31 +// 0 for x == 0 or x > 2**31. +func nonZeroToAllOnes(x uint32) uint32 { + return ((x - 1) >> 31) - 1 +} + +// p256ReduceCarry adds a multiple of p in order to cancel |carry|, +// which is a term at 2**257. +// +// On entry: carry < 2**3, inout[0,2,...] < 2**29, inout[1,3,...] < 2**28. +// On exit: inout[0,2,..] < 2**30, inout[1,3,...] < 2**29. +func p256ReduceCarry(inout *[p256Limbs]uint32, carry uint32) { + carry_mask := nonZeroToAllOnes(carry) + + inout[0] += carry << 1 + inout[3] += 0x10000000 & carry_mask + // carry < 2**3 thus (carry << 11) < 2**14 and we added 2**28 in the + // previous line therefore this doesn't underflow. + inout[3] -= carry << 11 + inout[4] += (0x20000000 - 1) & carry_mask + inout[5] += (0x10000000 - 1) & carry_mask + inout[6] += (0x20000000 - 1) & carry_mask + inout[6] -= carry << 22 + // This may underflow if carry is non-zero but, if so, we'll fix it in the + // next line. + inout[7] -= 1 & carry_mask + inout[7] += carry << 25 +} + +// p256Sum sets out = in+in2. +// +// On entry, in[i]+in2[i] must not overflow a 32-bit word. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29 +func p256Sum(out, in, in2 *[p256Limbs]uint32) { + carry := uint32(0) + for i := 0; ; i++ { + out[i] = in[i] + in2[i] + out[i] += carry + carry = out[i] >> 29 + out[i] &= bottom29Bits + + i++ + if i == p256Limbs { + break + } + + out[i] = in[i] + in2[i] + out[i] += carry + carry = out[i] >> 28 + out[i] &= bottom28Bits + } + + p256ReduceCarry(out, carry) +} + +const ( + two30m2 = 1<<30 - 1<<2 + two30p13m2 = 1<<30 + 1<<13 - 1<<2 + two31m2 = 1<<31 - 1<<2 + two31p24m2 = 1<<31 + 1<<24 - 1<<2 + two30m27m2 = 1<<30 - 1<<27 - 1<<2 +) + +// p256Zero31 is 0 mod p. +var p256Zero31 = [p256Limbs]uint32{two31m3, two30m2, two31m2, two30p13m2, two31m2, two30m2, two31p24m2, two30m27m2, two31m2} + +// p256Diff sets out = in-in2. +// +// On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29 and +// in2[0,2,...] < 2**30, in2[1,3,...] < 2**29. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +func p256Diff(out, in, in2 *[p256Limbs]uint32) { + var carry uint32 + + for i := 0; ; i++ { + out[i] = in[i] - in2[i] + out[i] += p256Zero31[i] + out[i] += carry + carry = out[i] >> 29 + out[i] &= bottom29Bits + + i++ + if i == p256Limbs { + break + } + + out[i] = in[i] - in2[i] + out[i] += p256Zero31[i] + out[i] += carry + carry = out[i] >> 28 + out[i] &= bottom28Bits + } + + p256ReduceCarry(out, carry) +} + +// p256ReduceDegree sets out = tmp/R mod p where tmp contains 64-bit words with +// the same 29,28,... bit positions as an field element. +// +// The values in field elements are in Montgomery form: x*R mod p where R = +// 2**257. Since we just multiplied two Montgomery values together, the result +// is x*y*R*R mod p. We wish to divide by R in order for the result also to be +// in Montgomery form. +// +// On entry: tmp[i] < 2**64 +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29 +func p256ReduceDegree(out *[p256Limbs]uint32, tmp [17]uint64) { + // The following table may be helpful when reading this code: + // + // Limb number: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10... + // Width (bits): 29| 28| 29| 28| 29| 28| 29| 28| 29| 28| 29 + // Start bit: 0 | 29| 57| 86|114|143|171|200|228|257|285 + // (odd phase): 0 | 28| 57| 85|114|142|171|199|228|256|285 + var tmp2 [18]uint32 + var carry, x, xMask uint32 + + // tmp contains 64-bit words with the same 29,28,29-bit positions as an + // field element. So the top of an element of tmp might overlap with + // another element two positions down. The following loop eliminates + // this overlap. + tmp2[0] = uint32(tmp[0]) & bottom29Bits + + tmp2[1] = uint32(tmp[0]) >> 29 + tmp2[1] |= (uint32(tmp[0]>>32) << 3) & bottom28Bits + tmp2[1] += uint32(tmp[1]) & bottom28Bits + carry = tmp2[1] >> 28 + tmp2[1] &= bottom28Bits + + for i := 2; i < 17; i++ { + tmp2[i] = (uint32(tmp[i-2] >> 32)) >> 25 + tmp2[i] += (uint32(tmp[i-1])) >> 28 + tmp2[i] += (uint32(tmp[i-1]>>32) << 4) & bottom29Bits + tmp2[i] += uint32(tmp[i]) & bottom29Bits + tmp2[i] += carry + carry = tmp2[i] >> 29 + tmp2[i] &= bottom29Bits + + i++ + if i == 17 { + break + } + tmp2[i] = uint32(tmp[i-2]>>32) >> 25 + tmp2[i] += uint32(tmp[i-1]) >> 29 + tmp2[i] += ((uint32(tmp[i-1] >> 32)) << 3) & bottom28Bits + tmp2[i] += uint32(tmp[i]) & bottom28Bits + tmp2[i] += carry + carry = tmp2[i] >> 28 + tmp2[i] &= bottom28Bits + } + + tmp2[17] = uint32(tmp[15]>>32) >> 25 + tmp2[17] += uint32(tmp[16]) >> 29 + tmp2[17] += uint32(tmp[16]>>32) << 3 + tmp2[17] += carry + + // Montgomery elimination of terms: + // + // Since R is 2**257, we can divide by R with a bitwise shift if we can + // ensure that the right-most 257 bits are all zero. We can make that true + // by adding multiplies of p without affecting the value. + // + // So we eliminate limbs from right to left. Since the bottom 29 bits of p + // are all ones, then by adding tmp2[0]*p to tmp2 we'll make tmp2[0] == 0. + // We can do that for 8 further limbs and then right shift to eliminate the + // extra factor of R. + for i := 0; ; i += 2 { + tmp2[i+1] += tmp2[i] >> 29 + x = tmp2[i] & bottom29Bits + xMask = nonZeroToAllOnes(x) + tmp2[i] = 0 + + // The bounds calculations for this loop are tricky. Each iteration of + // the loop eliminates two words by adding values to words to their + // right. + // + // The following table contains the amounts added to each word (as an + // offset from the value of i at the top of the loop). The amounts are + // accounted for from the first and second half of the loop separately + // and are written as, for example, 28 to mean a value <2**28. + // + // Word: 3 4 5 6 7 8 9 10 + // Added in top half: 28 11 29 21 29 28 + // 28 29 + // 29 + // Added in bottom half: 29 10 28 21 28 28 + // 29 + // + // The value that is currently offset 7 will be offset 5 for the next + // iteration and then offset 3 for the iteration after that. Therefore + // the total value added will be the values added at 7, 5 and 3. + // + // The following table accumulates these values. The sums at the bottom + // are written as, for example, 29+28, to mean a value < 2**29+2**28. + // + // Word: 3 4 5 6 7 8 9 10 11 12 13 + // 28 11 10 29 21 29 28 28 28 28 28 + // 29 28 11 28 29 28 29 28 29 28 + // 29 28 21 21 29 21 29 21 + // 10 29 28 21 28 21 28 + // 28 29 28 29 28 29 28 + // 11 10 29 10 29 10 + // 29 28 11 28 11 + // 29 29 + // -------------------------------------------- + // 30+ 31+ 30+ 31+ 30+ + // 28+ 29+ 28+ 29+ 21+ + // 21+ 28+ 21+ 28+ 10 + // 10 21+ 10 21+ + // 11 11 + // + // So the greatest amount is added to tmp2[10] and tmp2[12]. If + // tmp2[10/12] has an initial value of <2**29, then the maximum value + // will be < 2**31 + 2**30 + 2**28 + 2**21 + 2**11, which is < 2**32, + // as required. + tmp2[i+3] += (x << 10) & bottom28Bits + tmp2[i+4] += (x >> 18) + + tmp2[i+6] += (x << 21) & bottom29Bits + tmp2[i+7] += x >> 8 + + // At position 200, which is the starting bit position for word 7, we + // have a factor of 0xf000000 = 2**28 - 2**24. + tmp2[i+7] += 0x10000000 & xMask + tmp2[i+8] += (x - 1) & xMask + tmp2[i+7] -= (x << 24) & bottom28Bits + tmp2[i+8] -= x >> 4 + + tmp2[i+8] += 0x20000000 & xMask + tmp2[i+8] -= x + tmp2[i+8] += (x << 28) & bottom29Bits + tmp2[i+9] += ((x >> 1) - 1) & xMask + + if i+1 == p256Limbs { + break + } + tmp2[i+2] += tmp2[i+1] >> 28 + x = tmp2[i+1] & bottom28Bits + xMask = nonZeroToAllOnes(x) + tmp2[i+1] = 0 + + tmp2[i+4] += (x << 11) & bottom29Bits + tmp2[i+5] += (x >> 18) + + tmp2[i+7] += (x << 21) & bottom28Bits + tmp2[i+8] += x >> 7 + + // At position 199, which is the starting bit of the 8th word when + // dealing with a context starting on an odd word, we have a factor of + // 0x1e000000 = 2**29 - 2**25. Since we have not updated i, the 8th + // word from i+1 is i+8. + tmp2[i+8] += 0x20000000 & xMask + tmp2[i+9] += (x - 1) & xMask + tmp2[i+8] -= (x << 25) & bottom29Bits + tmp2[i+9] -= x >> 4 + + tmp2[i+9] += 0x10000000 & xMask + tmp2[i+9] -= x + tmp2[i+10] += (x - 1) & xMask + } + + // We merge the right shift with a carry chain. The words above 2**257 have + // widths of 28,29,... which we need to correct when copying them down. + carry = 0 + for i := 0; i < 8; i++ { + // The maximum value of tmp2[i + 9] occurs on the first iteration and + // is < 2**30+2**29+2**28. Adding 2**29 (from tmp2[i + 10]) is + // therefore safe. + out[i] = tmp2[i+9] + out[i] += carry + out[i] += (tmp2[i+10] << 28) & bottom29Bits + carry = out[i] >> 29 + out[i] &= bottom29Bits + + i++ + out[i] = tmp2[i+9] >> 1 + out[i] += carry + carry = out[i] >> 28 + out[i] &= bottom28Bits + } + + out[8] = tmp2[17] + out[8] += carry + carry = out[8] >> 29 + out[8] &= bottom29Bits + + p256ReduceCarry(out, carry) +} + +// p256Square sets out=in*in. +// +// On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +func p256Square(out, in *[p256Limbs]uint32) { + var tmp [17]uint64 + + tmp[0] = uint64(in[0]) * uint64(in[0]) + tmp[1] = uint64(in[0]) * (uint64(in[1]) << 1) + tmp[2] = uint64(in[0])*(uint64(in[2])<<1) + + uint64(in[1])*(uint64(in[1])<<1) + tmp[3] = uint64(in[0])*(uint64(in[3])<<1) + + uint64(in[1])*(uint64(in[2])<<1) + tmp[4] = uint64(in[0])*(uint64(in[4])<<1) + + uint64(in[1])*(uint64(in[3])<<2) + + uint64(in[2])*uint64(in[2]) + tmp[5] = uint64(in[0])*(uint64(in[5])<<1) + + uint64(in[1])*(uint64(in[4])<<1) + + uint64(in[2])*(uint64(in[3])<<1) + tmp[6] = uint64(in[0])*(uint64(in[6])<<1) + + uint64(in[1])*(uint64(in[5])<<2) + + uint64(in[2])*(uint64(in[4])<<1) + + uint64(in[3])*(uint64(in[3])<<1) + tmp[7] = uint64(in[0])*(uint64(in[7])<<1) + + uint64(in[1])*(uint64(in[6])<<1) + + uint64(in[2])*(uint64(in[5])<<1) + + uint64(in[3])*(uint64(in[4])<<1) + // tmp[8] has the greatest value of 2**61 + 2**60 + 2**61 + 2**60 + 2**60, + // which is < 2**64 as required. + tmp[8] = uint64(in[0])*(uint64(in[8])<<1) + + uint64(in[1])*(uint64(in[7])<<2) + + uint64(in[2])*(uint64(in[6])<<1) + + uint64(in[3])*(uint64(in[5])<<2) + + uint64(in[4])*uint64(in[4]) + tmp[9] = uint64(in[1])*(uint64(in[8])<<1) + + uint64(in[2])*(uint64(in[7])<<1) + + uint64(in[3])*(uint64(in[6])<<1) + + uint64(in[4])*(uint64(in[5])<<1) + tmp[10] = uint64(in[2])*(uint64(in[8])<<1) + + uint64(in[3])*(uint64(in[7])<<2) + + uint64(in[4])*(uint64(in[6])<<1) + + uint64(in[5])*(uint64(in[5])<<1) + tmp[11] = uint64(in[3])*(uint64(in[8])<<1) + + uint64(in[4])*(uint64(in[7])<<1) + + uint64(in[5])*(uint64(in[6])<<1) + tmp[12] = uint64(in[4])*(uint64(in[8])<<1) + + uint64(in[5])*(uint64(in[7])<<2) + + uint64(in[6])*uint64(in[6]) + tmp[13] = uint64(in[5])*(uint64(in[8])<<1) + + uint64(in[6])*(uint64(in[7])<<1) + tmp[14] = uint64(in[6])*(uint64(in[8])<<1) + + uint64(in[7])*(uint64(in[7])<<1) + tmp[15] = uint64(in[7]) * (uint64(in[8]) << 1) + tmp[16] = uint64(in[8]) * uint64(in[8]) + + p256ReduceDegree(out, tmp) +} + +// p256Mul sets out=in*in2. +// +// On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29 and +// in2[0,2,...] < 2**30, in2[1,3,...] < 2**29. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +func p256Mul(out, in, in2 *[p256Limbs]uint32) { + var tmp [17]uint64 + + tmp[0] = uint64(in[0]) * uint64(in2[0]) + tmp[1] = uint64(in[0])*(uint64(in2[1])<<0) + + uint64(in[1])*(uint64(in2[0])<<0) + tmp[2] = uint64(in[0])*(uint64(in2[2])<<0) + + uint64(in[1])*(uint64(in2[1])<<1) + + uint64(in[2])*(uint64(in2[0])<<0) + tmp[3] = uint64(in[0])*(uint64(in2[3])<<0) + + uint64(in[1])*(uint64(in2[2])<<0) + + uint64(in[2])*(uint64(in2[1])<<0) + + uint64(in[3])*(uint64(in2[0])<<0) + tmp[4] = uint64(in[0])*(uint64(in2[4])<<0) + + uint64(in[1])*(uint64(in2[3])<<1) + + uint64(in[2])*(uint64(in2[2])<<0) + + uint64(in[3])*(uint64(in2[1])<<1) + + uint64(in[4])*(uint64(in2[0])<<0) + tmp[5] = uint64(in[0])*(uint64(in2[5])<<0) + + uint64(in[1])*(uint64(in2[4])<<0) + + uint64(in[2])*(uint64(in2[3])<<0) + + uint64(in[3])*(uint64(in2[2])<<0) + + uint64(in[4])*(uint64(in2[1])<<0) + + uint64(in[5])*(uint64(in2[0])<<0) + tmp[6] = uint64(in[0])*(uint64(in2[6])<<0) + + uint64(in[1])*(uint64(in2[5])<<1) + + uint64(in[2])*(uint64(in2[4])<<0) + + uint64(in[3])*(uint64(in2[3])<<1) + + uint64(in[4])*(uint64(in2[2])<<0) + + uint64(in[5])*(uint64(in2[1])<<1) + + uint64(in[6])*(uint64(in2[0])<<0) + tmp[7] = uint64(in[0])*(uint64(in2[7])<<0) + + uint64(in[1])*(uint64(in2[6])<<0) + + uint64(in[2])*(uint64(in2[5])<<0) + + uint64(in[3])*(uint64(in2[4])<<0) + + uint64(in[4])*(uint64(in2[3])<<0) + + uint64(in[5])*(uint64(in2[2])<<0) + + uint64(in[6])*(uint64(in2[1])<<0) + + uint64(in[7])*(uint64(in2[0])<<0) + // tmp[8] has the greatest value but doesn't overflow. See logic in + // p256Square. + tmp[8] = uint64(in[0])*(uint64(in2[8])<<0) + + uint64(in[1])*(uint64(in2[7])<<1) + + uint64(in[2])*(uint64(in2[6])<<0) + + uint64(in[3])*(uint64(in2[5])<<1) + + uint64(in[4])*(uint64(in2[4])<<0) + + uint64(in[5])*(uint64(in2[3])<<1) + + uint64(in[6])*(uint64(in2[2])<<0) + + uint64(in[7])*(uint64(in2[1])<<1) + + uint64(in[8])*(uint64(in2[0])<<0) + tmp[9] = uint64(in[1])*(uint64(in2[8])<<0) + + uint64(in[2])*(uint64(in2[7])<<0) + + uint64(in[3])*(uint64(in2[6])<<0) + + uint64(in[4])*(uint64(in2[5])<<0) + + uint64(in[5])*(uint64(in2[4])<<0) + + uint64(in[6])*(uint64(in2[3])<<0) + + uint64(in[7])*(uint64(in2[2])<<0) + + uint64(in[8])*(uint64(in2[1])<<0) + tmp[10] = uint64(in[2])*(uint64(in2[8])<<0) + + uint64(in[3])*(uint64(in2[7])<<1) + + uint64(in[4])*(uint64(in2[6])<<0) + + uint64(in[5])*(uint64(in2[5])<<1) + + uint64(in[6])*(uint64(in2[4])<<0) + + uint64(in[7])*(uint64(in2[3])<<1) + + uint64(in[8])*(uint64(in2[2])<<0) + tmp[11] = uint64(in[3])*(uint64(in2[8])<<0) + + uint64(in[4])*(uint64(in2[7])<<0) + + uint64(in[5])*(uint64(in2[6])<<0) + + uint64(in[6])*(uint64(in2[5])<<0) + + uint64(in[7])*(uint64(in2[4])<<0) + + uint64(in[8])*(uint64(in2[3])<<0) + tmp[12] = uint64(in[4])*(uint64(in2[8])<<0) + + uint64(in[5])*(uint64(in2[7])<<1) + + uint64(in[6])*(uint64(in2[6])<<0) + + uint64(in[7])*(uint64(in2[5])<<1) + + uint64(in[8])*(uint64(in2[4])<<0) + tmp[13] = uint64(in[5])*(uint64(in2[8])<<0) + + uint64(in[6])*(uint64(in2[7])<<0) + + uint64(in[7])*(uint64(in2[6])<<0) + + uint64(in[8])*(uint64(in2[5])<<0) + tmp[14] = uint64(in[6])*(uint64(in2[8])<<0) + + uint64(in[7])*(uint64(in2[7])<<1) + + uint64(in[8])*(uint64(in2[6])<<0) + tmp[15] = uint64(in[7])*(uint64(in2[8])<<0) + + uint64(in[8])*(uint64(in2[7])<<0) + tmp[16] = uint64(in[8]) * (uint64(in2[8]) << 0) + + p256ReduceDegree(out, tmp) +} + +func p256Assign(out, in *[p256Limbs]uint32) { + *out = *in +} + +// p256Invert calculates |out| = |in|^{-1} +// +// Based on Fermat's Little Theorem: +// a^p = a (mod p) +// a^{p-1} = 1 (mod p) +// a^{p-2} = a^{-1} (mod p) +func p256Invert(out, in *[p256Limbs]uint32) { + var ftmp, ftmp2 [p256Limbs]uint32 + + // each e_I will hold |in|^{2^I - 1} + var e2, e4, e8, e16, e32, e64 [p256Limbs]uint32 + + p256Square(&ftmp, in) // 2^1 + p256Mul(&ftmp, in, &ftmp) // 2^2 - 2^0 + p256Assign(&e2, &ftmp) + p256Square(&ftmp, &ftmp) // 2^3 - 2^1 + p256Square(&ftmp, &ftmp) // 2^4 - 2^2 + p256Mul(&ftmp, &ftmp, &e2) // 2^4 - 2^0 + p256Assign(&e4, &ftmp) + p256Square(&ftmp, &ftmp) // 2^5 - 2^1 + p256Square(&ftmp, &ftmp) // 2^6 - 2^2 + p256Square(&ftmp, &ftmp) // 2^7 - 2^3 + p256Square(&ftmp, &ftmp) // 2^8 - 2^4 + p256Mul(&ftmp, &ftmp, &e4) // 2^8 - 2^0 + p256Assign(&e8, &ftmp) + for i := 0; i < 8; i++ { + p256Square(&ftmp, &ftmp) + } // 2^16 - 2^8 + p256Mul(&ftmp, &ftmp, &e8) // 2^16 - 2^0 + p256Assign(&e16, &ftmp) + for i := 0; i < 16; i++ { + p256Square(&ftmp, &ftmp) + } // 2^32 - 2^16 + p256Mul(&ftmp, &ftmp, &e16) // 2^32 - 2^0 + p256Assign(&e32, &ftmp) + for i := 0; i < 32; i++ { + p256Square(&ftmp, &ftmp) + } // 2^64 - 2^32 + p256Assign(&e64, &ftmp) + p256Mul(&ftmp, &ftmp, in) // 2^64 - 2^32 + 2^0 + for i := 0; i < 192; i++ { + p256Square(&ftmp, &ftmp) + } // 2^256 - 2^224 + 2^192 + + p256Mul(&ftmp2, &e64, &e32) // 2^64 - 2^0 + for i := 0; i < 16; i++ { + p256Square(&ftmp2, &ftmp2) + } // 2^80 - 2^16 + p256Mul(&ftmp2, &ftmp2, &e16) // 2^80 - 2^0 + for i := 0; i < 8; i++ { + p256Square(&ftmp2, &ftmp2) + } // 2^88 - 2^8 + p256Mul(&ftmp2, &ftmp2, &e8) // 2^88 - 2^0 + for i := 0; i < 4; i++ { + p256Square(&ftmp2, &ftmp2) + } // 2^92 - 2^4 + p256Mul(&ftmp2, &ftmp2, &e4) // 2^92 - 2^0 + p256Square(&ftmp2, &ftmp2) // 2^93 - 2^1 + p256Square(&ftmp2, &ftmp2) // 2^94 - 2^2 + p256Mul(&ftmp2, &ftmp2, &e2) // 2^94 - 2^0 + p256Square(&ftmp2, &ftmp2) // 2^95 - 2^1 + p256Square(&ftmp2, &ftmp2) // 2^96 - 2^2 + p256Mul(&ftmp2, &ftmp2, in) // 2^96 - 3 + + p256Mul(out, &ftmp2, &ftmp) // 2^256 - 2^224 + 2^192 + 2^96 - 3 +} + +// p256Scalar3 sets out=3*out. +// +// On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +func p256Scalar3(out *[p256Limbs]uint32) { + var carry uint32 + + for i := 0; ; i++ { + out[i] *= 3 + out[i] += carry + carry = out[i] >> 29 + out[i] &= bottom29Bits + + i++ + if i == p256Limbs { + break + } + + out[i] *= 3 + out[i] += carry + carry = out[i] >> 28 + out[i] &= bottom28Bits + } + + p256ReduceCarry(out, carry) +} + +// p256Scalar4 sets out=4*out. +// +// On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +func p256Scalar4(out *[p256Limbs]uint32) { + var carry, nextCarry uint32 + + for i := 0; ; i++ { + nextCarry = out[i] >> 27 + out[i] <<= 2 + out[i] &= bottom29Bits + out[i] += carry + carry = nextCarry + (out[i] >> 29) + out[i] &= bottom29Bits + + i++ + if i == p256Limbs { + break + } + nextCarry = out[i] >> 26 + out[i] <<= 2 + out[i] &= bottom28Bits + out[i] += carry + carry = nextCarry + (out[i] >> 28) + out[i] &= bottom28Bits + } + + p256ReduceCarry(out, carry) +} + +// p256Scalar8 sets out=8*out. +// +// On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +// On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. +func p256Scalar8(out *[p256Limbs]uint32) { + var carry, nextCarry uint32 + + for i := 0; ; i++ { + nextCarry = out[i] >> 26 + out[i] <<= 3 + out[i] &= bottom29Bits + out[i] += carry + carry = nextCarry + (out[i] >> 29) + out[i] &= bottom29Bits + + i++ + if i == p256Limbs { + break + } + nextCarry = out[i] >> 25 + out[i] <<= 3 + out[i] &= bottom28Bits + out[i] += carry + carry = nextCarry + (out[i] >> 28) + out[i] &= bottom28Bits + } + + p256ReduceCarry(out, carry) +} + +// Group operations: +// +// Elements of the elliptic curve group are represented in Jacobian +// coordinates: (x, y, z). An affine point (x', y') is x'=x/z**2, y'=y/z**3 in +// Jacobian form. + +// 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 +func p256PointDouble(xOut, yOut, zOut, x, y, z *[p256Limbs]uint32) { + var delta, gamma, alpha, beta, tmp, tmp2 [p256Limbs]uint32 + + p256Square(&delta, z) + p256Square(&gamma, y) + p256Mul(&beta, x, &gamma) + + p256Sum(&tmp, x, &delta) + p256Diff(&tmp2, x, &delta) + p256Mul(&alpha, &tmp, &tmp2) + p256Scalar3(&alpha) + + p256Sum(&tmp, y, z) + p256Square(&tmp, &tmp) + p256Diff(&tmp, &tmp, &gamma) + p256Diff(zOut, &tmp, &delta) + + p256Scalar4(&beta) + p256Square(xOut, &alpha) + p256Diff(xOut, xOut, &beta) + p256Diff(xOut, xOut, &beta) + + p256Diff(&tmp, &beta, xOut) + p256Mul(&tmp, &alpha, &tmp) + p256Square(&tmp2, &gamma) + p256Scalar8(&tmp2) + p256Diff(yOut, &tmp, &tmp2) +} + +// 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 +// +// Note that this function does not handle P+P, infinity+P nor P+infinity +// correctly. +func p256PointAddMixed(xOut, yOut, zOut, x1, y1, z1, x2, y2 *[p256Limbs]uint32) { + var z1z1, z1z1z1, s2, u2, h, i, j, r, rr, v, tmp [p256Limbs]uint32 + + p256Square(&z1z1, z1) + p256Sum(&tmp, z1, z1) + + p256Mul(&u2, x2, &z1z1) + p256Mul(&z1z1z1, z1, &z1z1) + p256Mul(&s2, y2, &z1z1z1) + p256Diff(&h, &u2, x1) + p256Sum(&i, &h, &h) + p256Square(&i, &i) + p256Mul(&j, &h, &i) + p256Diff(&r, &s2, y1) + p256Sum(&r, &r, &r) + p256Mul(&v, x1, &i) + + p256Mul(zOut, &tmp, &h) + p256Square(&rr, &r) + p256Diff(xOut, &rr, &j) + p256Diff(xOut, xOut, &v) + p256Diff(xOut, xOut, &v) + + p256Diff(&tmp, &v, xOut) + p256Mul(yOut, &tmp, &r) + p256Mul(&tmp, y1, &j) + p256Diff(yOut, yOut, &tmp) + p256Diff(yOut, yOut, &tmp) +} + +// 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 +// +// Note that this function does not handle P+P, infinity+P nor P+infinity +// correctly. +func p256PointAdd(xOut, yOut, zOut, x1, y1, z1, x2, y2, z2 *[p256Limbs]uint32) { + var z1z1, z1z1z1, z2z2, z2z2z2, s1, s2, u1, u2, h, i, j, r, rr, v, tmp [p256Limbs]uint32 + + p256Square(&z1z1, z1) + p256Square(&z2z2, z2) + p256Mul(&u1, x1, &z2z2) + + p256Sum(&tmp, z1, z2) + p256Square(&tmp, &tmp) + p256Diff(&tmp, &tmp, &z1z1) + p256Diff(&tmp, &tmp, &z2z2) + + p256Mul(&z2z2z2, z2, &z2z2) + p256Mul(&s1, y1, &z2z2z2) + + p256Mul(&u2, x2, &z1z1) + p256Mul(&z1z1z1, z1, &z1z1) + p256Mul(&s2, y2, &z1z1z1) + p256Diff(&h, &u2, &u1) + p256Sum(&i, &h, &h) + p256Square(&i, &i) + p256Mul(&j, &h, &i) + p256Diff(&r, &s2, &s1) + p256Sum(&r, &r, &r) + p256Mul(&v, &u1, &i) + + p256Mul(zOut, &tmp, &h) + p256Square(&rr, &r) + p256Diff(xOut, &rr, &j) + p256Diff(xOut, xOut, &v) + p256Diff(xOut, xOut, &v) + + p256Diff(&tmp, &v, xOut) + p256Mul(yOut, &tmp, &r) + p256Mul(&tmp, &s1, &j) + p256Diff(yOut, yOut, &tmp) + p256Diff(yOut, yOut, &tmp) +} + +// p256CopyConditional sets out=in if mask = 0xffffffff in constant time. +// +// On entry: mask is either 0 or 0xffffffff. +func p256CopyConditional(out, in *[p256Limbs]uint32, mask uint32) { + for i := 0; i < p256Limbs; i++ { + tmp := mask & (in[i] ^ out[i]) + out[i] ^= tmp + } +} + +// p256SelectAffinePoint sets {out_x,out_y} to the index'th entry of table. +// On entry: index < 16, table[0] must be zero. +func p256SelectAffinePoint(xOut, yOut *[p256Limbs]uint32, table []uint32, index uint32) { + for i := range xOut { + xOut[i] = 0 + } + for i := range yOut { + yOut[i] = 0 + } + + for i := uint32(1); i < 16; i++ { + mask := i ^ index + mask |= mask >> 2 + mask |= mask >> 1 + mask &= 1 + mask-- + for j := range xOut { + xOut[j] |= table[0] & mask + table = table[1:] + } + for j := range yOut { + yOut[j] |= table[0] & mask + table = table[1:] + } + } +} + +// p256SelectJacobianPoint sets {out_x,out_y,out_z} to the index'th entry of +// table. +// On entry: index < 16, table[0] must be zero. +func p256SelectJacobianPoint(xOut, yOut, zOut *[p256Limbs]uint32, table *[16][3][p256Limbs]uint32, index uint32) { + for i := range xOut { + xOut[i] = 0 + } + for i := range yOut { + yOut[i] = 0 + } + for i := range zOut { + zOut[i] = 0 + } + + // The implicit value at index 0 is all zero. We don't need to perform that + // iteration of the loop because we already set out_* to zero. + for i := uint32(1); i < 16; i++ { + mask := i ^ index + mask |= mask >> 2 + mask |= mask >> 1 + mask &= 1 + mask-- + for j := range xOut { + xOut[j] |= table[i][0][j] & mask + } + for j := range yOut { + yOut[j] |= table[i][1][j] & mask + } + for j := range zOut { + zOut[j] |= table[i][2][j] & mask + } + } +} + +// p256GetBit returns the bit'th bit of scalar. +func p256GetBit(scalar *[32]uint8, bit uint) uint32 { + return uint32(((scalar[bit>>3]) >> (bit & 7)) & 1) +} + +// p256ScalarBaseMult sets {xOut,yOut,zOut} = scalar*G where scalar is a +// little-endian number. Note that the value of scalar must be less than the +// order of the group. +func p256ScalarBaseMult(xOut, yOut, zOut *[p256Limbs]uint32, scalar *[32]uint8) { + nIsInfinityMask := ^uint32(0) + var pIsNoninfiniteMask, mask, tableOffset uint32 + var px, py, tx, ty, tz [p256Limbs]uint32 + + for i := range xOut { + xOut[i] = 0 + } + for i := range yOut { + yOut[i] = 0 + } + for i := range zOut { + zOut[i] = 0 + } + + // The loop adds bits at positions 0, 64, 128 and 192, followed by + // positions 32,96,160 and 224 and does this 32 times. + for i := uint(0); i < 32; i++ { + if i != 0 { + p256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) + } + tableOffset = 0 + for j := uint(0); j <= 32; j += 32 { + bit0 := p256GetBit(scalar, 31-i+j) + bit1 := p256GetBit(scalar, 95-i+j) + bit2 := p256GetBit(scalar, 159-i+j) + bit3 := p256GetBit(scalar, 223-i+j) + index := bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3) + + p256SelectAffinePoint(&px, &py, p256Precomputed[tableOffset:], index) + tableOffset += 30 * p256Limbs + + // Since scalar is less than the order of the group, we know that + // {xOut,yOut,zOut} != {px,py,1}, unless both are zero, which we handle + // below. + p256PointAddMixed(&tx, &ty, &tz, xOut, yOut, zOut, &px, &py) + // The result of pointAddMixed is incorrect if {xOut,yOut,zOut} is zero + // (a.k.a. the point at infinity). We handle that situation by + // copying the point from the table. + p256CopyConditional(xOut, &px, nIsInfinityMask) + p256CopyConditional(yOut, &py, nIsInfinityMask) + p256CopyConditional(zOut, &p256One, nIsInfinityMask) + + // Equally, the result is also wrong if the point from the table is + // zero, which happens when the index is zero. We handle that by + // only copying from {tx,ty,tz} to {xOut,yOut,zOut} if index != 0. + pIsNoninfiniteMask = nonZeroToAllOnes(index) + mask = pIsNoninfiniteMask & ^nIsInfinityMask + p256CopyConditional(xOut, &tx, mask) + p256CopyConditional(yOut, &ty, mask) + p256CopyConditional(zOut, &tz, mask) + // If p was not zero, then n is now non-zero. + nIsInfinityMask &= ^pIsNoninfiniteMask + } + } +} + +// p256PointToAffine converts a Jacobian point to an affine point. If the input +// is the point at infinity then it returns (0, 0) in constant time. +func p256PointToAffine(xOut, yOut, x, y, z *[p256Limbs]uint32) { + var zInv, zInvSq [p256Limbs]uint32 + + p256Invert(&zInv, z) + p256Square(&zInvSq, &zInv) + p256Mul(xOut, x, &zInvSq) + p256Mul(&zInv, &zInv, &zInvSq) + p256Mul(yOut, y, &zInv) +} + +// p256ToAffine returns a pair of *big.Int containing the affine representation +// of {x,y,z}. +func p256ToAffine(x, y, z *[p256Limbs]uint32) (xOut, yOut *big.Int) { + var xx, yy [p256Limbs]uint32 + p256PointToAffine(&xx, &yy, x, y, z) + return p256ToBig(&xx), p256ToBig(&yy) +} + +// p256ScalarMult sets {xOut,yOut,zOut} = scalar*{x,y}. +func p256ScalarMult(xOut, yOut, zOut, x, y *[p256Limbs]uint32, scalar *[32]uint8) { + var px, py, pz, tx, ty, tz [p256Limbs]uint32 + var precomp [16][3][p256Limbs]uint32 + var nIsInfinityMask, index, pIsNoninfiniteMask, mask uint32 + + // We precompute 0,1,2,... times {x,y}. + precomp[1][0] = *x + precomp[1][1] = *y + precomp[1][2] = p256One + + for i := 2; i < 16; i += 2 { + p256PointDouble(&precomp[i][0], &precomp[i][1], &precomp[i][2], &precomp[i/2][0], &precomp[i/2][1], &precomp[i/2][2]) + p256PointAddMixed(&precomp[i+1][0], &precomp[i+1][1], &precomp[i+1][2], &precomp[i][0], &precomp[i][1], &precomp[i][2], x, y) + } + + for i := range xOut { + xOut[i] = 0 + } + for i := range yOut { + yOut[i] = 0 + } + for i := range zOut { + zOut[i] = 0 + } + nIsInfinityMask = ^uint32(0) + + // We add in a window of four bits each iteration and do this 64 times. + for i := 0; i < 64; i++ { + if i != 0 { + p256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) + p256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) + p256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) + p256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) + } + + index = uint32(scalar[31-i/2]) + if (i & 1) == 1 { + index &= 15 + } else { + index >>= 4 + } + + // See the comments in scalarBaseMult about handling infinities. + p256SelectJacobianPoint(&px, &py, &pz, &precomp, index) + p256PointAdd(&tx, &ty, &tz, xOut, yOut, zOut, &px, &py, &pz) + p256CopyConditional(xOut, &px, nIsInfinityMask) + p256CopyConditional(yOut, &py, nIsInfinityMask) + p256CopyConditional(zOut, &pz, nIsInfinityMask) + + pIsNoninfiniteMask = nonZeroToAllOnes(index) + mask = pIsNoninfiniteMask & ^nIsInfinityMask + p256CopyConditional(xOut, &tx, mask) + p256CopyConditional(yOut, &ty, mask) + p256CopyConditional(zOut, &tz, mask) + nIsInfinityMask &= ^pIsNoninfiniteMask + } +} + +// p256FromBig sets out = R*in. +func p256FromBig(out *[p256Limbs]uint32, in *big.Int) { + tmp := new(big.Int).Lsh(in, 257) + tmp.Mod(tmp, p256.P) + + for i := 0; i < p256Limbs; i++ { + if bits := tmp.Bits(); len(bits) > 0 { + out[i] = uint32(bits[0]) & bottom29Bits + } else { + out[i] = 0 + } + tmp.Rsh(tmp, 29) + + i++ + if i == p256Limbs { + break + } + + if bits := tmp.Bits(); len(bits) > 0 { + out[i] = uint32(bits[0]) & bottom28Bits + } else { + out[i] = 0 + } + tmp.Rsh(tmp, 28) + } +} + +// p256ToBig returns a *big.Int containing the value of in. +func p256ToBig(in *[p256Limbs]uint32) *big.Int { + result, tmp := new(big.Int), new(big.Int) + + result.SetInt64(int64(in[p256Limbs-1])) + for i := p256Limbs - 2; i >= 0; i-- { + if (i & 1) == 0 { + result.Lsh(result, 29) + } else { + result.Lsh(result, 28) + } + tmp.SetInt64(int64(in[i])) + result.Add(result, tmp) + } + + result.Mul(result, p256RInverse) + result.Mod(result, p256.P) + return result +} diff --git a/libgo/go/crypto/md5/gen.go b/libgo/go/crypto/md5/gen.go index 275b4aeea39..ccaa7c13d38 100644 --- a/libgo/go/crypto/md5/gen.go +++ b/libgo/go/crypto/md5/gen.go @@ -164,7 +164,7 @@ var program = ` // DO NOT EDIT. // Generate with: go run gen.go{{if .Full}} -full{{end}} | gofmt >md5block.go -// +build !amd64 +// +build !amd64,!386,!arm package md5 diff --git a/libgo/go/crypto/md5/md5.go b/libgo/go/crypto/md5/md5.go index 825e5c8a282..1a1f35fabc0 100644 --- a/libgo/go/crypto/md5/md5.go +++ b/libgo/go/crypto/md5/md5.go @@ -88,7 +88,11 @@ func (d *digest) Write(p []byte) (nn int, err error) { 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() + return append(in, hash[:]...) +} +func (d *digest) checkSum() [Size]byte { // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. len := d.len var tmp [64]byte @@ -118,5 +122,13 @@ func (d0 *digest) Sum(in []byte) []byte { digest[i*4+3] = byte(s >> 24) } - return append(in, digest[:]...) + return digest +} + +// Sum returns the MD5 checksum of the data. +func Sum(data []byte) [Size]byte { + var d digest + d.Reset() + d.Write(data) + return d.checkSum() } diff --git a/libgo/go/crypto/md5/md5_test.go b/libgo/go/crypto/md5/md5_test.go index 3ef4519b9ad..a8b7a1a5252 100644 --- a/libgo/go/crypto/md5/md5_test.go +++ b/libgo/go/crypto/md5/md5_test.go @@ -53,6 +53,10 @@ var golden = []md5Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] + s := fmt.Sprintf("%x", Sum([]byte(g.in))) + if s != g.out { + t.Fatalf("Sum function: md5(%s) = %s want %s", g.in, s, g.out) + } c := New() buf := make([]byte, len(g.in)+4) for j := 0; j < 3+4; j++ { @@ -77,12 +81,28 @@ func TestGolden(t *testing.T) { } } -func ExampleNew() { - h := New() - io.WriteString(h, "The fog is getting thicker!") - io.WriteString(h, "And Leon's getting laaarger!") - fmt.Printf("%x", h.Sum(nil)) - // Output: e2c569be17396eca2a2e3c11578123ed +func TestLarge(t *testing.T) { + const N = 10000 + ok := "2bb571599a4180e1d542f76904adc3df" // md5sum of "0123456789" * 1000 + block := make([]byte, 10004) + c := New() + for offset := 0; offset < 4; offset++ { + for i := 0; i < N; i++ { + block[offset+i] = '0' + byte(i%10) + } + for blockSize := 10; blockSize <= N; blockSize *= 10 { + blocks := N / blockSize + b := block[offset : offset+blockSize] + c.Reset() + for i := 0; i < blocks; i++ { + c.Write(b) + } + s := fmt.Sprintf("%x", c.Sum(nil)) + if s != ok { + t.Fatalf("md5 TestLarge offset=%d, blockSize=%d = %s want %s", offset, blockSize, s, ok) + } + } + } } var bench = New() diff --git a/libgo/go/crypto/md5/md5block.go b/libgo/go/crypto/md5/md5block.go index a376fbee99b..3e739e36ffd 100644 --- a/libgo/go/crypto/md5/md5block.go +++ b/libgo/go/crypto/md5/md5block.go @@ -1,7 +1,7 @@ // DO NOT EDIT. // Generate with: go run gen.go -full | gofmt >md5block.go -// +build !amd64,!386 +// +build !amd64,!386,!arm package md5 diff --git a/libgo/go/crypto/md5/md5block_decl.go b/libgo/go/crypto/md5/md5block_decl.go index 14190c6ff29..c4d6aaaf03a 100644 --- a/libgo/go/crypto/md5/md5block_decl.go +++ b/libgo/go/crypto/md5/md5block_decl.go @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64 386 +// +build amd64 386 arm package md5 +//go:noescape + func block(dig *digest, p []byte) diff --git a/libgo/go/crypto/rand/rand.go b/libgo/go/crypto/rand/rand.go index 59759038ee0..4da3adb7010 100644 --- a/libgo/go/crypto/rand/rand.go +++ b/libgo/go/crypto/rand/rand.go @@ -14,5 +14,8 @@ import "io" // On Windows systems, Reader uses the CryptGenRandom API. var Reader io.Reader -// Read is a helper function that calls Reader.Read. -func Read(b []byte) (n int, err error) { return Reader.Read(b) } +// Read is a helper function that calls Reader.Read using io.ReadFull. +// On return, n == len(b) if and only if err == nil. +func Read(b []byte) (n int, err error) { + return io.ReadFull(Reader, b) +} diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go index 18f482472d3..238ceee557d 100644 --- a/libgo/go/crypto/rand/rand_unix.go +++ b/libgo/go/crypto/rand/rand_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 darwin freebsd linux netbsd openbsd plan9 +// +build darwin dragonfly freebsd linux netbsd openbsd plan9 // Unix cryptographically secure pseudorandom number // generator. diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go index 28ca5d73b39..1a055a3d623 100644 --- a/libgo/go/crypto/rsa/pkcs1v15.go +++ b/libgo/go/crypto/rsa/pkcs1v15.go @@ -124,7 +124,11 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex) } - valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) + // The PS padding must be at least 8 bytes long, and it starts two + // bytes into em. + validPS := subtle.ConstantTimeLessOrEq(2+8, index) + + valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS msg = em[index+1:] return } diff --git a/libgo/go/crypto/rsa/pkcs1v15_test.go b/libgo/go/crypto/rsa/pkcs1v15_test.go index bf9219bae1b..70bb2288996 100644 --- a/libgo/go/crypto/rsa/pkcs1v15_test.go +++ b/libgo/go/crypto/rsa/pkcs1v15_test.go @@ -197,6 +197,14 @@ func TestVerifyPKCS1v15(t *testing.T) { } } +func TestOverlongMessagePKCS1v15(t *testing.T) { + ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==") + _, err := DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) + if err == nil { + t.Error("RSA decrypted a message that was too long.") + } +} + // In order to generate new test vectors you'll need the PEM form of this key: // -----BEGIN RSA PRIVATE KEY----- // MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 diff --git a/libgo/go/crypto/rsa/pss.go b/libgo/go/crypto/rsa/pss.go new file mode 100644 index 00000000000..f9abec39490 --- /dev/null +++ b/libgo/go/crypto/rsa/pss.go @@ -0,0 +1,282 @@ +// 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. + +package rsa + +// This file implementes the PSS signature scheme [1]. +// +// [1] http://www.rsa.com/rsalabs/pkcs/files/h11300-wp-pkcs-1v2-2-rsa-cryptography-standard.pdf + +import ( + "bytes" + "crypto" + "errors" + "hash" + "io" + "math/big" +) + +func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) { + // See [1], section 9.1.1 + hLen := hash.Size() + sLen := len(salt) + emLen := (emBits + 7) / 8 + + // 1. If the length of M is greater than the input limitation for the + // hash function (2^61 - 1 octets for SHA-1), output "message too + // long" and stop. + // + // 2. Let mHash = Hash(M), an octet string of length hLen. + + if len(mHash) != hLen { + return nil, errors.New("crypto/rsa: input must be hashed message") + } + + // 3. If emLen < hLen + sLen + 2, output "encoding error" and stop. + + if emLen < hLen+sLen+2 { + return nil, errors.New("crypto/rsa: encoding error") + } + + em := make([]byte, emLen) + db := em[:emLen-sLen-hLen-2+1+sLen] + h := em[emLen-sLen-hLen-2+1+sLen : emLen-1] + + // 4. Generate a random octet string salt of length sLen; if sLen = 0, + // then salt is the empty string. + // + // 5. Let + // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; + // + // M' is an octet string of length 8 + hLen + sLen with eight + // initial zero octets. + // + // 6. Let H = Hash(M'), an octet string of length hLen. + + var prefix [8]byte + + hash.Write(prefix[:]) + hash.Write(mHash) + hash.Write(salt) + + h = hash.Sum(h[:0]) + hash.Reset() + + // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2 + // zero octets. The length of PS may be 0. + // + // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length + // emLen - hLen - 1. + + db[emLen-sLen-hLen-2] = 0x01 + copy(db[emLen-sLen-hLen-1:], salt) + + // 9. Let dbMask = MGF(H, emLen - hLen - 1). + // + // 10. Let maskedDB = DB \xor dbMask. + + mgf1XOR(db, hash, h) + + // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in + // maskedDB to zero. + + db[0] &= (0xFF >> uint(8*emLen-emBits)) + + // 12. Let EM = maskedDB || H || 0xbc. + em[emLen-1] = 0xBC + + // 13. Output EM. + return em, nil +} + +func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error { + // 1. If the length of M is greater than the input limitation for the + // hash function (2^61 - 1 octets for SHA-1), output "inconsistent" + // and stop. + // + // 2. Let mHash = Hash(M), an octet string of length hLen. + hLen := hash.Size() + if hLen != len(mHash) { + return ErrVerification + } + + // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop. + emLen := (emBits + 7) / 8 + if emLen < hLen+sLen+2 { + return ErrVerification + } + + // 4. If the rightmost octet of EM does not have hexadecimal value + // 0xbc, output "inconsistent" and stop. + if em[len(em)-1] != 0xBC { + return ErrVerification + } + + // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and + // let H be the next hLen octets. + db := em[:emLen-hLen-1] + h := em[emLen-hLen-1 : len(em)-1] + + // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in + // maskedDB are not all equal to zero, output "inconsistent" and + // stop. + if em[0]&(0xFF<<uint(8-(8*emLen-emBits))) != 0 { + return ErrVerification + } + + // 7. Let dbMask = MGF(H, emLen - hLen - 1). + // + // 8. Let DB = maskedDB \xor dbMask. + mgf1XOR(db, hash, h) + + // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB + // to zero. + db[0] &= (0xFF >> uint(8*emLen-emBits)) + + if sLen == PSSSaltLengthAuto { + FindSaltLength: + for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- { + switch db[emLen-hLen-sLen-2] { + case 1: + break FindSaltLength + case 0: + continue + default: + return ErrVerification + } + } + if sLen < 0 { + return ErrVerification + } + } else { + // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero + // or if the octet at position emLen - hLen - sLen - 1 (the leftmost + // position is "position 1") does not have hexadecimal value 0x01, + // output "inconsistent" and stop. + for _, e := range db[:emLen-hLen-sLen-2] { + if e != 0x00 { + return ErrVerification + } + } + if db[emLen-hLen-sLen-2] != 0x01 { + return ErrVerification + } + } + + // 11. Let salt be the last sLen octets of DB. + salt := db[len(db)-sLen:] + + // 12. Let + // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ; + // M' is an octet string of length 8 + hLen + sLen with eight + // initial zero octets. + // + // 13. Let H' = Hash(M'), an octet string of length hLen. + var prefix [8]byte + hash.Write(prefix[:]) + hash.Write(mHash) + hash.Write(salt) + + h0 := hash.Sum(nil) + + // 14. If H = H', output "consistent." Otherwise, output "inconsistent." + if !bytes.Equal(h0, h) { + return ErrVerification + } + return nil +} + +// signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt. +// Note that hashed must be the result of hashing the input message using the +// given hash funcion. salt is a random sequence of bytes whose length will be +// later used to verify the signature. +func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) { + nBits := priv.N.BitLen() + em, err := emsaPSSEncode(hashed, nBits-1, salt, hash.New()) + if err != nil { + return + } + m := new(big.Int).SetBytes(em) + c, err := decrypt(rand, priv, m) + if err != nil { + return + } + s = make([]byte, (nBits+7)/8) + copyWithLeftPad(s, c.Bytes()) + return +} + +const ( + // PSSSaltLengthAuto causes the salt in a PSS signature to be as large + // as possible when signing, and to be auto-detected when verifying. + PSSSaltLengthAuto = 0 + // PSSSaltLengthEqualsHash causes the salt length to equal the length + // of the hash used in the signature. + PSSSaltLengthEqualsHash = -1 +) + +// PSSOptions contains options for creating and verifying PSS signatures. +type PSSOptions struct { + // SaltLength controls the length of the salt used in the PSS + // signature. It can either be a number of bytes, or one of the special + // PSSSaltLength constants. + SaltLength int +} + +func (opts *PSSOptions) saltLength() int { + if opts == nil { + return PSSSaltLengthAuto + } + return opts.SaltLength +} + +// SignPSS calculates the signature of hashed using RSASSA-PSS [1]. +// Note that hashed must be the result of hashing the input message using the +// given hash funcion. The opts argument may be nil, in which case sensible +// defaults are used. +func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) (s []byte, err error) { + saltLength := opts.saltLength() + switch saltLength { + case PSSSaltLengthAuto: + saltLength = (priv.N.BitLen()+7)/8 - 2 - hash.Size() + case PSSSaltLengthEqualsHash: + saltLength = hash.Size() + } + + salt := make([]byte, saltLength) + if _, err = io.ReadFull(rand, salt); err != nil { + return + } + return signPSSWithSalt(rand, priv, hash, hashed, salt) +} + +// VerifyPSS verifies a PSS signature. +// hashed is the result of hashing the input message using the given hash +// function and sig is the signature. A valid signature is indicated by +// returning a nil error. The opts argument may be nil, in which case sensible +// defaults are used. +func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error { + return verifyPSS(pub, hash, hashed, sig, opts.saltLength()) +} + +// verifyPSS verifies a PSS signature with the given salt length. +func verifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, saltLen int) error { + nBits := pub.N.BitLen() + if len(sig) != (nBits+7)/8 { + return ErrVerification + } + s := new(big.Int).SetBytes(sig) + m := encrypt(new(big.Int), pub, s) + emBits := nBits - 1 + emLen := (emBits + 7) / 8 + if emLen < len(m.Bytes()) { + return ErrVerification + } + em := make([]byte, emLen) + copyWithLeftPad(em, m.Bytes()) + if saltLen == PSSSaltLengthEqualsHash { + saltLen = hash.Size() + } + return emsaPSSVerify(hashed, em, emBits, saltLen, hash.New()) +} diff --git a/libgo/go/crypto/rsa/pss_test.go b/libgo/go/crypto/rsa/pss_test.go new file mode 100644 index 00000000000..32e6fc39d29 --- /dev/null +++ b/libgo/go/crypto/rsa/pss_test.go @@ -0,0 +1,249 @@ +// 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. + +package rsa + +import ( + "bufio" + "bytes" + "compress/bzip2" + "crypto" + _ "crypto/md5" + "crypto/rand" + "crypto/sha1" + _ "crypto/sha256" + "encoding/hex" + "math/big" + "os" + "strconv" + "strings" + "testing" +) + +func TestEMSAPSS(t *testing.T) { + // Test vector in file pss-int.txt from: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip + msg := []byte{ + 0x85, 0x9e, 0xef, 0x2f, 0xd7, 0x8a, 0xca, 0x00, 0x30, 0x8b, + 0xdc, 0x47, 0x11, 0x93, 0xbf, 0x55, 0xbf, 0x9d, 0x78, 0xdb, + 0x8f, 0x8a, 0x67, 0x2b, 0x48, 0x46, 0x34, 0xf3, 0xc9, 0xc2, + 0x6e, 0x64, 0x78, 0xae, 0x10, 0x26, 0x0f, 0xe0, 0xdd, 0x8c, + 0x08, 0x2e, 0x53, 0xa5, 0x29, 0x3a, 0xf2, 0x17, 0x3c, 0xd5, + 0x0c, 0x6d, 0x5d, 0x35, 0x4f, 0xeb, 0xf7, 0x8b, 0x26, 0x02, + 0x1c, 0x25, 0xc0, 0x27, 0x12, 0xe7, 0x8c, 0xd4, 0x69, 0x4c, + 0x9f, 0x46, 0x97, 0x77, 0xe4, 0x51, 0xe7, 0xf8, 0xe9, 0xe0, + 0x4c, 0xd3, 0x73, 0x9c, 0x6b, 0xbf, 0xed, 0xae, 0x48, 0x7f, + 0xb5, 0x56, 0x44, 0xe9, 0xca, 0x74, 0xff, 0x77, 0xa5, 0x3c, + 0xb7, 0x29, 0x80, 0x2f, 0x6e, 0xd4, 0xa5, 0xff, 0xa8, 0xba, + 0x15, 0x98, 0x90, 0xfc, + } + salt := []byte{ + 0xe3, 0xb5, 0xd5, 0xd0, 0x02, 0xc1, 0xbc, 0xe5, 0x0c, 0x2b, + 0x65, 0xef, 0x88, 0xa1, 0x88, 0xd8, 0x3b, 0xce, 0x7e, 0x61, + } + expected := []byte{ + 0x66, 0xe4, 0x67, 0x2e, 0x83, 0x6a, 0xd1, 0x21, 0xba, 0x24, + 0x4b, 0xed, 0x65, 0x76, 0xb8, 0x67, 0xd9, 0xa4, 0x47, 0xc2, + 0x8a, 0x6e, 0x66, 0xa5, 0xb8, 0x7d, 0xee, 0x7f, 0xbc, 0x7e, + 0x65, 0xaf, 0x50, 0x57, 0xf8, 0x6f, 0xae, 0x89, 0x84, 0xd9, + 0xba, 0x7f, 0x96, 0x9a, 0xd6, 0xfe, 0x02, 0xa4, 0xd7, 0x5f, + 0x74, 0x45, 0xfe, 0xfd, 0xd8, 0x5b, 0x6d, 0x3a, 0x47, 0x7c, + 0x28, 0xd2, 0x4b, 0xa1, 0xe3, 0x75, 0x6f, 0x79, 0x2d, 0xd1, + 0xdc, 0xe8, 0xca, 0x94, 0x44, 0x0e, 0xcb, 0x52, 0x79, 0xec, + 0xd3, 0x18, 0x3a, 0x31, 0x1f, 0xc8, 0x96, 0xda, 0x1c, 0xb3, + 0x93, 0x11, 0xaf, 0x37, 0xea, 0x4a, 0x75, 0xe2, 0x4b, 0xdb, + 0xfd, 0x5c, 0x1d, 0xa0, 0xde, 0x7c, 0xec, 0xdf, 0x1a, 0x89, + 0x6f, 0x9d, 0x8b, 0xc8, 0x16, 0xd9, 0x7c, 0xd7, 0xa2, 0xc4, + 0x3b, 0xad, 0x54, 0x6f, 0xbe, 0x8c, 0xfe, 0xbc, + } + + hash := sha1.New() + hash.Write(msg) + hashed := hash.Sum(nil) + + encoded, err := emsaPSSEncode(hashed, 1023, salt, sha1.New()) + if err != nil { + t.Errorf("Error from emsaPSSEncode: %s\n", err) + } + if !bytes.Equal(encoded, expected) { + t.Errorf("Bad encoding. got %x, want %x", encoded, expected) + } + + if err = emsaPSSVerify(hashed, encoded, 1023, len(salt), sha1.New()); err != nil { + t.Errorf("Bad verification: %s", err) + } +} + +// TestPSSGolden tests all the test vectors in pss-vect.txt from +// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip +func TestPSSGolden(t *testing.T) { + inFile, err := os.Open("testdata/pss-vect.txt.bz2") + if err != nil { + t.Fatalf("Failed to open input file: %s", err) + } + defer inFile.Close() + + // The pss-vect.txt file contains RSA keys and then a series of + // signatures. A goroutine is used to preprocess the input by merging + // lines, removing spaces in hex values and identifying the start of + // new keys and signature blocks. + const newKeyMarker = "START NEW KEY" + const newSignatureMarker = "START NEW SIGNATURE" + + values := make(chan string) + + go func() { + defer close(values) + scanner := bufio.NewScanner(bzip2.NewReader(inFile)) + var partialValue string + lastWasValue := true + + for scanner.Scan() { + line := scanner.Text() + switch { + case len(line) == 0: + if len(partialValue) > 0 { + values <- strings.Replace(partialValue, " ", "", -1) + partialValue = "" + lastWasValue = true + } + continue + case strings.HasPrefix(line, "# ======") && lastWasValue: + values <- newKeyMarker + lastWasValue = false + case strings.HasPrefix(line, "# ------") && lastWasValue: + values <- newSignatureMarker + lastWasValue = false + case strings.HasPrefix(line, "#"): + continue + default: + partialValue += line + } + } + if err := scanner.Err(); err != nil { + panic(err) + } + }() + + var key *PublicKey + var hashed []byte + hash := crypto.SHA1 + h := hash.New() + opts := &PSSOptions{ + SaltLength: PSSSaltLengthEqualsHash, + } + + for marker := range values { + switch marker { + case newKeyMarker: + key = new(PublicKey) + nHex, ok := <-values + if !ok { + continue + } + key.N = bigFromHex(nHex) + key.E = intFromHex(<-values) + // We don't care for d, p, q, dP, dQ or qInv. + for i := 0; i < 6; i++ { + <-values + } + case newSignatureMarker: + msg := fromHex(<-values) + <-values // skip salt + sig := fromHex(<-values) + + h.Reset() + h.Write(msg) + hashed = h.Sum(hashed[:0]) + + if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil { + t.Error(err) + } + default: + t.Fatalf("unknown marker: " + marker) + } + } +} + +// TestPSSOpenSSL ensures that we can verify a PSS signature from OpenSSL with +// the default options. OpenSSL sets the salt length to be maximal. +func TestPSSOpenSSL(t *testing.T) { + hash := crypto.SHA256 + h := hash.New() + h.Write([]byte("testing")) + hashed := h.Sum(nil) + + // Generated with `echo -n testing | openssl dgst -sign key.pem -sigopt rsa_padding_mode:pss -sha256 > sig` + sig := []byte{ + 0x95, 0x59, 0x6f, 0xd3, 0x10, 0xa2, 0xe7, 0xa2, 0x92, 0x9d, + 0x4a, 0x07, 0x2e, 0x2b, 0x27, 0xcc, 0x06, 0xc2, 0x87, 0x2c, + 0x52, 0xf0, 0x4a, 0xcc, 0x05, 0x94, 0xf2, 0xc3, 0x2e, 0x20, + 0xd7, 0x3e, 0x66, 0x62, 0xb5, 0x95, 0x2b, 0xa3, 0x93, 0x9a, + 0x66, 0x64, 0x25, 0xe0, 0x74, 0x66, 0x8c, 0x3e, 0x92, 0xeb, + 0xc6, 0xe6, 0xc0, 0x44, 0xf3, 0xb4, 0xb4, 0x2e, 0x8c, 0x66, + 0x0a, 0x37, 0x9c, 0x69, + } + + if err := VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, nil); err != nil { + t.Error(err) + } +} + +func TestPSSSigning(t *testing.T) { + var saltLengthCombinations = []struct { + signSaltLength, verifySaltLength int + good bool + }{ + {PSSSaltLengthAuto, PSSSaltLengthAuto, true}, + {PSSSaltLengthEqualsHash, PSSSaltLengthAuto, true}, + {PSSSaltLengthEqualsHash, PSSSaltLengthEqualsHash, true}, + {PSSSaltLengthEqualsHash, 8, false}, + {PSSSaltLengthAuto, PSSSaltLengthEqualsHash, false}, + {8, 8, true}, + } + + hash := crypto.MD5 + h := hash.New() + h.Write([]byte("testing")) + hashed := h.Sum(nil) + var opts PSSOptions + + for i, test := range saltLengthCombinations { + opts.SaltLength = test.signSaltLength + sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts) + if err != nil { + t.Errorf("#%d: error while signing: %s", i, err) + continue + } + + opts.SaltLength = test.verifySaltLength + err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts) + if (err == nil) != test.good { + t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err) + } + } +} + +func bigFromHex(hex string) *big.Int { + n, ok := new(big.Int).SetString(hex, 16) + if !ok { + panic("bad hex: " + hex) + } + return n +} + +func intFromHex(hex string) int { + i, err := strconv.ParseInt(hex, 16, 32) + if err != nil { + panic(err) + } + return int(i) +} + +func fromHex(hexStr string) []byte { + s, err := hex.DecodeString(hexStr) + if err != nil { + panic(err) + } + return s +} diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index f56fb37ee54..c7353ea311a 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -5,8 +5,6 @@ // Package rsa implements RSA encryption as specified in PKCS#1. package rsa -// TODO(agl): Add support for PSS padding. - import ( "crypto/rand" "crypto/subtle" diff --git a/libgo/go/crypto/rsa/rsa_test.go b/libgo/go/crypto/rsa/rsa_test.go index ffd96e62f64..cf193c669f3 100644 --- a/libgo/go/crypto/rsa/rsa_test.go +++ b/libgo/go/crypto/rsa/rsa_test.go @@ -120,8 +120,10 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { } func fromBase10(base10 string) *big.Int { - i := new(big.Int) - i.SetString(base10, 10) + i, ok := new(big.Int).SetString(base10, 10) + if !ok { + panic("bad number: " + base10) + } return i } diff --git a/libgo/go/crypto/rsa/testdata/pss-vect.txt.bz2 b/libgo/go/crypto/rsa/testdata/pss-vect.txt.bz2 Binary files differnew file mode 100644 index 00000000000..ad3da1ac4ee --- /dev/null +++ b/libgo/go/crypto/rsa/testdata/pss-vect.txt.bz2 diff --git a/libgo/go/crypto/sha1/sha1.go b/libgo/go/crypto/sha1/sha1.go index 7cfde47dc07..8eb3f7a7988 100644 --- a/libgo/go/crypto/sha1/sha1.go +++ b/libgo/go/crypto/sha1/sha1.go @@ -90,9 +90,13 @@ func (d *digest) Write(p []byte) (nn int, err error) { 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() + return append(in, hash[:]...) +} - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. +func (d *digest) checkSum() [Size]byte { len := d.len + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. var tmp [64]byte tmp[0] = 0x80 if len%64 < 56 { @@ -120,5 +124,13 @@ func (d0 *digest) Sum(in []byte) []byte { digest[i*4+3] = byte(s) } - return append(in, digest[:]...) + return digest +} + +// Sum returns the SHA1 checksum of the data. +func Sum(data []byte) [Size]byte { + var d digest + d.Reset() + d.Write(data) + return d.checkSum() } diff --git a/libgo/go/crypto/sha1/sha1_test.go b/libgo/go/crypto/sha1/sha1_test.go index 57cd4313eb2..c3868d702ac 100644 --- a/libgo/go/crypto/sha1/sha1_test.go +++ b/libgo/go/crypto/sha1/sha1_test.go @@ -54,6 +54,10 @@ var golden = []sha1Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] + s := fmt.Sprintf("%x", Sum([]byte(g.in))) + if s != g.out { + t.Fatalf("Sum function: sha1(%s) = %s want %s", g.in, s, g.out) + } c := New() for j := 0; j < 3; j++ { if j < 2 { @@ -72,13 +76,6 @@ func TestGolden(t *testing.T) { } } -func ExampleNew() { - h := New() - io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.") - fmt.Printf("% x", h.Sum(nil)) - // Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd -} - var bench = New() var buf = make([]byte, 8192) diff --git a/libgo/go/crypto/sha1/sha1block_decl.go b/libgo/go/crypto/sha1/sha1block_decl.go index 3512a582991..4cb157fff6d 100644 --- a/libgo/go/crypto/sha1/sha1block_decl.go +++ b/libgo/go/crypto/sha1/sha1block_decl.go @@ -6,4 +6,6 @@ package sha1 +//go:noescape + func block(dig *digest, p []byte) diff --git a/libgo/go/crypto/sha256/sha256.go b/libgo/go/crypto/sha256/sha256.go index dc0e18f50df..d69ed24a3b4 100644 --- a/libgo/go/crypto/sha256/sha256.go +++ b/libgo/go/crypto/sha256/sha256.go @@ -134,9 +134,16 @@ func (d *digest) Write(p []byte) (nn int, err error) { 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 { + return append(in, hash[:Size224]...) + } + return append(in, hash[:]...) +} - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. +func (d *digest) checkSum() [Size]byte { len := d.len + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. var tmp [64]byte tmp[0] = 0x80 if len%64 < 56 { @@ -157,10 +164,8 @@ func (d0 *digest) Sum(in []byte) []byte { } h := d.h[:] - size := Size if d.is224 { h = d.h[:7] - size = Size224 } var digest [Size]byte @@ -171,5 +176,24 @@ func (d0 *digest) Sum(in []byte) []byte { digest[i*4+3] = byte(s) } - return append(in, digest[:size]...) + return digest +} + +// Sum256 returns the SHA256 checksum of the data. +func Sum256(data []byte) [Size]byte { + var d digest + d.Reset() + d.Write(data) + return d.checkSum() +} + +// Sum224 returns the SHA224 checksum of the data. +func Sum224(data []byte) (sum224 [Size224]byte) { + var d digest + d.is224 = true + d.Reset() + d.Write(data) + sum := d.checkSum() + copy(sum224[:], sum[:Size224]) + return } diff --git a/libgo/go/crypto/sha256/sha256_test.go b/libgo/go/crypto/sha256/sha256_test.go index 29bf1619aeb..bb1ec3b1626 100644 --- a/libgo/go/crypto/sha256/sha256_test.go +++ b/libgo/go/crypto/sha256/sha256_test.go @@ -88,6 +88,10 @@ var golden224 = []sha256Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] + s := fmt.Sprintf("%x", Sum256([]byte(g.in))) + if s != g.out { + t.Fatalf("Sum256 function: sha256(%s) = %s want %s", g.in, s, g.out) + } c := New() for j := 0; j < 3; j++ { if j < 2 { @@ -106,6 +110,10 @@ func TestGolden(t *testing.T) { } for i := 0; i < len(golden224); i++ { g := golden224[i] + s := fmt.Sprintf("%x", Sum224([]byte(g.in))) + if s != g.out { + t.Fatalf("Sum224 function: sha224(%s) = %s want %s", g.in, s, g.out) + } c := New224() for j := 0; j < 3; j++ { if j < 2 { diff --git a/libgo/go/crypto/sha512/sha512.go b/libgo/go/crypto/sha512/sha512.go index 4aec5293858..d2ada51373c 100644 --- a/libgo/go/crypto/sha512/sha512.go +++ b/libgo/go/crypto/sha512/sha512.go @@ -135,7 +135,14 @@ 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() + if d.is384 { + return append(in, hash[:Size384]...) + } + return append(in, hash[:]...) +} +func (d *digest) checkSum() [Size]byte { // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128. len := d.len var tmp [128]byte @@ -158,10 +165,8 @@ func (d0 *digest) Sum(in []byte) []byte { } h := d.h[:] - size := Size if d.is384 { h = d.h[:6] - size = Size384 } var digest [Size]byte @@ -176,5 +181,24 @@ func (d0 *digest) Sum(in []byte) []byte { digest[i*8+7] = byte(s) } - return append(in, digest[:size]...) + return digest +} + +// Sum512 returns the SHA512 checksum of the data. +func Sum512(data []byte) [Size]byte { + var d digest + d.Reset() + d.Write(data) + return d.checkSum() +} + +// Sum384 returns the SHA384 checksum of the data. +func Sum384(data []byte) (sum384 [Size384]byte) { + var d digest + d.is384 = true + d.Reset() + d.Write(data) + sum := d.checkSum() + copy(sum384[:], sum[:Size384]) + return } diff --git a/libgo/go/crypto/sha512/sha512_test.go b/libgo/go/crypto/sha512/sha512_test.go index 6eafb1b5fa9..167c20ad075 100644 --- a/libgo/go/crypto/sha512/sha512_test.go +++ b/libgo/go/crypto/sha512/sha512_test.go @@ -88,6 +88,10 @@ var golden384 = []sha512Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] + s := fmt.Sprintf("%x", Sum512([]byte(g.in))) + if s != g.out { + t.Fatalf("Sum512 function: sha512(%s) = %s want %s", g.in, s, g.out) + } c := New() for j := 0; j < 3; j++ { if j < 2 { @@ -106,6 +110,10 @@ func TestGolden(t *testing.T) { } for i := 0; i < len(golden384); i++ { g := golden384[i] + s := fmt.Sprintf("%x", Sum384([]byte(g.in))) + if s != g.out { + t.Fatalf("Sum384 function: sha384(%s) = %s want %s", g.in, s, g.out) + } c := New384() for j := 0; j < 3; j++ { if j < 2 { diff --git a/libgo/go/crypto/subtle/constant_time.go b/libgo/go/crypto/subtle/constant_time.go index 57dbe9db555..dfb658465e9 100644 --- a/libgo/go/crypto/subtle/constant_time.go +++ b/libgo/go/crypto/subtle/constant_time.go @@ -55,3 +55,11 @@ func ConstantTimeCopy(v int, x, y []byte) { } return } + +// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise. +// Its behavior is undefined if x or y are negative or > 2**31 - 1. +func ConstantTimeLessOrEq(x, y int) int { + x32 := int32(x) + y32 := int32(y) + return int(((x32 - y32 - 1) >> 31) & 1) +} diff --git a/libgo/go/crypto/subtle/constant_time_test.go b/libgo/go/crypto/subtle/constant_time_test.go index adab8e2e8dd..d8e321ec04a 100644 --- a/libgo/go/crypto/subtle/constant_time_test.go +++ b/libgo/go/crypto/subtle/constant_time_test.go @@ -103,3 +103,23 @@ func TestConstantTimeCopy(t *testing.T) { t.Error(err) } } + +var lessOrEqTests = []struct { + x, y, result int +}{ + {0, 0, 1}, + {1, 0, 0}, + {0, 1, 1}, + {10, 20, 1}, + {20, 10, 0}, + {10, 10, 1}, +} + +func TestConstantTimeLessOrEq(t *testing.T) { + for i, test := range lessOrEqTests { + result := ConstantTimeLessOrEq(test.x, test.y) + if result != test.result { + t.Errorf("#%d: %d <= %d gave %d, expected %d", i, test.x, test.y, result, test.result) + } + } +} diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go index a647e19aa19..39a51459d28 100644 --- a/libgo/go/crypto/tls/cipher_suites.go +++ b/libgo/go/crypto/tls/cipher_suites.go @@ -34,6 +34,22 @@ type keyAgreement interface { generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) } +const ( + // suiteECDH indicates that the cipher suite involves elliptic curve + // Diffie-Hellman. This means that it should only be selected when the + // client indicates that it supports ECC with a curve and point format + // that we're happy with. + suiteECDHE = 1 << iota + // suiteECDSA indicates that the cipher suite involves an ECDSA + // signature and therefore may only be selected when the server's + // certificate is ECDSA. If this is not set then the cipher suite is + // RSA based. + suiteECDSA + // suiteTLS12 indicates that the cipher suite should only be advertised + // and accepted when using TLS 1.2. + suiteTLS12 +) + // A cipherSuite is a specific combination of key agreement, cipher and MAC // function. All cipher suites currently assume RSA key agreement. type cipherSuite struct { @@ -42,24 +58,30 @@ type cipherSuite struct { keyLen int macLen int ivLen int - ka func() keyAgreement - // If elliptic is set, a server will only consider this ciphersuite if - // the ClientHello indicated that the client supports an elliptic curve - // and point format that we can handle. - elliptic bool - cipher func(key, iv []byte, isRead bool) interface{} - mac func(version uint16, macKey []byte) macFunction + ka func(version uint16) keyAgreement + // flags is a bitmask of the suite* values, above. + flags int + cipher func(key, iv []byte, isRead bool) interface{} + mac func(version uint16, macKey []byte) macFunction + aead func(key, fixedNonce []byte) cipher.AEAD } var cipherSuites = []*cipherSuite{ - {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, - {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1}, - {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, + // Ciphersuite order is chosen so that ECDHE comes before plain RSA + // and RC4 comes before AES (because of the Lucky13 attack). + {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, + {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil}, + {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, + {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, } func cipherRC4(key, iv []byte, isRead bool) interface{} { @@ -85,7 +107,7 @@ func cipherAES(key, iv []byte, isRead bool) interface{} { // macSHA1 returns a macFunction for the given protocol version. func macSHA1(version uint16, key []byte) macFunction { - if version == versionSSL30 { + if version == VersionSSL30 { mac := ssl30MAC{ h: sha1.New(), key: make([]byte, len(key)), @@ -98,7 +120,47 @@ func macSHA1(version uint16, key []byte) macFunction { type macFunction interface { Size() int - MAC(digestBuf, seq, data []byte) []byte + MAC(digestBuf, seq, header, data []byte) []byte +} + +// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to +// each call. +type fixedNonceAEAD struct { + // sealNonce and openNonce are buffers where the larger nonce will be + // constructed. Since a seal and open operation may be running + // concurrently, there is a separate buffer for each. + sealNonce, openNonce []byte + aead cipher.AEAD +} + +func (f *fixedNonceAEAD) NonceSize() int { return 8 } +func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } + +func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { + copy(f.sealNonce[len(f.sealNonce)-8:], nonce) + return f.aead.Seal(out, f.sealNonce, plaintext, additionalData) +} + +func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) { + copy(f.openNonce[len(f.openNonce)-8:], nonce) + return f.aead.Open(out, f.openNonce, plaintext, additionalData) +} + +func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { + aes, err := aes.NewCipher(key) + if err != nil { + panic(err) + } + aead, err := cipher.NewGCM(aes) + if err != nil { + panic(err) + } + + nonce1, nonce2 := make([]byte, 12), make([]byte, 12) + copy(nonce1, fixedNonce) + copy(nonce2, fixedNonce) + + return &fixedNonceAEAD{nonce1, nonce2, aead} } // ssl30MAC implements the SSLv3 MAC function, as defined in @@ -116,7 +178,7 @@ var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0 var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c} -func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte { +func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte { padLength := 48 if s.h.Size() == 20 { padLength = 40 @@ -126,9 +188,9 @@ func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte { s.h.Write(s.key) s.h.Write(ssl30Pad1[:padLength]) s.h.Write(seq) - s.h.Write(record[:1]) - s.h.Write(record[3:5]) - s.h.Write(record[recordHeaderLen:]) + s.h.Write(header[:1]) + s.h.Write(header[3:5]) + s.h.Write(data) digestBuf = s.h.Sum(digestBuf[:0]) s.h.Reset() @@ -147,19 +209,30 @@ func (s tls10MAC) Size() int { return s.h.Size() } -func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte { +func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte { s.h.Reset() s.h.Write(seq) - s.h.Write(record) + s.h.Write(header) + s.h.Write(data) return s.h.Sum(digestBuf[:0]) } -func rsaKA() keyAgreement { +func rsaKA(version uint16) keyAgreement { return rsaKeyAgreement{} } -func ecdheRSAKA() keyAgreement { - return new(ecdheRSAKeyAgreement) +func ecdheECDSAKA(version uint16) keyAgreement { + return &ecdheKeyAgreement{ + sigType: signatureECDSA, + version: version, + } +} + +func ecdheRSAKA(version uint16) keyAgreement { + return &ecdheKeyAgreement{ + sigType: signatureRSA, + version: version, + } } // mutualCipherSuite returns a cipherSuite given a list of supported @@ -181,12 +254,17 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { // A list of the possible cipher suite ids. Taken from // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml const ( - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 + TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 + TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a + TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f + TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a + TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b ) diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go index f86c90de74d..b7229d29f8b 100644 --- a/libgo/go/crypto/tls/common.go +++ b/libgo/go/crypto/tls/common.go @@ -9,22 +9,27 @@ import ( "crypto/rand" "crypto/x509" "io" + "math/big" "strings" "sync" "time" ) const ( + VersionSSL30 = 0x0300 + VersionTLS10 = 0x0301 + VersionTLS11 = 0x0302 + VersionTLS12 = 0x0303 +) + +const ( maxPlaintext = 16384 // maximum plaintext payload length maxCiphertext = 16384 + 2048 // maximum ciphertext payload length recordHeaderLen = 5 // record header length maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) - versionSSL30 = 0x0300 - versionTLS10 = 0x0301 - - minVersion = versionSSL30 - maxVersion = versionTLS10 + minVersion = VersionSSL30 + maxVersion = VersionTLS12 ) // TLS record types. @@ -60,12 +65,13 @@ const ( // TLS extension numbers var ( - extensionServerName uint16 = 0 - extensionStatusRequest uint16 = 5 - extensionSupportedCurves uint16 = 10 - extensionSupportedPoints uint16 = 11 - extensionSessionTicket uint16 = 35 - extensionNextProtoNeg uint16 = 13172 // not IANA assigned + extensionServerName uint16 = 0 + extensionStatusRequest uint16 = 5 + extensionSupportedCurves uint16 = 10 + extensionSupportedPoints uint16 = 11 + extensionSignatureAlgorithms uint16 = 13 + extensionSessionTicket uint16 = 35 + extensionNextProtoNeg uint16 = 13172 // not IANA assigned ) // TLS Elliptic Curves @@ -93,25 +99,60 @@ const ( certTypeDSSSign = 2 // A certificate containing a DSA key certTypeRSAFixedDH = 3 // A certificate containing a static DH key certTypeDSSFixedDH = 4 // A certificate containing a static DH key + + // See RFC4492 sections 3 and 5.5. + certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. + certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. + certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. + // Rest of these are reserved by the TLS spec ) +// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1) +const ( + hashSHA1 uint8 = 2 + hashSHA256 uint8 = 4 +) + +// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1) +const ( + signatureRSA uint8 = 1 + signatureECDSA uint8 = 3 +) + +// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See +// RFC 5246, section A.4.1. +type signatureAndHash struct { + hash, signature uint8 +} + +// supportedSKXSignatureAlgorithms contains the signature and hash algorithms +// that the code advertises as supported in a TLS 1.2 ClientHello. +var supportedSKXSignatureAlgorithms = []signatureAndHash{ + {hashSHA256, signatureRSA}, + {hashSHA256, signatureECDSA}, + {hashSHA1, signatureRSA}, + {hashSHA1, signatureECDSA}, +} + +// supportedClientCertSignatureAlgorithms contains the signature and hash +// algorithms that the code advertises as supported in a TLS 1.2 +// CertificateRequest. +var supportedClientCertSignatureAlgorithms = []signatureAndHash{ + {hashSHA256, signatureRSA}, + {hashSHA256, signatureECDSA}, +} + // ConnectionState records basic TLS details about the connection. type ConnectionState struct { - HandshakeComplete bool - DidResume bool - CipherSuite uint16 - NegotiatedProtocol string - NegotiatedProtocolIsMutual bool - - // ServerName contains the server name indicated by the client, if any. - // (Only valid for server connections.) - ServerName string - - // the certificate chain that was presented by the other side - PeerCertificates []*x509.Certificate - // the verified certificate chains built from PeerCertificates. - VerifiedChains [][]*x509.Certificate + HandshakeComplete bool // TLS handshake is complete + DidResume bool // connection resumes a previous TLS connection + CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...) + NegotiatedProtocol string // negotiated next protocol (from Config.NextProtos) + NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server + ServerName string // server name requested by client, if any (server side only) + PeerCertificates []*x509.Certificate // certificate chain presented by remote peer + VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates } // ClientAuthType declares the policy the server will follow for @@ -204,6 +245,15 @@ type Config struct { // connections using that key are compromised. SessionTicketKey [32]byte + // MinVersion contains the minimum SSL/TLS version that is acceptable. + // If zero, then SSLv3 is taken as the minimum. + MinVersion uint16 + + // MaxVersion contains the maximum SSL/TLS version that is acceptable. + // If zero, then the maximum version supported by this package is used, + // which is currently TLS 1.2. + MaxVersion uint16 + serverInitOnce sync.Once // guards calling (*Config).serverInit } @@ -248,6 +298,35 @@ func (c *Config) cipherSuites() []uint16 { return s } +func (c *Config) minVersion() uint16 { + if c == nil || c.MinVersion == 0 { + return minVersion + } + return c.MinVersion +} + +func (c *Config) maxVersion() uint16 { + if c == nil || c.MaxVersion == 0 { + return maxVersion + } + return c.MaxVersion +} + +// mutualVersion returns the protocol version to use given the advertised +// version of the peer. +func (c *Config) mutualVersion(vers uint16) (uint16, bool) { + minVersion := c.minVersion() + maxVersion := c.maxVersion() + + if vers < minVersion { + return 0, false + } + if vers > maxVersion { + vers = maxVersion + } + return vers, true +} + // getCertificateForName returns the best certificate for the given name, // defaulting to the first element of c.Certificates if there are no good // options. @@ -304,7 +383,7 @@ func (c *Config) BuildNameToCertificate() { // A Certificate is a chain of one or more certificates, leaf first. type Certificate struct { Certificate [][]byte - PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey + PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey // OCSPStaple contains an optional OCSP response which will be served // to clients that request it. OCSPStaple []byte @@ -327,18 +406,13 @@ type handshakeMessage interface { unmarshal([]byte) bool } -// mutualVersion returns the protocol version to use given the advertised -// version of the peer. -func mutualVersion(vers uint16) (uint16, bool) { - if vers < minVersion { - return 0, false - } - if vers > maxVersion { - vers = maxVersion - } - return vers, true +// TODO(jsing): Make these available to both crypto/x509 and crypto/tls. +type dsaSignature struct { + R, S *big.Int } +type ecdsaSignature dsaSignature + var emptyConfig Config func defaultConfig() *Config { diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go index d8c2be00a26..2e64b88a689 100644 --- a/libgo/go/crypto/tls/conn.go +++ b/libgo/go/crypto/tls/conn.go @@ -146,6 +146,9 @@ func (hc *halfConn) changeCipherSpec() error { hc.mac = hc.nextMac hc.nextCipher = nil hc.nextMac = nil + for i := range hc.seq { + hc.seq[i] = 0 + } return nil } @@ -229,8 +232,16 @@ func roundUp(a, b int) int { return a + (b-a%b)%b } -// decrypt checks and strips the mac and decrypts the data in b. -func (hc *halfConn) decrypt(b *block) (bool, alert) { +// cbcMode is an interface for block ciphers using cipher block chaining. +type cbcMode interface { + cipher.BlockMode + SetIV([]byte) +} + +// decrypt checks and strips the mac and decrypts the data in b. Returns a +// success boolean, the number of bytes to skip from the start of the record in +// order to get the application payload, and an optional alert value. +func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) { // pull out payload payload := b.data[recordHeaderLen:] @@ -240,26 +251,54 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) { } paddingGood := byte(255) + explicitIVLen := 0 // decrypt if hc.cipher != nil { switch c := hc.cipher.(type) { case cipher.Stream: c.XORKeyStream(payload, payload) - case cipher.BlockMode: + case cipher.AEAD: + explicitIVLen = 8 + if len(payload) < explicitIVLen { + return false, 0, alertBadRecordMAC + } + nonce := payload[:8] + payload = payload[8:] + + var additionalData [13]byte + copy(additionalData[:], hc.seq[:]) + copy(additionalData[8:], b.data[:3]) + n := len(payload) - c.Overhead() + additionalData[11] = byte(n >> 8) + additionalData[12] = byte(n) + var err error + payload, err = c.Open(payload[:0], nonce, payload, additionalData[:]) + if err != nil { + return false, 0, alertBadRecordMAC + } + b.resize(recordHeaderLen + explicitIVLen + len(payload)) + case cbcMode: blockSize := c.BlockSize() + if hc.version >= VersionTLS11 { + explicitIVLen = blockSize + } - if len(payload)%blockSize != 0 || len(payload) < roundUp(macSize+1, blockSize) { - return false, alertBadRecordMAC + if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) { + return false, 0, alertBadRecordMAC } + if explicitIVLen > 0 { + c.SetIV(payload[:explicitIVLen]) + payload = payload[explicitIVLen:] + } c.CryptBlocks(payload, payload) - if hc.version == versionSSL30 { + if hc.version == VersionSSL30 { payload, paddingGood = removePaddingSSL30(payload) } else { payload, paddingGood = removePadding(payload) } - b.resize(recordHeaderLen + len(payload)) + b.resize(recordHeaderLen + explicitIVLen + len(payload)) // note that we still have a timing side-channel in the // MAC check, below. An attacker can align the record @@ -279,25 +318,25 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) { // check, strip mac if hc.mac != nil { if len(payload) < macSize { - return false, alertBadRecordMAC + return false, 0, alertBadRecordMAC } // strip mac off payload, b.data n := len(payload) - macSize b.data[3] = byte(n >> 8) b.data[4] = byte(n) - b.resize(recordHeaderLen + n) + b.resize(recordHeaderLen + explicitIVLen + n) remoteMAC := payload[n:] - localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data) - hc.incSeq() + localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], payload[:n]) if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { - return false, alertBadRecordMAC + return false, 0, alertBadRecordMAC } hc.inDigestBuf = localMAC } + hc.incSeq() - return true, 0 + return true, recordHeaderLen + explicitIVLen, 0 } // padToBlockSize calculates the needed padding block, if any, for a payload. @@ -318,11 +357,10 @@ func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) { } // encrypt encrypts and macs the data in b. -func (hc *halfConn) encrypt(b *block) (bool, alert) { +func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { // mac if hc.mac != nil { - mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data) - hc.incSeq() + mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:]) n := len(b.data) b.resize(n + len(mac)) @@ -337,11 +375,30 @@ func (hc *halfConn) encrypt(b *block) (bool, alert) { switch c := hc.cipher.(type) { case cipher.Stream: c.XORKeyStream(payload, payload) - case cipher.BlockMode: - prefix, finalBlock := padToBlockSize(payload, c.BlockSize()) - b.resize(recordHeaderLen + len(prefix) + len(finalBlock)) - c.CryptBlocks(b.data[recordHeaderLen:], prefix) - c.CryptBlocks(b.data[recordHeaderLen+len(prefix):], finalBlock) + case cipher.AEAD: + payloadLen := len(b.data) - recordHeaderLen - explicitIVLen + b.resize(len(b.data) + c.Overhead()) + nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] + payload := b.data[recordHeaderLen+explicitIVLen:] + payload = payload[:payloadLen] + + var additionalData [13]byte + copy(additionalData[:], hc.seq[:]) + copy(additionalData[8:], b.data[:3]) + additionalData[11] = byte(payloadLen >> 8) + additionalData[12] = byte(payloadLen) + + c.Seal(payload[:0], nonce, payload, additionalData[:]) + case cbcMode: + blockSize := c.BlockSize() + if explicitIVLen > 0 { + c.SetIV(payload[:explicitIVLen]) + payload = payload[explicitIVLen:] + } + prefix, finalBlock := padToBlockSize(payload, blockSize) + b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock)) + c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix) + c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock) default: panic("unknown cipher type") } @@ -351,6 +408,7 @@ func (hc *halfConn) encrypt(b *block) (bool, alert) { n := len(b.data) - recordHeaderLen b.data[3] = byte(n >> 8) b.data[4] = byte(n) + hc.incSeq() return true, 0 } @@ -534,10 +592,11 @@ Again: // Process message. b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n) - b.off = recordHeaderLen - if ok, err := c.in.decrypt(b); !ok { + ok, off, err := c.in.decrypt(b) + if !ok { return c.sendAlert(err) } + b.off = off data := b.data[b.off:] if len(data) > maxPlaintext { c.sendAlert(alertRecordOverflow) @@ -637,18 +696,52 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) { if m > maxPlaintext { m = maxPlaintext } - b.resize(recordHeaderLen + m) + explicitIVLen := 0 + explicitIVIsSeq := false + + var cbc cbcMode + if c.out.version >= VersionTLS11 { + var ok bool + if cbc, ok = c.out.cipher.(cbcMode); ok { + explicitIVLen = cbc.BlockSize() + } + } + if explicitIVLen == 0 { + if _, ok := c.out.cipher.(cipher.AEAD); ok { + explicitIVLen = 8 + // The AES-GCM construction in TLS has an + // explicit nonce so that the nonce can be + // random. However, the nonce is only 8 bytes + // which is too small for a secure, random + // nonce. Therefore we use the sequence number + // as the nonce. + explicitIVIsSeq = true + } + } + b.resize(recordHeaderLen + explicitIVLen + m) b.data[0] = byte(typ) vers := c.vers if vers == 0 { - vers = maxVersion + // Some TLS servers fail if the record version is + // greater than TLS 1.0 for the initial ClientHello. + vers = VersionTLS10 } b.data[1] = byte(vers >> 8) b.data[2] = byte(vers) b.data[3] = byte(m >> 8) b.data[4] = byte(m) - copy(b.data[recordHeaderLen:], data) - c.out.encrypt(b) + if explicitIVLen > 0 { + explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] + if explicitIVIsSeq { + copy(explicitIV, c.out.seq[:]) + } else { + if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil { + break + } + } + } + copy(b.data[recordHeaderLen+explicitIVLen:], data) + c.out.encrypt(b, explicitIVLen) _, err = c.conn.Write(b.data) if err != nil { break @@ -709,7 +802,9 @@ func (c *Conn) readHandshake() (interface{}, error) { case typeCertificate: m = new(certificateMsg) case typeCertificateRequest: - m = new(certificateRequestMsg) + m = &certificateRequestMsg{ + hasSignatureAndHash: c.vers >= VersionTLS12, + } case typeCertificateStatus: m = new(certificateStatusMsg) case typeServerKeyExchange: @@ -719,7 +814,9 @@ func (c *Conn) readHandshake() (interface{}, error) { case typeClientKeyExchange: m = new(clientKeyExchangeMsg) case typeCertificateVerify: - m = new(certificateVerifyMsg) + m = &certificateVerifyMsg{ + hasSignatureAndHash: c.vers >= VersionTLS12, + } case typeNextProtocol: m = new(nextProtoMsg) case typeFinished: @@ -768,7 +865,7 @@ func (c *Conn) Write(b []byte) (int, error) { // http://www.imperialviolet.org/2012/01/15/beastfollowup.html var m int - if len(b) > 1 && c.vers <= versionTLS10 { + if len(b) > 1 && c.vers <= VersionTLS10 { if _, ok := c.out.cipher.(cipher.BlockMode); ok { n, err := c.writeRecord(recordTypeApplicationData, b[:1]) if err != nil { @@ -792,21 +889,32 @@ func (c *Conn) Read(b []byte) (n int, err error) { c.in.Lock() defer c.in.Unlock() - for c.input == nil && c.error() == nil { - if err := c.readRecord(recordTypeApplicationData); err != nil { - // Soft error, like EAGAIN + // Some OpenSSL servers send empty records in order to randomize the + // CBC IV. So this loop ignores a limited number of empty records. + const maxConsecutiveEmptyRecords = 100 + for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ { + for c.input == nil && c.error() == nil { + if err := c.readRecord(recordTypeApplicationData); err != nil { + // Soft error, like EAGAIN + return 0, err + } + } + if err := c.error(); err != nil { return 0, err } + + n, err = c.input.Read(b) + if c.input.off >= len(c.input.data) { + c.in.freeBlock(c.input) + c.input = nil + } + + if n != 0 || err != nil { + return n, err + } } - if err := c.error(); err != nil { - return 0, err - } - n, err = c.input.Read(b) - if c.input.off >= len(c.input.data) { - c.in.freeBlock(c.input) - c.input = nil - } - return n, nil + + return 0, io.ErrNoProgress } // Close closes the connection. diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go index 215644d2435..b417ea4640f 100644 --- a/libgo/go/crypto/tls/generate_cert.go +++ b/libgo/go/crypto/tls/generate_cert.go @@ -30,7 +30,7 @@ var ( validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") - rsaBits = flag.Int("rsa-bits", 1024, "Size of RSA key to generate") + rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate") ) func main() { diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index 7db13bf70d8..85e4adefcb0 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -6,25 +6,23 @@ package tls import ( "bytes" - "crypto" + "crypto/ecdsa" "crypto/rsa" "crypto/subtle" "crypto/x509" + "encoding/asn1" "errors" "io" "strconv" ) func (c *Conn) clientHandshake() error { - finishedHash := newFinishedHash(versionTLS10) - if c.config == nil { c.config = defaultConfig() } hello := &clientHelloMsg{ - vers: maxVersion, - cipherSuites: c.config.cipherSuites(), + vers: c.config.maxVersion(), compressionMethods: []uint8{compressionNone}, random: make([]byte, 32), ocspStapling: true, @@ -34,6 +32,25 @@ func (c *Conn) clientHandshake() error { nextProtoNeg: len(c.config.NextProtos) > 0, } + possibleCipherSuites := c.config.cipherSuites() + hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) + +NextCipherSuite: + for _, suiteId := range possibleCipherSuites { + for _, suite := range cipherSuites { + if suite.id != suiteId { + continue + } + // Don't advertise TLS 1.2-only cipher suites unless + // we're attempting TLS 1.2. + if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { + continue + } + hello.cipherSuites = append(hello.cipherSuites, suiteId) + continue NextCipherSuite + } + } + t := uint32(c.config.time().Unix()) hello.random[0] = byte(t >> 24) hello.random[1] = byte(t >> 16) @@ -45,7 +62,10 @@ func (c *Conn) clientHandshake() error { return errors.New("short read from Rand") } - finishedHash.Write(hello.marshal()) + if hello.vers >= VersionTLS12 { + hello.signatureAndHashes = supportedSKXSignatureAlgorithms + } + c.writeRecord(recordTypeHandshake, hello.marshal()) msg, err := c.readHandshake() @@ -56,16 +76,19 @@ func (c *Conn) clientHandshake() error { if !ok { return c.sendAlert(alertUnexpectedMessage) } - finishedHash.Write(serverHello.marshal()) - vers, ok := mutualVersion(serverHello.vers) - if !ok || vers < versionTLS10 { + vers, ok := c.config.mutualVersion(serverHello.vers) + if !ok || vers < VersionTLS10 { // TLS 1.0 is the minimum version supported as a client. return c.sendAlert(alertProtocolVersion) } c.vers = vers c.haveVers = true + finishedHash := newFinishedHash(c.vers) + finishedHash.Write(hello.marshal()) + finishedHash.Write(serverHello.marshal()) + if serverHello.compressionMethod != compressionNone { return c.sendAlert(alertUnexpectedMessage) } @@ -121,7 +144,10 @@ func (c *Conn) clientHandshake() error { } } - if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok { + switch certs[0].PublicKey.(type) { + case *rsa.PublicKey, *ecdsa.PublicKey: + break + default: return c.sendAlert(alertUnsupportedCertificate) } @@ -148,7 +174,7 @@ func (c *Conn) clientHandshake() error { return err } - keyAgreement := suite.ka() + keyAgreement := suite.ka(c.vers) skx, ok := msg.(*serverKeyExchangeMsg) if ok { @@ -165,7 +191,7 @@ func (c *Conn) clientHandshake() error { } } - var certToSend *Certificate + var chainToSend *Certificate var certRequested bool certReq, ok := msg.(*certificateRequestMsg) if ok { @@ -184,12 +210,13 @@ func (c *Conn) clientHandshake() error { finishedHash.Write(certReq.marshal()) - // For now, we only know how to sign challenges with RSA - rsaAvail := false + var rsaAvail, ecdsaAvail bool for _, certType := range certReq.certificateTypes { - if certType == certTypeRSASign { + switch certType { + case certTypeRSASign: rsaAvail = true - break + case certTypeECDSASign: + ecdsaAvail = true } } @@ -197,35 +224,42 @@ func (c *Conn) clientHandshake() error { // where SignatureAlgorithm is RSA and the Issuer is in // certReq.certificateAuthorities findCert: - for i, cert := range c.config.Certificates { - if !rsaAvail { + for i, chain := range c.config.Certificates { + if !rsaAvail && !ecdsaAvail { continue } - leaf := cert.Leaf - if leaf == nil { - if leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) + for j, cert := range chain.Certificate { + x509Cert := chain.Leaf + // parse the certificate if this isn't the leaf + // node, or if chain.Leaf was nil + if j != 0 || x509Cert == nil { + if x509Cert, err = x509.ParseCertificate(cert); err != nil { + c.sendAlert(alertInternalError) + return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) + } } - } - - if leaf.PublicKeyAlgorithm != x509.RSA { - continue - } - if len(certReq.certificateAuthorities) == 0 { - // they gave us an empty list, so just take the - // first RSA cert from c.config.Certificates - certToSend = &cert - break - } + switch { + case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA: + case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA: + default: + continue findCert + } - for _, ca := range certReq.certificateAuthorities { - if bytes.Equal(leaf.RawIssuer, ca) { - certToSend = &cert + if len(certReq.certificateAuthorities) == 0 { + // they gave us an empty list, so just take the + // first RSA cert from c.config.Certificates + chainToSend = &chain break findCert } + + for _, ca := range certReq.certificateAuthorities { + if bytes.Equal(x509Cert.RawIssuer, ca) { + chainToSend = &chain + break findCert + } + } } } @@ -246,8 +280,8 @@ func (c *Conn) clientHandshake() error { // certificate to send. if certRequested { certMsg = new(certificateMsg) - if certToSend != nil { - certMsg.certificates = certToSend.Certificate + if chainToSend != nil { + certMsg.certificates = chainToSend.Certificate } finishedHash.Write(certMsg.marshal()) c.writeRecord(recordTypeHandshake, certMsg.marshal()) @@ -263,12 +297,29 @@ func (c *Conn) clientHandshake() error { c.writeRecord(recordTypeHandshake, ckx.marshal()) } - if certToSend != nil { - certVerify := new(certificateVerifyMsg) - digest := make([]byte, 0, 36) - digest = finishedHash.serverMD5.Sum(digest) - digest = finishedHash.serverSHA1.Sum(digest) - signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, digest) + if chainToSend != nil { + var signed []byte + certVerify := &certificateVerifyMsg{ + hasSignatureAndHash: c.vers >= VersionTLS12, + } + + switch key := c.config.Certificates[0].PrivateKey.(type) { + case *ecdsa.PrivateKey: + digest, _, hashId := finishedHash.hashForClientCertificate(signatureECDSA) + r, s, err := ecdsa.Sign(c.config.rand(), key, digest) + if err == nil { + signed, err = asn1.Marshal(ecdsaSignature{r, s}) + } + certVerify.signatureAndHash.signature = signatureECDSA + certVerify.signatureAndHash.hash = hashId + case *rsa.PrivateKey: + digest, hashFunc, hashId := finishedHash.hashForClientCertificate(signatureRSA) + signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest) + certVerify.signatureAndHash.signature = signatureRSA + certVerify.signatureAndHash.hash = hashId + default: + err = errors.New("unknown private key type") + } if err != nil { return c.sendAlert(alertInternalError) } @@ -282,8 +333,14 @@ func (c *Conn) clientHandshake() error { clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen) - clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */) - clientHash := suite.mac(c.vers, clientMAC) + var clientCipher interface{} + var clientHash macFunction + if suite.cipher != nil { + clientCipher = suite.cipher(clientKey, clientIV, false /* not for reading */) + clientHash = suite.mac(c.vers, clientMAC) + } else { + clientCipher = suite.aead(clientKey, clientIV) + } c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) @@ -303,8 +360,14 @@ func (c *Conn) clientHandshake() error { finishedHash.Write(finished.marshal()) c.writeRecord(recordTypeHandshake, finished.marshal()) - serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */) - serverHash := suite.mac(c.vers, serverMAC) + var serverCipher interface{} + var serverHash macFunction + if suite.cipher != nil { + serverCipher = suite.cipher(serverKey, serverIV, true /* for reading */) + serverHash = suite.mac(c.vers, serverMAC) + } else { + serverCipher = suite.aead(serverKey, serverIV) + } c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) c.readRecord(recordTypeChangeCipherSpec) if err := c.error(); err != nil { diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go index 9673947a409..6c564001b0d 100644 --- a/libgo/go/crypto/tls/handshake_client_test.go +++ b/libgo/go/crypto/tls/handshake_client_test.go @@ -39,16 +39,56 @@ func testClientScript(t *testing.T, name string, clientScript [][]byte, config * } } -func TestHandshakeClientRC4(t *testing.T) { +func TestHandshakeClientRSARC4(t *testing.T) { var config = *testConfig config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA} - testClientScript(t, "RC4", rc4ClientScript, &config) + testClientScript(t, "RSA-RC4", rsaRC4ClientScript, &config) } -func TestHandshakeClientECDHEAES(t *testing.T) { +func TestHandshakeClientECDHERSAAES(t *testing.T) { var config = *testConfig config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} - testClientScript(t, "ECDHE-AES", ecdheAESClientScript, &config) + testClientScript(t, "ECDHE-RSA-AES", ecdheRSAAESClientScript, &config) +} + +func TestHandshakeClientECDHECDSAAES(t *testing.T) { + var config = *testConfig + config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA} + config.Certificates = nil + config.BuildNameToCertificate() + testClientScript(t, "ECDHE-ECDSA-AES", ecdheECDSAAESClientScript, &config) +} + +func TestLongClientCerticiateChain(t *testing.T) { + config := *testConfig + cert, _ := X509KeyPair(testClientChainCertificate, testClientChainCertificate) + config.Certificates = []Certificate{cert} + testClientScript(t, "Long client certificate chains", clientChainCertificateScript, &config) +} + +func TestHandshakeClientTLS11(t *testing.T) { + var config = *testConfig + config.MaxVersion = VersionTLS11 + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} + testClientScript(t, "TLS11-ECDHE-AES", tls11ECDHEAESClientScript, &config) +} + +func TestHandshakeClientTLS12(t *testing.T) { + config := *testConfig + config.MaxVersion = VersionTLS12 + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} + cert, _ := X509KeyPair(testClientChainCertificate, testClientChainCertificate) + config.Certificates = []Certificate{cert} + testClientScript(t, "TLS12", clientTLS12Script, &config) +} + +func TestHandshakeClientTLS12ClientCert(t *testing.T) { + config := *testConfig + config.MaxVersion = VersionTLS12 + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256} + cert, _ := X509KeyPair(testClientChainCertificate, testClientChainCertificate) + config.Certificates = []Certificate{cert} + testClientScript(t, "TLS12ClientCert", clientTLS12ClientCertScript, &config) } var connect = flag.Bool("connect", false, "connect to a TLS server on :10443") @@ -79,6 +119,48 @@ func TestRunClient(t *testing.T) { record.WriteTo(os.Stdout) } +func TestEmptyRecords(t *testing.T) { + // emptyRecordScript contains a TLS connection with an empty record as + // the first application data from the server. This test ensures that + // the empty record doesn't cause (0, nil) to be returned from + // Conn.Read. + config := *testConfig + config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA} + + c, s := net.Pipe() + cli := Client(c, &config) + go func() { + buf := make([]byte, 1024) + n, err := cli.Read(buf) + defer c.Close() + defer cli.Close() + + if err != nil { + t.Fatalf("error reading from tls.Client: %s", err) + } + const expectedLength = 197 + if n != expectedLength { + t.Fatalf("incorrect length reading from tls.Client, got %d, want %d", n, expectedLength) + } + }() + + defer c.Close() + for i, b := range emptyRecordScript { + if i%2 == 1 { + s.Write(b) + continue + } + bb := make([]byte, len(b)) + _, err := io.ReadFull(s, bb) + if err != nil { + t.Fatalf("#%d: %s", i, err) + } + if !bytes.Equal(b, bb) { + t.Fatalf("#%d: mismatch on read: got:%x want:%x", i, bb, b) + } + } +} + // Script of interaction with gnutls implementation. // The values for this test are obtained by building and running in client mode: // % go test -test.run "TestRunClient" -connect @@ -110,7 +192,7 @@ func TestRunClient(t *testing.T) { // CSqGSIb3DQEBBQUAA0EAhTZAc8G7GtrUWZ8tonAxRnTsg26oyDxRrzms7EC86CJG // HZnWRiok1IsFCEv7NRFukrt3uuQSu/TIXpyBqJdgTA== // -----END CERTIFICATE----- -var rc4ClientScript = [][]byte{ +var rsaRC4ClientScript = [][]byte{ { 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -231,7 +313,7 @@ var rc4ClientScript = [][]byte{ }, } -var ecdheAESClientScript = [][]byte{ +var ecdheRSAAESClientScript = [][]byte{ { 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -406,3 +488,2563 @@ var ecdheAESClientScript = [][]byte{ 0x57, 0x33, 0xc3, 0xbc, 0x3f, 0x7a, 0x4d, }, } + +var emptyRecordScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, + 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x35, + 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, + 0x46, 0x03, 0x01, 0x51, 0x71, 0x8e, 0x03, 0x02, + 0xef, 0x09, 0xf2, 0x0e, 0xf5, 0x3b, 0x29, 0x9a, + 0xa8, 0x8b, 0x46, 0xa3, 0xd4, 0xb4, 0xc1, 0x14, + 0xc3, 0x19, 0x99, 0xba, 0x3d, 0x78, 0xcf, 0x50, + 0xd1, 0xe7, 0x26, 0x20, 0xa0, 0x37, 0x6d, 0xc9, + 0xae, 0x93, 0x33, 0x81, 0x20, 0xe3, 0xc1, 0x90, + 0x64, 0x6e, 0x67, 0x93, 0xdb, 0xb4, 0x04, 0x16, + 0xc4, 0x25, 0xdd, 0x10, 0x79, 0x3c, 0x18, 0x0a, + 0x7c, 0xfd, 0x28, 0x65, 0x00, 0x35, 0x00, 0x16, + 0x03, 0x01, 0x09, 0x9e, 0x0b, 0x00, 0x09, 0x9a, + 0x00, 0x09, 0x97, 0x00, 0x04, 0xea, 0x30, 0x82, + 0x04, 0xe6, 0x30, 0x82, 0x03, 0xce, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x11, 0x00, 0xff, 0xab, + 0x02, 0x93, 0xe0, 0x72, 0x99, 0x18, 0x6c, 0x9e, + 0x96, 0xb8, 0xb9, 0xf7, 0x47, 0xcb, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x41, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x47, + 0x41, 0x4e, 0x44, 0x49, 0x20, 0x53, 0x41, 0x53, + 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x15, 0x47, 0x61, 0x6e, 0x64, 0x69, + 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, + 0x64, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, + 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x31, + 0x34, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, + 0x30, 0x62, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x13, 0x18, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x20, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x20, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1b, + 0x47, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x53, 0x74, + 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x57, + 0x69, 0x6c, 0x64, 0x63, 0x61, 0x72, 0x64, 0x20, + 0x53, 0x53, 0x4c, 0x31, 0x17, 0x30, 0x15, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x14, 0x0e, 0x2a, 0x2e, + 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, + 0x02, 0x82, 0x01, 0x01, 0x00, 0xdc, 0xe3, 0xfd, + 0xce, 0xc1, 0x66, 0x62, 0x28, 0x8b, 0x99, 0x65, + 0x72, 0x52, 0x88, 0x93, 0x5b, 0x3f, 0x8d, 0xde, + 0x2b, 0xb0, 0xa0, 0xf4, 0xbd, 0xb4, 0x07, 0x5f, + 0x9e, 0x01, 0x47, 0x60, 0x57, 0x5f, 0xdf, 0xdc, + 0x63, 0x28, 0x1c, 0x1e, 0x5b, 0xc8, 0xe6, 0x29, + 0xdd, 0xeb, 0x26, 0x63, 0xd5, 0xbf, 0x83, 0xb2, + 0x2d, 0xcd, 0x2c, 0xa0, 0xb6, 0x91, 0xad, 0xaf, + 0x95, 0x21, 0x1d, 0x1f, 0x39, 0x8d, 0x3e, 0x17, + 0xd6, 0xbd, 0x99, 0xf5, 0x6c, 0xd4, 0xcb, 0x79, + 0x12, 0x3e, 0x11, 0xb9, 0x7e, 0x62, 0xbc, 0x2d, + 0xbf, 0xe0, 0x55, 0x1b, 0x5c, 0x1e, 0xce, 0x31, + 0xd9, 0xf8, 0x56, 0x68, 0x95, 0x2b, 0x15, 0x84, + 0x35, 0xae, 0x98, 0x2c, 0x63, 0x01, 0xb2, 0x0d, + 0xab, 0xa8, 0x61, 0xef, 0x7f, 0x15, 0x2c, 0x6d, + 0xf7, 0x67, 0x1d, 0xb8, 0x8d, 0xf6, 0xa2, 0x1c, + 0x4e, 0x85, 0xf0, 0xea, 0x1a, 0x2b, 0xc8, 0xac, + 0x70, 0x86, 0x9a, 0xbb, 0x9e, 0x9d, 0xbd, 0xc9, + 0x87, 0x2b, 0x9f, 0x5e, 0x40, 0x44, 0x9b, 0xba, + 0x96, 0x45, 0x24, 0xbc, 0x49, 0xb8, 0xfe, 0x26, + 0x3a, 0x1d, 0x1a, 0x0a, 0x3a, 0x90, 0x9c, 0x75, + 0x51, 0x59, 0x89, 0x98, 0x1a, 0x56, 0xe1, 0x3a, + 0x1a, 0xba, 0xff, 0xb4, 0x37, 0x7d, 0xd8, 0x99, + 0xe2, 0xeb, 0x45, 0x27, 0xe2, 0x42, 0x42, 0x46, + 0xbb, 0x00, 0x29, 0x9f, 0x30, 0xc9, 0x1e, 0x6c, + 0xce, 0x59, 0x0e, 0xbe, 0x16, 0x03, 0x31, 0xec, + 0x10, 0xc1, 0x6d, 0xca, 0x9d, 0x5f, 0x6d, 0xf1, + 0x26, 0x11, 0xe5, 0x50, 0xa1, 0xbb, 0x67, 0xb2, + 0xe0, 0x2b, 0xed, 0x76, 0x5b, 0xc7, 0x68, 0xc0, + 0x18, 0xad, 0x91, 0x9e, 0xb5, 0xd4, 0x4d, 0x21, + 0xcd, 0x98, 0xd9, 0xe0, 0x05, 0x0a, 0x4d, 0x24, + 0xa3, 0xe6, 0x12, 0x04, 0xdd, 0x50, 0xe6, 0xc8, + 0x7a, 0x69, 0xb9, 0x32, 0x43, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0xb6, 0x30, 0x82, + 0x01, 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb6, + 0xa8, 0xff, 0xa2, 0xa8, 0x2f, 0xd0, 0xa6, 0xcd, + 0x4b, 0xb1, 0x68, 0xf3, 0xe7, 0x50, 0x10, 0x31, + 0xa7, 0x79, 0x21, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62, 0x37, + 0xd4, 0x3c, 0xbf, 0xd9, 0xc2, 0x99, 0xf3, 0x28, + 0x3e, 0xdb, 0xca, 0xee, 0xf3, 0xb3, 0xc8, 0x73, + 0xb0, 0x3c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x05, 0xa0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, + 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, + 0x60, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x59, + 0x30, 0x57, 0x30, 0x4b, 0x06, 0x0b, 0x2b, 0x06, + 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x02, + 0x1a, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, + 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x67, 0x61, 0x6e, 0x64, + 0x69, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x2f, + 0x66, 0x72, 0x2f, 0x73, 0x73, 0x6c, 0x2f, 0x63, + 0x70, 0x73, 0x2f, 0x70, 0x64, 0x66, 0x2f, 0x30, + 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, + 0x01, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x35, 0x30, 0x33, 0x30, 0x31, 0xa0, 0x2f, + 0xa0, 0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, + 0x61, 0x6e, 0x64, 0x69, 0x2e, 0x6e, 0x65, 0x74, + 0x2f, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x53, 0x74, + 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x53, 0x53, + 0x4c, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x6a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x5e, 0x30, 0x5c, 0x30, + 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x02, 0x86, 0x2b, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, + 0x67, 0x61, 0x6e, 0x64, 0x69, 0x2e, 0x6e, 0x65, + 0x74, 0x2f, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x53, + 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x53, + 0x53, 0x4c, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, + 0x30, 0x21, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x01, 0x86, 0x15, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, + 0x70, 0x2e, 0x67, 0x61, 0x6e, 0x64, 0x69, 0x2e, + 0x6e, 0x65, 0x74, 0x30, 0x27, 0x06, 0x03, 0x55, + 0x1d, 0x11, 0x04, 0x20, 0x30, 0x1e, 0x82, 0x0e, + 0x2a, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x82, 0x0c, + 0x66, 0x72, 0x65, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x5b, 0x4a, 0x3a, 0x1d, 0x75, 0xe0, 0xc0, 0x9e, + 0xc9, 0x16, 0x66, 0x7f, 0x73, 0x95, 0x6e, 0x35, + 0xe4, 0x27, 0xfa, 0x8c, 0x9d, 0xee, 0xb1, 0x37, + 0x42, 0x3f, 0x54, 0x6a, 0x9d, 0x41, 0x84, 0x57, + 0xe1, 0x03, 0x3d, 0x69, 0x61, 0x77, 0x3b, 0x91, + 0xa2, 0x70, 0x94, 0xb6, 0x8e, 0x41, 0x63, 0x70, + 0xf2, 0x16, 0x04, 0x50, 0x05, 0x14, 0xfb, 0x59, + 0x7d, 0x89, 0x09, 0x3f, 0xb6, 0xef, 0xca, 0x3c, + 0x89, 0x88, 0x08, 0xe9, 0xa1, 0xf3, 0x33, 0x31, + 0x05, 0x4d, 0x70, 0xff, 0xdd, 0xa7, 0xd2, 0xe2, + 0xa0, 0x94, 0x3a, 0xf7, 0xc2, 0x9f, 0xad, 0x2b, + 0x2e, 0x20, 0xfa, 0x6c, 0xe1, 0xfc, 0xe6, 0x62, + 0x22, 0xa1, 0x38, 0x93, 0xec, 0x3e, 0xce, 0xfd, + 0x1f, 0xdd, 0xd4, 0x7c, 0x39, 0x46, 0x8b, 0xb4, + 0x64, 0xfa, 0xa1, 0x46, 0x87, 0x78, 0x2c, 0xd7, + 0x9c, 0xdd, 0x60, 0xd6, 0xda, 0x8e, 0xd8, 0x29, + 0x6d, 0x61, 0xa7, 0x29, 0x07, 0x76, 0xfc, 0xf9, + 0xbd, 0xfd, 0x14, 0xeb, 0x44, 0x70, 0xff, 0xd0, + 0x23, 0x99, 0x83, 0xc5, 0x5c, 0x56, 0x88, 0xaa, + 0x34, 0xda, 0xa6, 0xb3, 0x9a, 0xbf, 0xda, 0x58, + 0x1e, 0xa4, 0xb8, 0xc0, 0x40, 0x9d, 0xf0, 0xfc, + 0xf1, 0x23, 0xc2, 0xbc, 0x59, 0xe1, 0x82, 0xed, + 0x5d, 0xfb, 0x99, 0xaf, 0xf5, 0xf5, 0x15, 0xb8, + 0x8b, 0x59, 0xce, 0xaa, 0xca, 0xdf, 0xdc, 0x94, + 0x11, 0xe0, 0x96, 0xbf, 0x9f, 0x54, 0xa4, 0x9f, + 0x54, 0x36, 0x4a, 0xe8, 0x93, 0xda, 0xf4, 0x8c, + 0xb0, 0x6b, 0x8d, 0x4a, 0x9e, 0x11, 0xae, 0xcb, + 0xcb, 0x33, 0x8a, 0x4d, 0xcd, 0x4e, 0xa5, 0x9b, + 0xe9, 0x14, 0x46, 0x43, 0x9b, 0x96, 0x5f, 0x6d, + 0xf2, 0xea, 0x40, 0xef, 0x14, 0xc3, 0x99, 0x9f, + 0x23, 0x1e, 0xa5, 0x13, 0xab, 0x08, 0xea, 0x8f, + 0x68, 0x5b, 0x7d, 0x71, 0xdf, 0x18, 0xd1, 0x57, + 0x00, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x30, + 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x10, 0x5a, 0xb6, 0x1d, 0xac, 0x1e, 0x4d, + 0xa2, 0x06, 0x14, 0xc7, 0x55, 0x3d, 0x3d, 0xa9, + 0xb2, 0xdc, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, + 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, + 0x6b, 0x65, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, + 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54, 0x4e, + 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, + 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, + 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d, 0x30, + 0x38, 0x31, 0x30, 0x32, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, + 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, + 0x33, 0x38, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x09, 0x47, 0x41, 0x4e, + 0x44, 0x49, 0x20, 0x53, 0x41, 0x53, 0x31, 0x1e, + 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x15, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x53, + 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, + 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb6, + 0x54, 0x3d, 0xa5, 0xdb, 0x0d, 0x22, 0x78, 0x50, + 0x6a, 0x5a, 0x23, 0x89, 0x3f, 0x97, 0xa1, 0xd4, + 0x07, 0x1a, 0xa9, 0x58, 0x08, 0x9b, 0xa0, 0x15, + 0xc3, 0x32, 0xb6, 0xb7, 0xf1, 0xe8, 0xb9, 0xa5, + 0x6f, 0xad, 0x37, 0xf6, 0x6e, 0x71, 0x1b, 0xb4, + 0x75, 0x2d, 0x48, 0x5e, 0x9f, 0xc6, 0x15, 0xaa, + 0x81, 0xef, 0xe5, 0xc4, 0x88, 0x95, 0x8a, 0x3a, + 0x6c, 0x77, 0xcc, 0xb5, 0xcd, 0x65, 0xe4, 0x67, + 0xe5, 0x73, 0xc9, 0x50, 0x52, 0x94, 0xc1, 0x27, + 0x49, 0x3e, 0xa0, 0x6b, 0x41, 0x16, 0x41, 0xb6, + 0x94, 0x99, 0x41, 0xae, 0x3e, 0xcb, 0xe2, 0x06, + 0x46, 0x09, 0xe9, 0x4d, 0xbe, 0xc9, 0x4c, 0x55, + 0xa9, 0x18, 0x7e, 0xa6, 0xdf, 0x6e, 0xfd, 0x4a, + 0xb2, 0xcc, 0x6c, 0x4e, 0xd9, 0xc8, 0x50, 0x15, + 0x93, 0xb3, 0xf2, 0xe9, 0xe3, 0xc2, 0x6a, 0xad, + 0x3a, 0xd5, 0xfb, 0xc3, 0x79, 0x50, 0x9f, 0x25, + 0x79, 0x29, 0xb2, 0x47, 0x64, 0x7c, 0x20, 0x3e, + 0xe2, 0x08, 0x4d, 0x93, 0x29, 0x14, 0xb6, 0x34, + 0x6e, 0xcf, 0x71, 0x46, 0x7e, 0x76, 0x10, 0xf4, + 0xfd, 0x6c, 0xaa, 0x01, 0xd2, 0xc2, 0x06, 0xde, + 0x92, 0x83, 0xcc, 0x58, 0x90, 0x2e, 0x92, 0xde, + 0x1e, 0x65, 0xb7, 0x63, 0x2f, 0x3d, 0xb2, 0xeb, + 0x70, 0x8c, 0x4c, 0xe0, 0xbe, 0x15, 0x9d, 0xde, + 0xc1, 0x4d, 0x56, 0xf8, 0x0b, 0xc6, 0x8e, 0x07, + 0xb9, 0x5d, 0xdf, 0x95, 0xf0, 0x7b, 0x40, 0x1f, + 0x1a, 0x2c, 0xd7, 0x9c, 0x2b, 0x4b, 0x76, 0xf4, + 0x59, 0xf5, 0x43, 0xc1, 0x2c, 0x66, 0x10, 0x9e, + 0x9e, 0x66, 0x96, 0x60, 0x9d, 0x1c, 0x74, 0x1b, + 0x4e, 0x18, 0x5c, 0x08, 0xb0, 0x6e, 0x6c, 0xca, + 0x69, 0x1a, 0x02, 0xe9, 0xbb, 0xca, 0x78, 0xef, + 0x66, 0x2e, 0xe3, 0x32, 0xfd, 0x41, 0x5c, 0x95, + 0x74, 0x81, 0x4d, 0xf4, 0xda, 0xfe, 0x4b, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3e, + 0x30, 0x82, 0x01, 0x3a, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98, + 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, + 0x9d, 0x4b, 0xd2, 0xc3, 0x45, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xb6, 0xa8, 0xff, 0xa2, 0xa8, 0x2f, 0xd0, 0xa6, + 0xcd, 0x4b, 0xb1, 0x68, 0xf3, 0xe7, 0x50, 0x10, + 0x31, 0xa7, 0x79, 0x21, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x18, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x11, 0x30, 0x0f, 0x30, 0x0d, 0x06, 0x0b, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, + 0x02, 0x1a, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, + 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, 0x54, + 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, + 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, + 0x77, 0x61, 0x72, 0x65, 0x2e, 0x63, 0x72, 0x6c, + 0x30, 0x74, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x01, 0x01, 0x04, 0x68, 0x30, 0x66, + 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x02, 0x86, 0x31, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x55, + 0x54, 0x4e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, + 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0x19, 0x53, 0xbf, 0x03, 0x3d, 0x9b, + 0xe2, 0x6b, 0x5a, 0xfd, 0xba, 0x49, 0x1f, 0x4f, + 0xec, 0xe1, 0xc6, 0x82, 0x39, 0x3c, 0xd2, 0x03, + 0x04, 0x0f, 0xab, 0x7b, 0x3e, 0x82, 0xa9, 0x85, + 0x10, 0x1f, 0xf4, 0xde, 0x32, 0xaf, 0x58, 0x3f, + 0xff, 0x70, 0xf3, 0x30, 0x1d, 0x97, 0x2d, 0x4c, + 0x9a, 0xe2, 0xec, 0x0c, 0x3e, 0x14, 0x2d, 0x2f, + 0x98, 0x48, 0x9d, 0xae, 0x16, 0x6a, 0xac, 0x2d, + 0x42, 0xaa, 0xb5, 0x64, 0xa4, 0x70, 0xbb, 0xeb, + 0x73, 0x94, 0x7b, 0x46, 0x4c, 0xe7, 0x7a, 0x14, + 0x76, 0x5b, 0x4c, 0x1d, 0x84, 0xa1, 0x20, 0x74, + 0x1f, 0x2e, 0x4b, 0x5c, 0x70, 0x88, 0xdc, 0xbd, + 0xf7, 0x19, 0x3d, 0xed, 0x59, 0x0d, 0xe2, 0x3f, + 0x26, 0xe2, 0x9c, 0xac, 0xa4, 0x3c, 0x95, 0x1c, + 0xf8, 0xbe, 0x8c, 0x03, 0xae, 0xf0, 0xe5, 0x9c, + 0x4d, 0xbc, 0xc7, 0x9b, 0x58, 0x00, 0xbf, 0xaf, + 0xad, 0xfa, 0x37, 0x6e, 0x71, 0x6d, 0x18, 0x34, + 0x0e, 0xc1, 0xea, 0x6a, 0xf8, 0x0d, 0xdf, 0x69, + 0x54, 0x56, 0x15, 0xf2, 0x28, 0xb3, 0xfe, 0xa4, + 0x63, 0xec, 0xc5, 0x04, 0x64, 0x60, 0xbb, 0xfe, + 0x2a, 0xf0, 0xf4, 0x87, 0xa1, 0xb0, 0xae, 0xbd, + 0xaa, 0xe4, 0x2f, 0xe3, 0x03, 0x0b, 0x2f, 0x66, + 0x5f, 0x85, 0xa4, 0x32, 0x7b, 0x46, 0xed, 0x25, + 0x0c, 0xe7, 0xf1, 0xb7, 0xe7, 0x19, 0xfd, 0x60, + 0xba, 0x5f, 0x87, 0x77, 0xde, 0x98, 0x07, 0x96, + 0xe4, 0x5e, 0xea, 0x63, 0x7d, 0xa8, 0xde, 0x55, + 0xda, 0x61, 0x5c, 0x3c, 0x90, 0x83, 0x43, 0x04, + 0x07, 0x3c, 0xdd, 0xf3, 0xf8, 0x9f, 0x06, 0x52, + 0x0a, 0xde, 0xc7, 0xb6, 0x7b, 0x8f, 0xe1, 0x11, + 0xf7, 0x04, 0x7a, 0x35, 0xff, 0x6a, 0xbc, 0x5b, + 0xc7, 0x50, 0x49, 0x08, 0x70, 0x6f, 0x94, 0x43, + 0xcd, 0x9e, 0xc7, 0x70, 0xf1, 0xdb, 0xd0, 0x6d, + 0xda, 0x8f, 0x16, 0x03, 0x01, 0x00, 0x0e, 0x0d, + 0x00, 0x00, 0x06, 0x03, 0x01, 0x02, 0x40, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, + 0xba, 0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, + 0x82, 0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, + 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, + 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, + 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, + 0x39, 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, + 0x31, 0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, + 0x30, 0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, + 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, + 0x00, 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, + 0xbf, 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, + 0x2b, 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, + 0x7a, 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, + 0x65, 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, + 0xb4, 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, + 0x62, 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, + 0x5c, 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, + 0x58, 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, + 0xd0, 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, + 0x9f, 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, + 0x18, 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, + 0xf1, 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, + 0xc9, 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, + 0x01, 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, + 0x1d, 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, + 0x79, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, + 0xa7, 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, + 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, + 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, + 0x18, 0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, + 0xb1, 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, + 0xdb, 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, + 0x8e, 0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, + 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, + 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, + 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, + 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, + 0xb8, 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, + 0x81, 0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, + 0x6b, 0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, + 0xb0, 0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, + 0xb5, 0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, + 0xae, 0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, + 0x6e, 0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, + 0xb5, 0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, + 0x30, 0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, + 0xe7, 0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, + 0x78, 0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, + 0x2d, 0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, + 0x75, 0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, + 0xcd, 0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, + 0x1c, 0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, + 0x57, 0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, + 0x9b, 0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, + 0xa7, 0xbd, 0xd9, 0x16, 0x03, 0x01, 0x01, 0x06, + 0x10, 0x00, 0x01, 0x02, 0x01, 0x00, 0x25, 0x48, + 0x6c, 0x0a, 0xde, 0x9d, 0x3a, 0x57, 0xe4, 0x2e, + 0xb9, 0xfc, 0xb4, 0x46, 0x1f, 0x20, 0x4f, 0x58, + 0x4d, 0x12, 0x08, 0xb4, 0x3e, 0x4c, 0xf5, 0xa8, + 0xa5, 0x16, 0x40, 0x29, 0x19, 0x04, 0x4d, 0xf9, + 0x54, 0x3a, 0x32, 0xd7, 0x79, 0xf2, 0x0e, 0xc1, + 0x7b, 0x0c, 0x62, 0x71, 0xbb, 0xb4, 0x8c, 0xe7, + 0x84, 0xd5, 0xf8, 0x11, 0x77, 0x7f, 0x87, 0x6c, + 0xfc, 0x25, 0xf3, 0x2d, 0x97, 0x3d, 0x1f, 0xf5, + 0xfc, 0x64, 0x94, 0x9f, 0xdd, 0x90, 0x82, 0xdd, + 0x11, 0x74, 0x74, 0x59, 0xa2, 0x1a, 0x71, 0xb2, + 0x55, 0x6d, 0x18, 0xca, 0x85, 0x47, 0x8b, 0x79, + 0x73, 0x06, 0x24, 0x38, 0xc3, 0x34, 0x98, 0x84, + 0x62, 0x81, 0xd8, 0xad, 0x54, 0xad, 0x13, 0xa5, + 0xf4, 0xe4, 0x82, 0x85, 0xd3, 0xe3, 0x9e, 0xeb, + 0xb5, 0xf5, 0x95, 0x83, 0x0e, 0xb9, 0x7d, 0xb6, + 0xda, 0x0c, 0xf6, 0x14, 0x6a, 0x60, 0x8c, 0x75, + 0x56, 0xf0, 0xe9, 0x60, 0xe0, 0x4c, 0xf4, 0x4e, + 0x84, 0x8b, 0x4f, 0xf4, 0x2f, 0xde, 0xb7, 0xec, + 0x61, 0xd3, 0x77, 0x07, 0x6e, 0x41, 0x57, 0xc9, + 0xd9, 0x1d, 0x75, 0xee, 0x42, 0x63, 0xdc, 0x58, + 0xad, 0xfc, 0xc7, 0xe1, 0x77, 0x49, 0xb1, 0x58, + 0x21, 0x96, 0x00, 0x55, 0x90, 0x6b, 0xf6, 0x2a, + 0x5a, 0x19, 0x25, 0x93, 0x59, 0x9d, 0xaf, 0x79, + 0x9b, 0x18, 0x5d, 0xf6, 0x5d, 0x64, 0x4b, 0x9a, + 0xf4, 0xde, 0xf2, 0x7f, 0xbd, 0x93, 0x7e, 0x45, + 0x3e, 0x17, 0xae, 0xbf, 0x52, 0xe1, 0xba, 0x8e, + 0x0b, 0xbc, 0x1e, 0x91, 0x9d, 0xf1, 0x4e, 0x0b, + 0xab, 0x9e, 0x5c, 0x4c, 0x6f, 0xf7, 0xf3, 0x8d, + 0x8c, 0x6d, 0xeb, 0x46, 0x05, 0x36, 0x7e, 0x2f, + 0x9c, 0xa1, 0x86, 0x15, 0xe1, 0xe4, 0xb4, 0x20, + 0x06, 0x44, 0x7b, 0x3c, 0x8b, 0x13, 0x96, 0xf5, + 0x02, 0xb1, 0x4f, 0x3c, 0x2d, 0x4a, 0x16, 0x03, + 0x01, 0x00, 0x86, 0x0f, 0x00, 0x00, 0x82, 0x00, + 0x80, 0x52, 0xb1, 0x0d, 0xfc, 0x85, 0x34, 0x56, + 0xb9, 0xdf, 0xa7, 0x8e, 0xf4, 0xfd, 0x02, 0x46, + 0x8a, 0x23, 0xcc, 0x53, 0x3b, 0x0f, 0xa7, 0x61, + 0xf3, 0xb5, 0xbf, 0xfe, 0x59, 0x77, 0x10, 0xd6, + 0x56, 0x93, 0x19, 0x6b, 0x2c, 0xf1, 0x35, 0x71, + 0xe3, 0x36, 0x2f, 0xa0, 0x90, 0x4e, 0x5a, 0xdf, + 0x8d, 0x06, 0x88, 0xcf, 0xb1, 0x06, 0x56, 0x8b, + 0x74, 0x8f, 0x02, 0x8e, 0x10, 0xd2, 0xab, 0x8d, + 0x3f, 0x3e, 0x02, 0xf1, 0x1a, 0x80, 0x6d, 0x0f, + 0x9e, 0x77, 0xd8, 0xfa, 0x92, 0xb3, 0x16, 0x40, + 0xeb, 0x9e, 0xca, 0xd7, 0xe4, 0x31, 0xcc, 0x63, + 0x5f, 0xe2, 0x4c, 0x85, 0x0e, 0xf2, 0xdd, 0xd3, + 0xfe, 0x7e, 0xa7, 0x60, 0x1c, 0xb4, 0x00, 0xd8, + 0xbe, 0x4b, 0x9b, 0x66, 0x78, 0x0f, 0xfb, 0x3b, + 0x52, 0x30, 0x2b, 0x8b, 0xd9, 0xef, 0x82, 0x0a, + 0xa4, 0x18, 0x1d, 0xb0, 0xb5, 0xbf, 0x54, 0x97, + 0x0c, 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, + 0x03, 0x01, 0x00, 0x30, 0xa1, 0x74, 0x22, 0xd8, + 0x86, 0x6a, 0xbe, 0x53, 0x34, 0x1d, 0xb3, 0x73, + 0xff, 0x51, 0xc0, 0xce, 0x8e, 0x7d, 0x9b, 0xab, + 0xcb, 0x8b, 0x79, 0xae, 0x04, 0x01, 0xa7, 0xf2, + 0x8e, 0x9d, 0xab, 0xa3, 0x73, 0x80, 0x5c, 0xff, + 0x96, 0x20, 0xbb, 0x8d, 0xc0, 0x02, 0x66, 0x6c, + 0x83, 0x4b, 0x78, 0x20, + }, + { + 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x01, 0x00, 0x30, 0x29, 0xd4, 0xfd, 0x03, 0x8b, + 0x30, 0x20, 0xf7, 0xca, 0xc0, 0x6c, 0x83, 0x5d, + 0x73, 0xcb, 0x81, 0x60, 0xe0, 0x9a, 0x09, 0xcb, + 0x33, 0x03, 0x80, 0x81, 0x4e, 0x84, 0x47, 0xd5, + 0x74, 0x6c, 0x3b, 0xb5, 0xc0, 0x48, 0x0d, 0x52, + 0xdd, 0xbe, 0xc2, 0x06, 0xf5, 0x79, 0x2b, 0x3e, + 0x99, 0x56, 0x94, 0x17, 0x03, 0x01, 0x00, 0x20, + 0x26, 0x46, 0x90, 0x9d, 0xef, 0x59, 0x00, 0xb6, + 0x70, 0xe8, 0x1e, 0x1a, 0x80, 0x8b, 0x04, 0xb2, + 0xfc, 0x51, 0xf8, 0x93, 0xbe, 0x00, 0x28, 0xba, + 0xb8, 0xdc, 0x51, 0x7e, 0x92, 0x80, 0xfa, 0xf2, + 0x17, 0x03, 0x01, 0x00, 0xe0, 0xb8, 0x2e, 0xc4, + 0x6b, 0x3f, 0xda, 0x39, 0x87, 0x7f, 0x03, 0x43, + 0x28, 0xdd, 0xb9, 0xf9, 0x9e, 0x16, 0xf5, 0xce, + 0x3f, 0x7e, 0x6a, 0x7b, 0xb3, 0x60, 0x14, 0xe1, + 0xea, 0x54, 0xc5, 0xe6, 0x05, 0x0a, 0x6c, 0xe0, + 0xef, 0x58, 0x29, 0x8a, 0x77, 0x64, 0x77, 0x5d, + 0x9c, 0xe2, 0xe0, 0x3c, 0x6d, 0x87, 0x82, 0xbe, + 0x47, 0x63, 0xd4, 0xfd, 0x0c, 0x25, 0xc4, 0xb1, + 0xfe, 0x29, 0x6f, 0x84, 0xfb, 0xab, 0x6e, 0xa7, + 0xf9, 0x22, 0x89, 0x97, 0x5b, 0x91, 0x0a, 0x07, + 0xe0, 0xef, 0x3d, 0x67, 0xee, 0x87, 0xa8, 0x33, + 0x02, 0x64, 0x33, 0xca, 0x15, 0x10, 0xb9, 0x57, + 0xd8, 0xe5, 0x1a, 0x4b, 0xe3, 0x45, 0xc1, 0x62, + 0x85, 0x50, 0xf1, 0x79, 0x54, 0xe1, 0x2e, 0x25, + 0x01, 0x3c, 0xdb, 0x2d, 0x39, 0x14, 0x2f, 0x9b, + 0xd0, 0x1d, 0xc1, 0xac, 0x73, 0x7d, 0xa4, 0xed, + 0x89, 0x98, 0xb1, 0xae, 0x8a, 0x9e, 0xc8, 0xa7, + 0xfe, 0x55, 0x27, 0xb5, 0xb5, 0xa2, 0xec, 0x7e, + 0xe3, 0x6b, 0x45, 0x19, 0xfa, 0x20, 0x1c, 0x33, + 0x83, 0x22, 0x33, 0x97, 0xd2, 0x5a, 0xc4, 0xf8, + 0x9a, 0x03, 0x13, 0x85, 0xf2, 0x2b, 0x04, 0x59, + 0x27, 0xd7, 0x0b, 0x42, 0x47, 0x9b, 0x7d, 0x4d, + 0xb2, 0x1a, 0x85, 0x7f, 0x97, 0xc2, 0xf2, 0x10, + 0xf0, 0xfa, 0x4e, 0x4b, 0x62, 0x43, 0x3a, 0x09, + 0x2e, 0xcd, 0x8f, 0xa8, 0xb6, 0x0b, 0x5f, 0x34, + 0xd7, 0x3b, 0xba, 0xd9, 0xe5, 0x01, 0x2d, 0x35, + 0xae, 0xc5, 0x4c, 0xab, 0x40, 0x64, 0xc2, 0xc9, + 0x8c, 0x69, 0x44, 0xf4, 0xb8, 0xb5, 0x3a, 0x05, + 0x3c, 0x29, 0x19, 0xb4, 0x09, 0x17, 0x03, 0x01, + 0x00, 0x20, 0xc8, 0xc5, 0xb7, 0xe3, 0xd2, 0x3e, + 0x27, 0xb5, 0x71, 0x8f, 0x52, 0x0b, 0xce, 0x17, + 0x64, 0x86, 0xa4, 0x34, 0x16, 0x1b, 0x61, 0x64, + 0x7c, 0xb3, 0xf2, 0xe5, 0x3e, 0xfd, 0xdd, 0xfb, + 0x40, 0x78, 0x17, 0x03, 0x01, 0x00, 0x50, 0x8e, + 0x79, 0xf0, 0x8e, 0x76, 0x5d, 0x34, 0x09, 0xdc, + 0xec, 0x6d, 0xc3, 0x43, 0x1d, 0xcb, 0x2d, 0xaa, + 0x08, 0x7a, 0x51, 0x94, 0x4e, 0xc5, 0x26, 0xe4, + 0x0b, 0x8e, 0x8f, 0x51, 0xf2, 0x9f, 0xeb, 0xc3, + 0x18, 0x43, 0x95, 0x15, 0xfc, 0x59, 0x18, 0x25, + 0x47, 0xb6, 0x4a, 0x6e, 0xa3, 0xa4, 0x3b, 0xa3, + 0x47, 0x34, 0x74, 0x6b, 0xc5, 0x3d, 0x41, 0x14, + 0x64, 0xd5, 0x69, 0x5f, 0x77, 0xf3, 0x7c, 0x41, + 0xc6, 0xed, 0x2e, 0xcf, 0xff, 0x40, 0xf2, 0xce, + 0xbb, 0xa7, 0x4e, 0x73, 0x88, 0x98, 0x10, + }, + { + 0x15, 0x03, 0x01, 0x00, 0x20, 0x1a, 0xbc, 0x70, + 0x24, 0xf8, 0xfb, 0xf2, 0x4a, 0xf9, 0x44, 0x1e, + 0x58, 0xf8, 0xaa, 0x41, 0x24, 0xe8, 0x80, 0x33, + 0x45, 0x18, 0xa1, 0x5d, 0xee, 0x16, 0x80, 0xae, + 0x40, 0x41, 0x8e, 0x41, 0x9b, + }, +} + +var tls11ECDHEAESClientScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, + 0x46, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13, + 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, + }, + { + 0x16, 0x03, 0x02, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x50, 0x03, 0x02, 0x51, 0x9f, 0xa2, 0x21, 0x1a, + 0xb7, 0x75, 0x42, 0x69, 0xd3, 0x14, 0xdd, 0x05, + 0x1e, 0xda, 0x13, 0x71, 0x8d, 0x6a, 0x45, 0x97, + 0xcb, 0xee, 0x0e, 0x77, 0x01, 0x0d, 0x6e, 0xe5, + 0x22, 0x70, 0x16, 0x20, 0x69, 0xfc, 0xa6, 0x9a, + 0xe8, 0x21, 0xcc, 0x46, 0x65, 0x05, 0xb4, 0x48, + 0x0f, 0x34, 0x63, 0x2c, 0xac, 0xa4, 0xf5, 0x4b, + 0x64, 0xd1, 0x07, 0x13, 0xa7, 0xe4, 0x5b, 0xa3, + 0x4d, 0x31, 0x41, 0x53, 0xc0, 0x13, 0x00, 0x00, + 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, + 0x02, 0x16, 0x03, 0x02, 0x02, 0x39, 0x0b, 0x00, + 0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, + 0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, + 0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, + 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, + 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, + 0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, + 0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, + 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, + 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, + 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, + 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, + 0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, + 0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, + 0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, + 0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, + 0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, + 0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, + 0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, + 0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, + 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, + 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, + 0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, + 0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, + 0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, + 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, + 0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, + 0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, + 0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, + 0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, + 0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, + 0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, + 0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, + 0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, + 0x03, 0x02, 0x00, 0x8b, 0x0c, 0x00, 0x00, 0x87, + 0x03, 0x00, 0x17, 0x41, 0x04, 0x34, 0xde, 0x50, + 0x32, 0x8f, 0x25, 0x6b, 0x37, 0x2c, 0x36, 0x24, + 0x27, 0x0e, 0xf9, 0x67, 0xb4, 0xf8, 0x29, 0x1c, + 0xa5, 0xa4, 0x59, 0x9a, 0xca, 0x40, 0x26, 0x15, + 0x61, 0x72, 0x34, 0x4a, 0xd3, 0x0c, 0xac, 0x69, + 0xcb, 0x2a, 0x9e, 0xf8, 0x80, 0xfb, 0x7a, 0xc4, + 0xd4, 0x4b, 0x91, 0x1b, 0xbe, 0x24, 0x26, 0xad, + 0x19, 0x24, 0xbe, 0x32, 0x58, 0xfb, 0xc7, 0x77, + 0xce, 0x7e, 0x71, 0x51, 0x1a, 0x00, 0x40, 0x1a, + 0x0b, 0xe8, 0x91, 0x84, 0x64, 0x54, 0xb6, 0x19, + 0xe8, 0xd4, 0x43, 0x7c, 0x09, 0x0c, 0x2e, 0xba, + 0x42, 0xb9, 0x74, 0xc3, 0x6c, 0x06, 0x9b, 0xa6, + 0x7e, 0x92, 0xe9, 0xee, 0x7c, 0x74, 0xa9, 0xd3, + 0x63, 0xf0, 0x16, 0x20, 0x60, 0x71, 0x8e, 0x24, + 0xc7, 0x7f, 0xc5, 0x5b, 0x9c, 0x19, 0x0c, 0x80, + 0x15, 0x61, 0xbf, 0xb6, 0xed, 0x5b, 0x7b, 0x90, + 0xc5, 0x05, 0x13, 0x72, 0x45, 0x79, 0xdf, 0x16, + 0x03, 0x02, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x02, 0x00, 0x46, 0x10, 0x00, 0x00, + 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, + 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, + 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, + 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, + 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, + 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, + 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, + 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, + 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x02, 0x00, 0x01, + 0x01, 0x16, 0x03, 0x02, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x50, + 0x32, 0x26, 0x51, 0xbd, 0xbd, 0x3c, 0x4f, 0x72, + 0xbf, 0xbc, 0x91, 0x70, 0x4b, 0x5d, 0x43, 0x4a, + 0x65, 0x26, 0x0d, 0xaa, 0xed, 0x00, 0x91, 0xaf, + 0x4f, 0x47, 0x09, 0xaa, 0x79, 0xc4, 0x47, 0x21, + 0x71, 0xd8, 0x2b, 0xc1, 0x51, 0xc8, 0xef, 0xed, + 0x67, 0xde, 0x97, 0xef, 0x18, 0x53, + }, + { + 0x14, 0x03, 0x02, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x02, 0x00, 0x40, 0x72, 0x20, 0xbf, 0xd1, 0xbd, + 0x83, 0x53, 0x57, 0xb0, 0x4e, 0xac, 0xba, 0x1a, + 0x2b, 0x2d, 0xeb, 0x8a, 0x48, 0x17, 0xfa, 0x69, + 0xf9, 0xb5, 0x94, 0x8e, 0x6f, 0x9c, 0xda, 0x59, + 0xba, 0x6c, 0x7c, 0x82, 0xe2, 0x53, 0xa9, 0x46, + 0xdc, 0x33, 0xa0, 0x9b, 0xf0, 0x1e, 0xf1, 0x53, + 0x83, 0x48, 0xbf, 0x5e, 0xef, 0x03, 0x2b, 0x50, + 0x7a, 0xa6, 0xf8, 0xc3, 0x9e, 0x24, 0x43, 0x3a, + 0xdf, 0x44, 0x3e, + }, + { + 0x17, 0x03, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x0b, 0x8f, + 0x6b, 0xf9, 0xd3, 0x9f, 0x2b, 0x49, 0xe0, 0x62, + 0x9a, 0x0b, 0x3e, 0xa2, 0x72, 0x8b, 0x96, 0x0c, + 0x41, 0x09, 0x95, 0x9e, 0x6b, 0x26, 0xa1, 0x46, + 0xca, 0xb8, 0xb6, 0xd2, 0xd4, 0x15, 0x03, 0x02, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0xd4, 0x84, 0xc6, 0x7e, 0x1c, + 0x2f, 0xbd, 0x6b, 0x45, 0x31, 0x1d, 0x7d, 0x8f, + 0x31, 0x39, 0x5a, 0x4e, 0xaa, 0xf1, 0x0a, 0x8a, + 0x6c, 0x33, 0x59, 0x19, 0xd8, 0x75, 0x80, 0xab, + 0x93, 0x81, + }, +} + +var clientChainCertificateScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, + 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, + 0x46, 0x03, 0x01, 0x51, 0xa2, 0x9b, 0x8b, 0xd4, + 0xe6, 0x33, 0xa2, 0x70, 0x38, 0x37, 0xba, 0x55, + 0x86, 0xcf, 0x87, 0xea, 0x6d, 0x2c, 0x3e, 0x17, + 0xc2, 0x09, 0xf8, 0x4d, 0xb0, 0x5d, 0x93, 0x2b, + 0x15, 0x99, 0x0c, 0x20, 0x5d, 0x61, 0x21, 0x2c, + 0xed, 0x49, 0x32, 0x29, 0x08, 0x6e, 0x21, 0x58, + 0x00, 0xdb, 0x34, 0xb7, 0x37, 0xcd, 0x27, 0x75, + 0x31, 0x1e, 0x6c, 0x74, 0xa6, 0xef, 0xa2, 0xc4, + 0x2b, 0x6c, 0xc3, 0x03, 0x00, 0x05, 0x00, 0x16, + 0x03, 0x01, 0x03, 0xef, 0x0b, 0x00, 0x03, 0xeb, + 0x00, 0x03, 0xe8, 0x00, 0x03, 0xe5, 0x30, 0x82, + 0x03, 0xe1, 0x30, 0x82, 0x02, 0xc9, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xcc, 0x22, + 0x4c, 0x4b, 0x98, 0xa2, 0x88, 0xfc, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, 0x86, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, + 0x4e, 0x59, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, + 0x6f, 0x6b, 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, + 0x4d, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, + 0x6f, 0x72, 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, + 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, + 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x33, 0x30, 0x35, 0x32, 0x36, + 0x32, 0x31, 0x30, 0x35, 0x30, 0x31, 0x5a, 0x17, + 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x34, 0x32, + 0x31, 0x30, 0x35, 0x30, 0x31, 0x5a, 0x30, 0x81, + 0x86, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x02, 0x4e, 0x59, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x42, 0x72, + 0x6f, 0x6f, 0x6b, 0x6c, 0x79, 0x6e, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x18, 0x4d, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x08, 0x6d, 0x79, 0x63, 0x61, + 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x21, 0x30, 0x1f, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, + 0x68, 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, + 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xf0, 0xfb, 0xad, 0x80, 0x5e, 0x37, 0xd3, 0x6d, + 0xee, 0x2e, 0xcc, 0xbc, 0x0c, 0xd7, 0x56, 0x4b, + 0x56, 0x45, 0xcd, 0x28, 0xb6, 0x22, 0xe9, 0xe2, + 0x0f, 0xd1, 0x87, 0x2a, 0x27, 0xce, 0x77, 0x8d, + 0x6e, 0x0e, 0x0f, 0xfb, 0x66, 0xe1, 0xb5, 0x0e, + 0x9a, 0xb6, 0x05, 0x8e, 0xb3, 0xe1, 0xc5, 0x77, + 0x86, 0x5b, 0x46, 0xd2, 0x0b, 0x92, 0x03, 0x1b, + 0x89, 0x0c, 0x1b, 0x10, 0x0e, 0x99, 0x8f, 0xe2, + 0x17, 0xe8, 0xc2, 0x30, 0x00, 0x47, 0xd6, 0xfc, + 0xf9, 0x0f, 0x3b, 0x75, 0x34, 0x8d, 0x4d, 0xb0, + 0x99, 0xb7, 0xa0, 0x6d, 0xa0, 0xb6, 0xad, 0xda, + 0x07, 0x5e, 0x38, 0x2e, 0x02, 0xe4, 0x30, 0x6d, + 0xae, 0x13, 0x72, 0xd4, 0xc8, 0xce, 0x14, 0x07, + 0xae, 0x23, 0x8c, 0x8f, 0x9e, 0x8c, 0x60, 0xd6, + 0x06, 0xb9, 0xef, 0x00, 0x18, 0xc0, 0x1d, 0x25, + 0x1e, 0xda, 0x3e, 0x2f, 0xcf, 0x2b, 0x56, 0x84, + 0x9e, 0x30, 0x21, 0xc7, 0x29, 0xf6, 0x03, 0x8a, + 0x24, 0xf9, 0x34, 0xac, 0x65, 0x9d, 0x80, 0x36, + 0xc8, 0x3b, 0x15, 0x10, 0xbd, 0x51, 0xe9, 0xbc, + 0x02, 0xe1, 0xe9, 0xb3, 0x5a, 0x9a, 0x99, 0x41, + 0x1b, 0x27, 0xa0, 0x4d, 0x50, 0x9e, 0x27, 0x7f, + 0xa1, 0x7d, 0x09, 0x87, 0xbd, 0x8a, 0xca, 0x5f, + 0xb1, 0xa5, 0x08, 0xb8, 0x04, 0xd4, 0x52, 0x89, + 0xaa, 0xe0, 0x7d, 0x42, 0x2e, 0x2f, 0x15, 0xee, + 0x66, 0x57, 0x0f, 0x13, 0x19, 0x45, 0xa8, 0x4b, + 0x5d, 0x81, 0x66, 0xcc, 0x12, 0x37, 0x94, 0x5e, + 0xfd, 0x3c, 0x10, 0x81, 0x51, 0x3f, 0xfa, 0x0f, + 0xdd, 0xa1, 0x89, 0x03, 0xa9, 0x78, 0x91, 0xf5, + 0x3b, 0xf3, 0xbc, 0xac, 0xbe, 0x93, 0x30, 0x2e, + 0xbe, 0xca, 0x7f, 0x46, 0xd3, 0x28, 0xb4, 0x4e, + 0x91, 0x7b, 0x5b, 0x43, 0x6c, 0xaf, 0x9b, 0x5c, + 0x6a, 0x6d, 0x5a, 0xdb, 0x79, 0x5e, 0x6a, 0x6b, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, + 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x6b, 0x1e, 0x00, 0xa8, + 0x9f, 0xfa, 0x7d, 0x00, 0xf9, 0xe0, 0x9d, 0x0f, + 0x90, 0x8c, 0x90, 0xa8, 0xa1, 0x37, 0x6b, 0xda, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0x6b, 0x1e, 0x00, + 0xa8, 0x9f, 0xfa, 0x7d, 0x00, 0xf9, 0xe0, 0x9d, + 0x0f, 0x90, 0x8c, 0x90, 0xa8, 0xa1, 0x37, 0x6b, + 0xda, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0xcd, 0x6f, 0x73, 0x4d, 0x56, + 0x0b, 0xf3, 0x2e, 0x1c, 0xe2, 0x02, 0x0c, 0x14, + 0xbb, 0x2f, 0xdd, 0x3c, 0x43, 0xfe, 0xdf, 0x94, + 0x2d, 0xa9, 0x89, 0x81, 0x51, 0xf8, 0x5f, 0xa7, + 0xa0, 0x13, 0xaa, 0xcc, 0xb0, 0x18, 0xe2, 0x57, + 0x3e, 0x0d, 0x29, 0x93, 0xe8, 0x95, 0xd5, 0x1b, + 0x53, 0xd2, 0x51, 0xf2, 0xbd, 0xf5, 0x9e, 0x7b, + 0x22, 0x65, 0x62, 0x5c, 0xc4, 0x4c, 0x1d, 0xe8, + 0xe9, 0xc3, 0xd4, 0x2b, 0xe7, 0x78, 0xcb, 0x10, + 0xf3, 0xfe, 0x06, 0x83, 0xdc, 0x3a, 0x1e, 0x62, + 0x10, 0xc0, 0x46, 0x77, 0xc6, 0x9d, 0x9f, 0xab, + 0x96, 0x25, 0x5c, 0xfb, 0x26, 0xc1, 0x15, 0x1f, + 0xa5, 0x33, 0xee, 0x4f, 0x9a, 0x14, 0x6a, 0x14, + 0x97, 0x93, 0x2b, 0x95, 0x0b, 0xdc, 0xa8, 0xd7, + 0x69, 0x2e, 0xf0, 0x01, 0x0e, 0xfd, 0x4e, 0xd0, + 0xd9, 0xa8, 0xe5, 0x65, 0xde, 0xfb, 0xca, 0xca, + 0x1c, 0x5f, 0xf9, 0x53, 0xa0, 0x87, 0xe7, 0x33, + 0x9b, 0x2f, 0xcf, 0xe4, 0x13, 0xfc, 0xec, 0x7a, + 0x6c, 0xb0, 0x90, 0x13, 0x9b, 0xb6, 0xc5, 0x03, + 0xf6, 0x0e, 0x5e, 0xe2, 0xe4, 0x26, 0xc1, 0x7e, + 0x53, 0xfe, 0x69, 0xa3, 0xc7, 0xd8, 0x8e, 0x6e, + 0x94, 0x32, 0xa0, 0xde, 0xca, 0xb6, 0xcc, 0xd6, + 0x01, 0xd5, 0x78, 0x40, 0x28, 0x63, 0x9b, 0xee, + 0xcf, 0x09, 0x3b, 0x35, 0x04, 0xf0, 0x14, 0x02, + 0xf6, 0x80, 0x0e, 0x90, 0xb2, 0x94, 0xd2, 0x25, + 0x16, 0xb8, 0x7a, 0x76, 0x87, 0x84, 0x9f, 0x84, + 0xc5, 0xaf, 0xc2, 0x6d, 0x68, 0x7a, 0x84, 0x9c, + 0xc6, 0x8a, 0x63, 0x60, 0x87, 0x6a, 0x25, 0xc1, + 0xa1, 0x78, 0x0f, 0xba, 0xe8, 0x5f, 0xe1, 0xba, + 0xac, 0xa4, 0x6f, 0xdd, 0x09, 0x3f, 0x12, 0xcb, + 0x1d, 0xf3, 0xcf, 0x48, 0xd7, 0xd3, 0x26, 0xe8, + 0x9c, 0xc3, 0x53, 0xb3, 0xba, 0xdc, 0x32, 0x99, + 0x98, 0x96, 0xd6, 0x16, 0x03, 0x01, 0x00, 0x99, + 0x0d, 0x00, 0x00, 0x91, 0x03, 0x01, 0x02, 0x40, + 0x00, 0x8b, 0x00, 0x89, 0x30, 0x81, 0x86, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, + 0x59, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, + 0x6b, 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, + 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, + 0x72, 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, + 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, + 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x0e, 0x00, 0x00, + 0x00, + }, + { + 0x16, 0x03, 0x01, 0x0a, 0xfb, 0x0b, 0x00, 0x0a, + 0xf7, 0x00, 0x0a, 0xf4, 0x00, 0x03, 0x7e, 0x30, + 0x82, 0x03, 0x7a, 0x30, 0x82, 0x02, 0x62, 0x02, + 0x09, 0x00, 0xb4, 0x47, 0x58, 0x57, 0x2b, 0x67, + 0xc8, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, + 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, 0x20, 0x43, + 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, 0x61, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, + 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, + 0x31, 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, + 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x34, + 0x34, 0x30, 0x30, 0x5a, 0x30, 0x7d, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x08, 0x4e, 0x65, + 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, + 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x79, 0x20, 0x4c, + 0x65, 0x61, 0x66, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x6d, 0x79, + 0x6c, 0x65, 0x61, 0x66, 0x2e, 0x63, 0x6f, 0x6d, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, + 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xa0, 0xa3, 0xef, 0xc1, + 0x44, 0x7d, 0xa2, 0xe3, 0x71, 0x98, 0x27, 0x63, + 0xb3, 0x1d, 0x71, 0x50, 0xa6, 0x34, 0x15, 0xcb, + 0xc9, 0x2a, 0xc3, 0xea, 0xe4, 0x9e, 0x9c, 0x49, + 0xa6, 0x01, 0x9b, 0x7e, 0xa9, 0xb5, 0x7a, 0xff, + 0x15, 0x92, 0x71, 0xc8, 0x97, 0x9c, 0x25, 0xb7, + 0x79, 0x2b, 0xff, 0xab, 0xc6, 0xb1, 0xa7, 0x00, + 0x90, 0xb2, 0x8b, 0xd7, 0x71, 0xd5, 0xc2, 0x3a, + 0xe6, 0x82, 0x42, 0x37, 0x89, 0x41, 0x04, 0xb0, + 0xba, 0xc7, 0x5b, 0x8a, 0x43, 0x9f, 0x97, 0x39, + 0x0c, 0x0f, 0xd5, 0x6d, 0x9e, 0x8d, 0xeb, 0xc0, + 0x26, 0xc5, 0x18, 0xe8, 0x7a, 0x3d, 0x32, 0x2e, + 0x38, 0x90, 0x40, 0x5b, 0x39, 0x2c, 0x07, 0xcb, + 0x24, 0x10, 0xc5, 0xc9, 0x3b, 0xe3, 0x66, 0x47, + 0x57, 0xb9, 0x6a, 0xad, 0x44, 0xf8, 0xd0, 0x70, + 0x62, 0x3b, 0x8e, 0xed, 0x60, 0x5f, 0x22, 0xf8, + 0xb8, 0x0c, 0xc9, 0x41, 0x2b, 0xc9, 0x80, 0x6e, + 0x4e, 0x1b, 0xe1, 0x20, 0xfc, 0x47, 0xa4, 0xac, + 0xc3, 0x3f, 0xe6, 0xc2, 0x81, 0x79, 0x03, 0x37, + 0x25, 0x89, 0xca, 0xd6, 0xa5, 0x46, 0x91, 0x63, + 0x41, 0xc5, 0x3e, 0xd5, 0xed, 0x7f, 0x4f, 0x8d, + 0x06, 0xc0, 0x89, 0x00, 0xbe, 0x37, 0x7b, 0x7e, + 0x73, 0xca, 0x70, 0x00, 0x14, 0x34, 0xbe, 0x47, + 0xbc, 0xb2, 0x6a, 0x28, 0xa5, 0x29, 0x84, 0xa8, + 0x9d, 0xc8, 0x1e, 0x77, 0x66, 0x1f, 0x9f, 0xaa, + 0x2b, 0x47, 0xdb, 0xdd, 0x6b, 0x9c, 0xa8, 0xfc, + 0x82, 0x36, 0x94, 0x62, 0x0d, 0x5c, 0x3f, 0xb2, + 0x01, 0xb4, 0xa5, 0xb8, 0xc6, 0x0e, 0x94, 0x5b, + 0xec, 0x5e, 0xbb, 0x7a, 0x63, 0x24, 0xf1, 0xf9, + 0xd6, 0x50, 0x08, 0xc1, 0xa3, 0xcc, 0x90, 0x07, + 0x5b, 0x04, 0x04, 0x42, 0x74, 0xcf, 0x37, 0xfa, + 0xf0, 0xa5, 0xd9, 0xd3, 0x86, 0x89, 0x89, 0x18, + 0xf3, 0x4c, 0xe2, 0x11, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x90, 0xbb, 0xf9, + 0x5e, 0xba, 0x17, 0x1f, 0xac, 0x21, 0x9f, 0x6b, + 0x4a, 0x46, 0xd0, 0x6d, 0x3c, 0x8f, 0x3d, 0xf8, + 0x5e, 0x3e, 0x72, 0xaf, 0xa0, 0x1a, 0xf3, 0xff, + 0x89, 0xac, 0x5b, 0x7a, 0xe2, 0x91, 0x2a, 0x23, + 0x85, 0xc6, 0x4d, 0x47, 0x67, 0x01, 0x08, 0xa8, + 0x05, 0x1d, 0x01, 0x60, 0x50, 0x5f, 0x59, 0xad, + 0xfe, 0x7b, 0xc6, 0x0c, 0x54, 0x90, 0x68, 0x70, + 0x67, 0x2e, 0xed, 0x87, 0xf8, 0x69, 0x8a, 0xac, + 0x32, 0xfe, 0x6f, 0x90, 0x19, 0x2a, 0x64, 0x8d, + 0x82, 0x66, 0x05, 0x43, 0x88, 0xee, 0xf2, 0x30, + 0xed, 0xa4, 0x8f, 0xbf, 0xd6, 0x57, 0x20, 0xd4, + 0x43, 0x1d, 0x52, 0x96, 0x6f, 0xae, 0x09, 0x96, + 0x01, 0x52, 0x38, 0xe3, 0xaf, 0x99, 0xd7, 0xdc, + 0x14, 0x99, 0xc4, 0x8b, 0x0e, 0x04, 0x0f, 0xb3, + 0x14, 0x14, 0xd4, 0xa5, 0x93, 0xe1, 0xc9, 0x8a, + 0x81, 0xef, 0x63, 0xfc, 0x36, 0x77, 0x05, 0x06, + 0xf0, 0x2a, 0x04, 0x0a, 0xbe, 0x2e, 0xce, 0x81, + 0x3d, 0x23, 0xa1, 0xda, 0xd8, 0xeb, 0xc6, 0xea, + 0x5e, 0xcf, 0x28, 0x36, 0x51, 0x31, 0x95, 0x5e, + 0x40, 0x04, 0xed, 0xac, 0xc1, 0xc8, 0x56, 0x69, + 0x87, 0xec, 0x3b, 0x03, 0x3e, 0x9d, 0x0f, 0x4c, + 0x4c, 0xeb, 0xd7, 0xba, 0x26, 0xdf, 0xe3, 0xde, + 0x10, 0xee, 0x93, 0x62, 0x8d, 0x73, 0x52, 0x6e, + 0xff, 0x37, 0x36, 0x98, 0x7b, 0x2d, 0x56, 0x4c, + 0xba, 0x09, 0xb8, 0xa7, 0xf0, 0x3b, 0x16, 0x81, + 0xca, 0xdb, 0x43, 0xab, 0xec, 0x4c, 0x6e, 0x7c, + 0xc1, 0x0b, 0x22, 0x22, 0x43, 0x1d, 0xb6, 0x0c, + 0xc1, 0xb9, 0xcf, 0xe4, 0x53, 0xee, 0x1d, 0x3e, + 0x88, 0xa7, 0x13, 0xbe, 0x7f, 0xbd, 0xae, 0x72, + 0xcf, 0xcd, 0x63, 0xd2, 0xc3, 0x18, 0x58, 0x92, + 0xa2, 0xad, 0xb5, 0x09, 0x9d, 0x91, 0x03, 0xdd, + 0x3c, 0xe2, 0x1c, 0xde, 0x78, 0x00, 0x03, 0x88, + 0x30, 0x82, 0x03, 0x84, 0x30, 0x82, 0x02, 0x6c, + 0x02, 0x09, 0x00, 0xab, 0xed, 0xa6, 0xe4, 0x4a, + 0x2b, 0x2b, 0xf8, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, + 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, + 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, + 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x31, + 0x38, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, + 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x31, 0x38, + 0x34, 0x30, 0x5a, 0x30, 0x81, 0x80, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, + 0x6c, 0x79, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, + 0x20, 0x43, 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, + 0x61, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, + 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, + 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xce, + 0x13, 0xf0, 0x72, 0xb0, 0x61, 0xc8, 0x18, 0x37, + 0x8a, 0x41, 0x3d, 0x20, 0xa1, 0x1c, 0xcb, 0xbf, + 0xf6, 0x3b, 0x74, 0x26, 0x2a, 0x96, 0x11, 0xec, + 0x53, 0xa1, 0xcc, 0x7d, 0x77, 0x56, 0x45, 0x0f, + 0x36, 0xb7, 0xf2, 0x48, 0x92, 0x1a, 0x62, 0xcc, + 0xb6, 0xc0, 0xa1, 0x2f, 0x44, 0x2b, 0xc1, 0x89, + 0xcb, 0x6e, 0x1e, 0xdb, 0x57, 0x92, 0xd5, 0x97, + 0x60, 0x8c, 0x41, 0x2c, 0xd9, 0x20, 0xfe, 0xe9, + 0x1f, 0x8e, 0xfc, 0x7f, 0x02, 0x44, 0x0f, 0x28, + 0x81, 0xd6, 0x0c, 0xcd, 0xbc, 0xf0, 0x57, 0x6c, + 0xcc, 0xa7, 0xba, 0x06, 0xa0, 0xa6, 0x91, 0xda, + 0xef, 0x46, 0x8a, 0x60, 0x0f, 0x52, 0x6c, 0x90, + 0x6c, 0x8c, 0x44, 0xaf, 0xb0, 0x9d, 0x90, 0xba, + 0x21, 0x58, 0xa0, 0x3c, 0xee, 0x54, 0xb5, 0x29, + 0x26, 0x1f, 0x0a, 0xac, 0xef, 0x48, 0x68, 0x33, + 0xd0, 0x33, 0xd0, 0x8b, 0x1a, 0xec, 0x6e, 0x2f, + 0xb5, 0x4a, 0x53, 0xc2, 0x1a, 0xd2, 0xf1, 0x50, + 0x05, 0x59, 0x5c, 0xd9, 0xda, 0x03, 0x0a, 0x47, + 0xb7, 0xdd, 0xf7, 0x3a, 0x69, 0xf5, 0x4e, 0xea, + 0x4a, 0xc2, 0xca, 0x54, 0xb0, 0x8b, 0x76, 0xe1, + 0x02, 0x2d, 0x52, 0x67, 0xb9, 0xdd, 0x50, 0xc9, + 0x3b, 0x07, 0x24, 0x22, 0x6a, 0x00, 0x1d, 0x58, + 0x83, 0xa8, 0xec, 0x95, 0xf1, 0xda, 0xe2, 0x73, + 0xa0, 0xa1, 0x72, 0x60, 0x9e, 0x86, 0x53, 0xcb, + 0x45, 0xa8, 0xc2, 0xa0, 0x50, 0xa0, 0x53, 0xd6, + 0xfc, 0x18, 0x84, 0xb5, 0x4a, 0x26, 0xd0, 0xa2, + 0xaa, 0xd0, 0xff, 0xb6, 0xfe, 0x3a, 0x9c, 0xb5, + 0x19, 0x3b, 0x3f, 0xe1, 0x48, 0x0d, 0xa4, 0x09, + 0x4f, 0x83, 0xc9, 0xc0, 0xc9, 0xa6, 0x0b, 0x58, + 0x1f, 0x1c, 0x7b, 0xac, 0xa2, 0x42, 0xbc, 0x61, + 0xf4, 0x21, 0x8a, 0x00, 0xda, 0x14, 0xa0, 0x60, + 0x03, 0xfe, 0x93, 0x12, 0x6c, 0x56, 0xcd, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x25, 0x29, 0x3b, 0x1e, 0xc3, 0x58, 0x32, 0xe6, + 0x23, 0xc8, 0xee, 0x18, 0xf0, 0x1d, 0x62, 0x6d, + 0x3b, 0x59, 0x99, 0x3a, 0xfe, 0x49, 0x72, 0x07, + 0x3f, 0x58, 0x93, 0xdb, 0xc0, 0xaf, 0xb0, 0xb3, + 0x5c, 0xd1, 0x5c, 0x98, 0xc8, 0xea, 0x4a, 0xe4, + 0x58, 0x73, 0x0d, 0x57, 0xc5, 0x13, 0x7c, 0x5c, + 0x79, 0x66, 0xda, 0x04, 0x1d, 0xe5, 0x98, 0xda, + 0x35, 0x47, 0x44, 0xb0, 0xd2, 0x7a, 0x66, 0x9d, + 0xcd, 0x41, 0xa5, 0x8f, 0xa1, 0x11, 0xb2, 0x1a, + 0x87, 0xc0, 0xcd, 0x55, 0xed, 0xb4, 0x7b, 0x33, + 0x72, 0xeb, 0xf7, 0xe3, 0x7b, 0x8b, 0x02, 0x86, + 0xe9, 0x2b, 0x26, 0x32, 0x9f, 0x99, 0xf1, 0xcb, + 0x93, 0xab, 0xb9, 0x16, 0xb3, 0x9a, 0xb2, 0x22, + 0x13, 0x21, 0x1f, 0x5b, 0xcc, 0xa2, 0x59, 0xbb, + 0x69, 0xf2, 0xb8, 0x07, 0x80, 0xce, 0x0c, 0xf7, + 0x98, 0x4c, 0x85, 0xc2, 0x96, 0x6a, 0x22, 0x05, + 0xe9, 0xbe, 0x48, 0xb0, 0x02, 0x5b, 0x69, 0x28, + 0x18, 0x88, 0x96, 0xe3, 0xd7, 0xc6, 0x7a, 0xd3, + 0xe9, 0x99, 0xff, 0x9d, 0xc3, 0x61, 0x4d, 0x9a, + 0x96, 0xf2, 0xc6, 0x33, 0x4d, 0xe5, 0x5d, 0x5a, + 0x68, 0x64, 0x5a, 0x82, 0x35, 0x65, 0x25, 0xe3, + 0x8c, 0x5b, 0xb0, 0xf6, 0x96, 0x56, 0xbc, 0xbf, + 0x97, 0x76, 0x4b, 0x66, 0x44, 0x81, 0xa4, 0xc4, + 0xa7, 0x31, 0xc5, 0xa1, 0x4f, 0xe8, 0xa4, 0xca, + 0x20, 0xf5, 0x01, 0x5b, 0x99, 0x4f, 0x5a, 0xf4, + 0xf0, 0x78, 0xbf, 0x71, 0x49, 0xd5, 0xf1, 0xc1, + 0xa2, 0x18, 0xfd, 0x72, 0x5b, 0x16, 0xe8, 0x92, + 0xc7, 0x37, 0x48, 0xaf, 0xee, 0x24, 0xfc, 0x35, + 0x0b, 0xc2, 0xdd, 0x05, 0xc7, 0x6e, 0xa3, 0x29, + 0xbb, 0x29, 0x7d, 0xd3, 0x2b, 0x94, 0x80, 0xc3, + 0x40, 0x53, 0x0e, 0x03, 0x54, 0x3d, 0x7b, 0x8b, + 0xce, 0xf9, 0xa4, 0x03, 0x27, 0x63, 0xec, 0x51, + 0x00, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, + 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x09, 0x00, 0xcc, 0x22, 0x4c, 0x4b, 0x98, + 0xa2, 0x88, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, + 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, + 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, + 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x30, + 0x35, 0x30, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x33, + 0x30, 0x35, 0x32, 0x34, 0x32, 0x31, 0x30, 0x35, + 0x30, 0x31, 0x5a, 0x30, 0x81, 0x86, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, + 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, + 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, + 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, + 0x02, 0x82, 0x01, 0x01, 0x00, 0xf0, 0xfb, 0xad, + 0x80, 0x5e, 0x37, 0xd3, 0x6d, 0xee, 0x2e, 0xcc, + 0xbc, 0x0c, 0xd7, 0x56, 0x4b, 0x56, 0x45, 0xcd, + 0x28, 0xb6, 0x22, 0xe9, 0xe2, 0x0f, 0xd1, 0x87, + 0x2a, 0x27, 0xce, 0x77, 0x8d, 0x6e, 0x0e, 0x0f, + 0xfb, 0x66, 0xe1, 0xb5, 0x0e, 0x9a, 0xb6, 0x05, + 0x8e, 0xb3, 0xe1, 0xc5, 0x77, 0x86, 0x5b, 0x46, + 0xd2, 0x0b, 0x92, 0x03, 0x1b, 0x89, 0x0c, 0x1b, + 0x10, 0x0e, 0x99, 0x8f, 0xe2, 0x17, 0xe8, 0xc2, + 0x30, 0x00, 0x47, 0xd6, 0xfc, 0xf9, 0x0f, 0x3b, + 0x75, 0x34, 0x8d, 0x4d, 0xb0, 0x99, 0xb7, 0xa0, + 0x6d, 0xa0, 0xb6, 0xad, 0xda, 0x07, 0x5e, 0x38, + 0x2e, 0x02, 0xe4, 0x30, 0x6d, 0xae, 0x13, 0x72, + 0xd4, 0xc8, 0xce, 0x14, 0x07, 0xae, 0x23, 0x8c, + 0x8f, 0x9e, 0x8c, 0x60, 0xd6, 0x06, 0xb9, 0xef, + 0x00, 0x18, 0xc0, 0x1d, 0x25, 0x1e, 0xda, 0x3e, + 0x2f, 0xcf, 0x2b, 0x56, 0x84, 0x9e, 0x30, 0x21, + 0xc7, 0x29, 0xf6, 0x03, 0x8a, 0x24, 0xf9, 0x34, + 0xac, 0x65, 0x9d, 0x80, 0x36, 0xc8, 0x3b, 0x15, + 0x10, 0xbd, 0x51, 0xe9, 0xbc, 0x02, 0xe1, 0xe9, + 0xb3, 0x5a, 0x9a, 0x99, 0x41, 0x1b, 0x27, 0xa0, + 0x4d, 0x50, 0x9e, 0x27, 0x7f, 0xa1, 0x7d, 0x09, + 0x87, 0xbd, 0x8a, 0xca, 0x5f, 0xb1, 0xa5, 0x08, + 0xb8, 0x04, 0xd4, 0x52, 0x89, 0xaa, 0xe0, 0x7d, + 0x42, 0x2e, 0x2f, 0x15, 0xee, 0x66, 0x57, 0x0f, + 0x13, 0x19, 0x45, 0xa8, 0x4b, 0x5d, 0x81, 0x66, + 0xcc, 0x12, 0x37, 0x94, 0x5e, 0xfd, 0x3c, 0x10, + 0x81, 0x51, 0x3f, 0xfa, 0x0f, 0xdd, 0xa1, 0x89, + 0x03, 0xa9, 0x78, 0x91, 0xf5, 0x3b, 0xf3, 0xbc, + 0xac, 0xbe, 0x93, 0x30, 0x2e, 0xbe, 0xca, 0x7f, + 0x46, 0xd3, 0x28, 0xb4, 0x4e, 0x91, 0x7b, 0x5b, + 0x43, 0x6c, 0xaf, 0x9b, 0x5c, 0x6a, 0x6d, 0x5a, + 0xdb, 0x79, 0x5e, 0x6a, 0x6b, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, 0x7d, + 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, 0x90, + 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, + 0x7d, 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, + 0x90, 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x0c, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, + 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0xcd, 0x6f, 0x73, 0x4d, 0x56, 0x0b, 0xf3, 0x2e, + 0x1c, 0xe2, 0x02, 0x0c, 0x14, 0xbb, 0x2f, 0xdd, + 0x3c, 0x43, 0xfe, 0xdf, 0x94, 0x2d, 0xa9, 0x89, + 0x81, 0x51, 0xf8, 0x5f, 0xa7, 0xa0, 0x13, 0xaa, + 0xcc, 0xb0, 0x18, 0xe2, 0x57, 0x3e, 0x0d, 0x29, + 0x93, 0xe8, 0x95, 0xd5, 0x1b, 0x53, 0xd2, 0x51, + 0xf2, 0xbd, 0xf5, 0x9e, 0x7b, 0x22, 0x65, 0x62, + 0x5c, 0xc4, 0x4c, 0x1d, 0xe8, 0xe9, 0xc3, 0xd4, + 0x2b, 0xe7, 0x78, 0xcb, 0x10, 0xf3, 0xfe, 0x06, + 0x83, 0xdc, 0x3a, 0x1e, 0x62, 0x10, 0xc0, 0x46, + 0x77, 0xc6, 0x9d, 0x9f, 0xab, 0x96, 0x25, 0x5c, + 0xfb, 0x26, 0xc1, 0x15, 0x1f, 0xa5, 0x33, 0xee, + 0x4f, 0x9a, 0x14, 0x6a, 0x14, 0x97, 0x93, 0x2b, + 0x95, 0x0b, 0xdc, 0xa8, 0xd7, 0x69, 0x2e, 0xf0, + 0x01, 0x0e, 0xfd, 0x4e, 0xd0, 0xd9, 0xa8, 0xe5, + 0x65, 0xde, 0xfb, 0xca, 0xca, 0x1c, 0x5f, 0xf9, + 0x53, 0xa0, 0x87, 0xe7, 0x33, 0x9b, 0x2f, 0xcf, + 0xe4, 0x13, 0xfc, 0xec, 0x7a, 0x6c, 0xb0, 0x90, + 0x13, 0x9b, 0xb6, 0xc5, 0x03, 0xf6, 0x0e, 0x5e, + 0xe2, 0xe4, 0x26, 0xc1, 0x7e, 0x53, 0xfe, 0x69, + 0xa3, 0xc7, 0xd8, 0x8e, 0x6e, 0x94, 0x32, 0xa0, + 0xde, 0xca, 0xb6, 0xcc, 0xd6, 0x01, 0xd5, 0x78, + 0x40, 0x28, 0x63, 0x9b, 0xee, 0xcf, 0x09, 0x3b, + 0x35, 0x04, 0xf0, 0x14, 0x02, 0xf6, 0x80, 0x0e, + 0x90, 0xb2, 0x94, 0xd2, 0x25, 0x16, 0xb8, 0x7a, + 0x76, 0x87, 0x84, 0x9f, 0x84, 0xc5, 0xaf, 0xc2, + 0x6d, 0x68, 0x7a, 0x84, 0x9c, 0xc6, 0x8a, 0x63, + 0x60, 0x87, 0x6a, 0x25, 0xc1, 0xa1, 0x78, 0x0f, + 0xba, 0xe8, 0x5f, 0xe1, 0xba, 0xac, 0xa4, 0x6f, + 0xdd, 0x09, 0x3f, 0x12, 0xcb, 0x1d, 0xf3, 0xcf, + 0x48, 0xd7, 0xd3, 0x26, 0xe8, 0x9c, 0xc3, 0x53, + 0xb3, 0xba, 0xdc, 0x32, 0x99, 0x98, 0x96, 0xd6, + 0x16, 0x03, 0x01, 0x01, 0x06, 0x10, 0x00, 0x01, + 0x02, 0x01, 0x00, 0x6e, 0xea, 0x15, 0x6f, 0x21, + 0xbd, 0x2d, 0x14, 0xde, 0x9d, 0x02, 0xeb, 0xdf, + 0x3b, 0x09, 0x75, 0xaf, 0x32, 0x80, 0x0c, 0xe2, + 0xc2, 0x7b, 0x0d, 0xca, 0x24, 0x96, 0xf6, 0x3e, + 0xa5, 0x97, 0xba, 0x0c, 0x50, 0x7e, 0xb3, 0x68, + 0x58, 0xc6, 0xd8, 0xec, 0xab, 0xa9, 0xd9, 0x3a, + 0xb1, 0x49, 0xea, 0x2f, 0xd7, 0xdb, 0x15, 0x1b, + 0xb5, 0xaf, 0xec, 0xcc, 0x40, 0x5c, 0xe6, 0x0f, + 0xc4, 0x33, 0x71, 0xe7, 0x41, 0xc0, 0x04, 0x89, + 0x60, 0x3e, 0xb7, 0xe6, 0xda, 0x38, 0x62, 0x27, + 0x6a, 0xd9, 0xfb, 0x93, 0x94, 0x9d, 0xc1, 0x63, + 0x92, 0x5c, 0x88, 0x19, 0x38, 0x81, 0x79, 0x9d, + 0x59, 0x48, 0x5e, 0xd3, 0xc8, 0xea, 0xcb, 0x6e, + 0x66, 0x66, 0x03, 0xdc, 0x0c, 0x2d, 0x95, 0xb1, + 0x4d, 0x68, 0xc7, 0xc5, 0x6e, 0xfa, 0x94, 0x14, + 0xdf, 0x2c, 0x70, 0x69, 0x04, 0xf4, 0x69, 0xf1, + 0xf0, 0x07, 0xbd, 0x23, 0x53, 0x63, 0xb3, 0x41, + 0xec, 0xa7, 0x10, 0xa5, 0x04, 0x84, 0x24, 0xb5, + 0xf5, 0x0c, 0x0f, 0x5d, 0x02, 0x47, 0x79, 0x60, + 0x76, 0xbb, 0xdf, 0x60, 0xa6, 0xd7, 0x4d, 0x08, + 0x7d, 0xa6, 0x85, 0x4f, 0x61, 0xac, 0x96, 0x3d, + 0xbc, 0xaf, 0x07, 0xb0, 0x7c, 0xb6, 0x23, 0x3e, + 0x1f, 0x0a, 0x62, 0x77, 0x97, 0x77, 0xae, 0x33, + 0x55, 0x0f, 0x85, 0xdf, 0xdc, 0xbe, 0xc6, 0xe0, + 0xe0, 0x14, 0x83, 0x4c, 0x50, 0xf0, 0xe5, 0x2d, + 0xdc, 0x0b, 0x74, 0x7f, 0xc3, 0x28, 0x98, 0x16, + 0xda, 0x74, 0xe6, 0x40, 0xc2, 0xf0, 0xea, 0xc0, + 0x00, 0xd5, 0xfc, 0x16, 0xe4, 0x43, 0xa1, 0xfc, + 0x31, 0x19, 0x81, 0x62, 0xec, 0x2b, 0xfe, 0xcc, + 0xe8, 0x19, 0xed, 0xa1, 0x1e, 0x6a, 0x49, 0x73, + 0xde, 0xc4, 0xe9, 0x22, 0x0a, 0x21, 0xde, 0x45, + 0x1e, 0x55, 0x12, 0xd9, 0x44, 0xef, 0x4e, 0xaa, + 0x5e, 0x26, 0x57, 0x16, 0x03, 0x01, 0x01, 0x06, + 0x0f, 0x00, 0x01, 0x02, 0x01, 0x00, 0x23, 0xde, + 0xb0, 0x39, 0x60, 0xe9, 0x82, 0xb8, 0xed, 0x17, + 0x78, 0xd2, 0x37, 0x0e, 0x85, 0x69, 0xda, 0xcc, + 0x9f, 0x54, 0x4d, 0xda, 0xce, 0xe8, 0x5a, 0xeb, + 0x3c, 0x61, 0x4c, 0x7a, 0x84, 0x1f, 0x21, 0x03, + 0xb3, 0x8a, 0x74, 0x3b, 0x6a, 0x9e, 0x4f, 0x44, + 0xd9, 0x75, 0x0a, 0xd8, 0x7e, 0x56, 0xa3, 0xef, + 0x5a, 0xfe, 0x8a, 0x35, 0xce, 0x29, 0x18, 0xfe, + 0xa6, 0x61, 0x8e, 0x8f, 0x00, 0x90, 0x2d, 0x85, + 0xe3, 0x6c, 0x0e, 0x8d, 0x8c, 0x27, 0x80, 0x8c, + 0x9f, 0x51, 0xe9, 0xd3, 0xe6, 0x7d, 0x70, 0xe9, + 0xfb, 0xcb, 0xb8, 0x24, 0x94, 0x30, 0x9b, 0xba, + 0x01, 0x14, 0x49, 0x9f, 0xaf, 0x09, 0xd8, 0x26, + 0x1b, 0x23, 0xa4, 0xb8, 0xd9, 0x44, 0x0a, 0xdc, + 0x4e, 0x27, 0xe7, 0x32, 0xf5, 0x9c, 0xf3, 0x8d, + 0xa0, 0xc5, 0xc4, 0xbe, 0x92, 0x02, 0x85, 0x4f, + 0x33, 0x8f, 0xa7, 0xf7, 0x87, 0xa9, 0x44, 0xf3, + 0x64, 0xbd, 0x32, 0x04, 0xeb, 0xc5, 0xc3, 0x62, + 0xe9, 0xda, 0x2f, 0x95, 0x5c, 0xf7, 0x58, 0x3e, + 0xad, 0x35, 0xd7, 0x7e, 0xad, 0xdd, 0x32, 0x8d, + 0xce, 0x81, 0x08, 0xad, 0x49, 0xf7, 0xdb, 0xf7, + 0xaf, 0xe3, 0xc6, 0xb2, 0xdd, 0x76, 0x0c, 0xcf, + 0x0f, 0x87, 0x79, 0x90, 0x10, 0x79, 0xc6, 0xc8, + 0x7b, 0xe6, 0x23, 0xf2, 0xda, 0x33, 0xca, 0xe1, + 0xf0, 0x59, 0x42, 0x43, 0x03, 0x56, 0x19, 0xe3, + 0x8b, 0xe6, 0xa8, 0x70, 0xbc, 0x80, 0xfa, 0x24, + 0xae, 0x03, 0x13, 0x30, 0x0d, 0x1f, 0xab, 0xb7, + 0x82, 0xd9, 0x24, 0x90, 0x80, 0xbf, 0x75, 0xe1, + 0x0d, 0x1c, 0xb2, 0xfe, 0x92, 0x2c, 0x4d, 0x21, + 0xe9, 0x5d, 0xa1, 0x68, 0xf3, 0x16, 0xd8, 0x3f, + 0xb2, 0xc3, 0x00, 0x3e, 0xd8, 0x42, 0x25, 0x5c, + 0x90, 0x11, 0xc0, 0x1b, 0xd4, 0x26, 0x5c, 0x37, + 0x47, 0xbd, 0xf8, 0x1e, 0x34, 0xa9, 0x14, 0x03, + 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, + 0x24, 0x8f, 0x94, 0x7e, 0x01, 0xee, 0xd5, 0x4f, + 0x83, 0x41, 0x31, 0xc0, 0x36, 0x81, 0x46, 0xc3, + 0xc0, 0xcc, 0x9c, 0xea, 0x0f, 0x29, 0x04, 0x10, + 0x43, 0x1e, 0x08, 0x6e, 0x08, 0xce, 0xb2, 0x62, + 0xa6, 0x0f, 0x68, 0x9f, 0x99, + }, + { + 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x01, 0x00, 0x24, 0xd9, 0x46, 0x5b, 0xbf, 0xfd, + 0x8a, 0xa1, 0x08, 0xd5, 0xf3, 0x0c, 0x1c, 0xd8, + 0xa8, 0xb3, 0xe5, 0x89, 0x83, 0x9e, 0x23, 0x47, + 0x81, 0x66, 0x77, 0x11, 0x98, 0xe5, 0xf4, 0xac, + 0x06, 0xe9, 0x4c, 0x05, 0x8b, 0xc4, 0x16, + }, + { + 0x17, 0x03, 0x01, 0x00, 0x1a, 0xc5, 0x28, 0xfd, + 0x71, 0xc0, 0xe6, 0x89, 0xb8, 0x82, 0x92, 0x1b, + 0xdd, 0x39, 0xe5, 0xbf, 0x41, 0x82, 0x1f, 0xc1, + 0xbc, 0x85, 0xe5, 0x32, 0x1b, 0x93, 0x46, 0x15, + 0x03, 0x01, 0x00, 0x16, 0x1a, 0x8b, 0x10, 0x42, + 0x12, 0xb2, 0xbd, 0xd3, 0xf1, 0x74, 0x1f, 0xc2, + 0x10, 0x08, 0xc2, 0x79, 0x99, 0x2c, 0x55, 0xef, + 0x4a, 0xbd, + }, +} + +// $ openssl s_server -tls1_2 -cert server.crt -key server.key \ +// -cipher ECDHE-RSA-AES128-SHA -port 10443 +// $ go test -test.run "TestRunClient" -connect -ciphersuites=0xc013 \ +// -minversion=0x0303 -maxversion=0x0303 +var clientTLS12Script = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, + 0x54, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x13, + 0x01, 0x00, 0x00, 0x29, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x08, 0x04, 0x01, 0x04, + 0x03, 0x02, 0x01, 0x02, 0x03, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x50, 0x03, 0x03, 0x52, 0x65, 0x67, 0xbd, 0xe8, + 0x72, 0x03, 0x6a, 0x52, 0x8d, 0x28, 0x2c, 0x9a, + 0x53, 0xff, 0xc2, 0xa1, 0x62, 0x5f, 0x54, 0xfb, + 0x73, 0x00, 0xcf, 0x4d, 0x28, 0x36, 0xc2, 0xee, + 0xfd, 0x78, 0xf0, 0x20, 0x6f, 0xbe, 0x49, 0xec, + 0x5b, 0x6f, 0xf9, 0x53, 0x42, 0x69, 0x0d, 0x6d, + 0x8b, 0x68, 0x2e, 0xca, 0x3c, 0x3c, 0x88, 0x9e, + 0x8b, 0xf9, 0x32, 0x65, 0x09, 0xd6, 0xa0, 0x7d, + 0xea, 0xc6, 0xd5, 0xc4, 0xc0, 0x13, 0x00, 0x00, + 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, + 0x02, 0x16, 0x03, 0x03, 0x02, 0x39, 0x0b, 0x00, + 0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, + 0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, + 0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, + 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, + 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, + 0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, + 0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, + 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, + 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, + 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, + 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, + 0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, + 0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, + 0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, + 0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, + 0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, + 0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, + 0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, + 0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, + 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, + 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, + 0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, + 0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, + 0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, + 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, + 0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, + 0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, + 0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, + 0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, + 0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, + 0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, + 0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, + 0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, + 0x03, 0x03, 0x00, 0x8d, 0x0c, 0x00, 0x00, 0x89, + 0x03, 0x00, 0x17, 0x41, 0x04, 0x48, 0x93, 0x62, + 0x6a, 0xf8, 0x7c, 0x94, 0xcc, 0xcc, 0x0a, 0x9b, + 0x5e, 0x11, 0xad, 0x0b, 0x30, 0xc4, 0x5d, 0xf7, + 0x63, 0x24, 0xc1, 0xb0, 0x40, 0x5f, 0xff, 0x9f, + 0x0d, 0x7e, 0xd5, 0xa5, 0xd0, 0x4f, 0x80, 0x16, + 0xa8, 0x66, 0x18, 0x31, 0x1f, 0x81, 0xb2, 0x9a, + 0x41, 0x62, 0x5b, 0xcf, 0x73, 0xac, 0x4a, 0x64, + 0xb5, 0xc1, 0x46, 0x4d, 0x8a, 0xac, 0x25, 0xba, + 0x81, 0x7f, 0xbe, 0x64, 0x68, 0x04, 0x01, 0x00, + 0x40, 0x4e, 0x3f, 0x1e, 0x04, 0x4c, 0xef, 0xd2, + 0xa6, 0x82, 0xe6, 0x7c, 0x76, 0x23, 0x17, 0xb9, + 0xe7, 0x52, 0x15, 0x6b, 0x3d, 0xb2, 0xb1, 0x17, + 0x7d, 0xe6, 0xde, 0x06, 0x87, 0x30, 0xb0, 0xb5, + 0x57, 0xae, 0xdf, 0xb2, 0xdc, 0x8d, 0xab, 0x76, + 0x9c, 0xaa, 0x45, 0x6d, 0x23, 0x5d, 0xc1, 0xa8, + 0x7b, 0x79, 0x79, 0xb1, 0x3c, 0xdc, 0xf5, 0x33, + 0x2c, 0xa1, 0x62, 0x3e, 0xbd, 0xf5, 0x5d, 0x6c, + 0x87, 0x16, 0x03, 0x03, 0x00, 0x04, 0x0e, 0x00, + 0x00, 0x00, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x46, 0x10, 0x00, 0x00, + 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, + 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, + 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, + 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, + 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, + 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, + 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, + 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, + 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x03, 0x00, 0x01, + 0x01, 0x16, 0x03, 0x03, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x17, + 0x54, 0x51, 0xb6, 0x1d, 0x8e, 0xe4, 0x6b, 0xed, + 0x5b, 0xa1, 0x27, 0x7f, 0xdc, 0xa9, 0xa5, 0xcf, + 0x38, 0xe6, 0x5d, 0x17, 0x34, 0xf9, 0xc0, 0x07, + 0xb8, 0xbe, 0x56, 0xe6, 0xd6, 0x6a, 0xb6, 0x26, + 0x4e, 0x45, 0x8d, 0x48, 0xe9, 0xc6, 0xb1, 0xa1, + 0xea, 0xdc, 0xb1, 0x37, 0xd9, 0xf6, + }, + { + 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x03, 0x00, 0x40, 0x00, 0x68, 0xc5, 0x27, 0xd5, + 0x3d, 0xba, 0x04, 0xde, 0x63, 0xf1, 0x5b, 0xc3, + 0x86, 0xb9, 0x82, 0xc7, 0xb3, 0x90, 0x31, 0xea, + 0x15, 0xe1, 0x42, 0x76, 0x7d, 0x90, 0xcb, 0xc9, + 0xd1, 0x05, 0xe6, 0x8c, 0x76, 0xc7, 0x9a, 0x35, + 0x67, 0xa2, 0x70, 0x9a, 0x8a, 0x6c, 0xb5, 0x6b, + 0xc7, 0x87, 0xf3, 0x65, 0x0a, 0xa0, 0x98, 0xba, + 0x57, 0xbb, 0x31, 0x7b, 0x1f, 0x1a, 0xf7, 0x2a, + 0xf3, 0x12, 0xf6, + }, + { + 0x17, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x80, + 0x54, 0x1e, 0x72, 0xd3, 0x1a, 0x86, 0x1c, 0xc4, + 0x4a, 0x9b, 0xd4, 0x80, 0xd2, 0x03, 0x35, 0x0d, + 0xe4, 0x12, 0xc2, 0x3d, 0x79, 0x4a, 0x2c, 0xba, + 0xc2, 0xad, 0xf3, 0xd2, 0x16, 0x15, 0x03, 0x03, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x9b, 0x68, 0x78, 0x92, 0x28, + 0x62, 0x02, 0x65, 0x87, 0x90, 0xe4, 0x32, 0xd7, + 0x72, 0x08, 0x70, 0xb8, 0x52, 0x32, 0x1f, 0x97, + 0xd4, 0x6a, 0xc6, 0x28, 0x83, 0xb0, 0x1d, 0x6e, + 0x16, 0xd5, + }, +} + +// $ openssl s_server -tls1_2 -cert server.crt -key server.key \ +// -port 10443 -verify 0 +// $ go test -test.run "TestRunClient" -connect -ciphersuites=0xc02f \ +// -maxversion=0x0303 +var clientTLS12ClientCertScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, + 0x54, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x2f, + 0x01, 0x00, 0x00, 0x29, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, + 0x0d, 0x00, 0x0a, 0x00, 0x08, 0x04, 0x01, 0x04, + 0x03, 0x02, 0x01, 0x02, 0x03, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x50, 0x03, 0x03, 0x52, 0x65, 0x67, 0xe0, 0xe8, + 0xf1, 0x13, 0x2a, 0x83, 0x28, 0xa8, 0x2e, 0x76, + 0x69, 0xe6, 0x89, 0x55, 0x6c, 0x48, 0x49, 0x2e, + 0x00, 0xf6, 0x87, 0x6c, 0x13, 0xa1, 0xd4, 0xaa, + 0xd0, 0x76, 0x3b, 0x20, 0xe4, 0xd6, 0x5b, 0x1d, + 0x11, 0xf2, 0x42, 0xf2, 0x82, 0x0c, 0x0d, 0x66, + 0x6d, 0xec, 0x52, 0xf8, 0x4a, 0xd9, 0x45, 0xcf, + 0xe4, 0x4a, 0xba, 0x8b, 0xf1, 0xab, 0x55, 0xe4, + 0x57, 0x18, 0xa9, 0x36, 0xc0, 0x2f, 0x00, 0x00, + 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, + 0x02, 0x16, 0x03, 0x03, 0x02, 0x39, 0x0b, 0x00, + 0x02, 0x35, 0x00, 0x02, 0x32, 0x00, 0x02, 0x2f, + 0x30, 0x82, 0x02, 0x2b, 0x30, 0x82, 0x01, 0xd5, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, + 0xb1, 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, + 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, + 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x32, 0x30, 0x34, 0x30, 0x36, + 0x31, 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x17, + 0x0d, 0x31, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, + 0x37, 0x31, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x45, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, + 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, + 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x5c, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, + 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9f, 0xb3, + 0xc3, 0x84, 0x27, 0x95, 0xff, 0x12, 0x31, 0x52, + 0x0f, 0x15, 0xef, 0x46, 0x11, 0xc4, 0xad, 0x80, + 0xe6, 0x36, 0x5b, 0x0f, 0xdd, 0x80, 0xd7, 0x61, + 0x8d, 0xe0, 0xfc, 0x72, 0x45, 0x09, 0x34, 0xfe, + 0x55, 0x66, 0x45, 0x43, 0x4c, 0x68, 0x97, 0x6a, + 0xfe, 0xa8, 0xa0, 0xa5, 0xdf, 0x5f, 0x78, 0xff, + 0xee, 0xd7, 0x64, 0xb8, 0x3f, 0x04, 0xcb, 0x6f, + 0xff, 0x2a, 0xfe, 0xfe, 0xb9, 0xed, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x78, 0xa6, 0x97, 0x9a, + 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, 0x22, + 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, 0x2b, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0x78, 0xa6, 0x97, + 0x9a, 0x63, 0xb5, 0xc5, 0xa1, 0xa5, 0x33, 0xba, + 0x22, 0x7c, 0x23, 0x6e, 0x5b, 0x1b, 0x7a, 0xcc, + 0x2b, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb1, + 0x35, 0x13, 0x65, 0x11, 0x20, 0xc5, 0x92, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x85, + 0x36, 0x40, 0x73, 0xc1, 0xbb, 0x1a, 0xda, 0xd4, + 0x59, 0x9f, 0x2d, 0xa2, 0x70, 0x31, 0x46, 0x74, + 0xec, 0x83, 0x6e, 0xa8, 0xc8, 0x3c, 0x51, 0xaf, + 0x39, 0xac, 0xec, 0x40, 0xbc, 0xe8, 0x22, 0x46, + 0x1d, 0x99, 0xd6, 0x46, 0x2a, 0x24, 0xd4, 0x8b, + 0x05, 0x08, 0x4b, 0xfb, 0x35, 0x11, 0x6e, 0x92, + 0xbb, 0x77, 0xba, 0xe4, 0x12, 0xbb, 0xf4, 0xc8, + 0x5e, 0x9c, 0x81, 0xa8, 0x97, 0x60, 0x4c, 0x16, + 0x03, 0x03, 0x00, 0x8d, 0x0c, 0x00, 0x00, 0x89, + 0x03, 0x00, 0x17, 0x41, 0x04, 0xaa, 0xf0, 0x0c, + 0xa3, 0x60, 0xcf, 0x69, 0x1e, 0xad, 0x16, 0x9a, + 0x01, 0x40, 0xc6, 0x22, 0xc4, 0xbb, 0x06, 0x3b, + 0x84, 0x65, 0xea, 0xc7, 0xa2, 0x96, 0x79, 0x17, + 0x2f, 0xc7, 0xbe, 0x56, 0x39, 0xe4, 0x79, 0xf3, + 0xad, 0x17, 0xf3, 0x7e, 0xe2, 0x7b, 0xa2, 0x6f, + 0x3f, 0x96, 0xea, 0xe5, 0x0e, 0xea, 0x39, 0x79, + 0x77, 0xeb, 0x14, 0x18, 0xbb, 0x7c, 0x95, 0xda, + 0xa7, 0x51, 0x09, 0xba, 0xd7, 0x04, 0x01, 0x00, + 0x40, 0x82, 0x3e, 0xce, 0xee, 0x7e, 0xba, 0x3b, + 0x51, 0xb1, 0xba, 0x71, 0x2e, 0x54, 0xa9, 0xb9, + 0xe2, 0xb1, 0x59, 0x17, 0xa1, 0xac, 0x76, 0xb4, + 0x4e, 0xf1, 0xae, 0x65, 0x17, 0x2b, 0x43, 0x06, + 0x31, 0x29, 0x0b, 0xa0, 0x1e, 0xb6, 0xfa, 0x35, + 0xe8, 0x63, 0x06, 0xde, 0x13, 0x89, 0x83, 0x69, + 0x3b, 0xc2, 0x15, 0x73, 0x1c, 0xc5, 0x07, 0xe9, + 0x38, 0x9b, 0x06, 0x81, 0x1b, 0x97, 0x7c, 0xa6, + 0x89, 0x16, 0x03, 0x03, 0x00, 0x30, 0x0d, 0x00, + 0x00, 0x28, 0x03, 0x01, 0x02, 0x40, 0x00, 0x20, + 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, + 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, + 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x03, 0x0a, 0xfb, 0x0b, 0x00, 0x0a, + 0xf7, 0x00, 0x0a, 0xf4, 0x00, 0x03, 0x7e, 0x30, + 0x82, 0x03, 0x7a, 0x30, 0x82, 0x02, 0x62, 0x02, + 0x09, 0x00, 0xb4, 0x47, 0x58, 0x57, 0x2b, 0x67, + 0xc8, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, + 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, 0x20, 0x43, + 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, 0x61, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, + 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, + 0x31, 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, + 0x34, 0x34, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x34, + 0x34, 0x30, 0x30, 0x5a, 0x30, 0x7d, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x08, 0x4e, 0x65, + 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, 0x79, + 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x79, 0x20, 0x4c, + 0x65, 0x61, 0x66, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0a, 0x6d, 0x79, + 0x6c, 0x65, 0x61, 0x66, 0x2e, 0x63, 0x6f, 0x6d, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, + 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xa0, 0xa3, 0xef, 0xc1, + 0x44, 0x7d, 0xa2, 0xe3, 0x71, 0x98, 0x27, 0x63, + 0xb3, 0x1d, 0x71, 0x50, 0xa6, 0x34, 0x15, 0xcb, + 0xc9, 0x2a, 0xc3, 0xea, 0xe4, 0x9e, 0x9c, 0x49, + 0xa6, 0x01, 0x9b, 0x7e, 0xa9, 0xb5, 0x7a, 0xff, + 0x15, 0x92, 0x71, 0xc8, 0x97, 0x9c, 0x25, 0xb7, + 0x79, 0x2b, 0xff, 0xab, 0xc6, 0xb1, 0xa7, 0x00, + 0x90, 0xb2, 0x8b, 0xd7, 0x71, 0xd5, 0xc2, 0x3a, + 0xe6, 0x82, 0x42, 0x37, 0x89, 0x41, 0x04, 0xb0, + 0xba, 0xc7, 0x5b, 0x8a, 0x43, 0x9f, 0x97, 0x39, + 0x0c, 0x0f, 0xd5, 0x6d, 0x9e, 0x8d, 0xeb, 0xc0, + 0x26, 0xc5, 0x18, 0xe8, 0x7a, 0x3d, 0x32, 0x2e, + 0x38, 0x90, 0x40, 0x5b, 0x39, 0x2c, 0x07, 0xcb, + 0x24, 0x10, 0xc5, 0xc9, 0x3b, 0xe3, 0x66, 0x47, + 0x57, 0xb9, 0x6a, 0xad, 0x44, 0xf8, 0xd0, 0x70, + 0x62, 0x3b, 0x8e, 0xed, 0x60, 0x5f, 0x22, 0xf8, + 0xb8, 0x0c, 0xc9, 0x41, 0x2b, 0xc9, 0x80, 0x6e, + 0x4e, 0x1b, 0xe1, 0x20, 0xfc, 0x47, 0xa4, 0xac, + 0xc3, 0x3f, 0xe6, 0xc2, 0x81, 0x79, 0x03, 0x37, + 0x25, 0x89, 0xca, 0xd6, 0xa5, 0x46, 0x91, 0x63, + 0x41, 0xc5, 0x3e, 0xd5, 0xed, 0x7f, 0x4f, 0x8d, + 0x06, 0xc0, 0x89, 0x00, 0xbe, 0x37, 0x7b, 0x7e, + 0x73, 0xca, 0x70, 0x00, 0x14, 0x34, 0xbe, 0x47, + 0xbc, 0xb2, 0x6a, 0x28, 0xa5, 0x29, 0x84, 0xa8, + 0x9d, 0xc8, 0x1e, 0x77, 0x66, 0x1f, 0x9f, 0xaa, + 0x2b, 0x47, 0xdb, 0xdd, 0x6b, 0x9c, 0xa8, 0xfc, + 0x82, 0x36, 0x94, 0x62, 0x0d, 0x5c, 0x3f, 0xb2, + 0x01, 0xb4, 0xa5, 0xb8, 0xc6, 0x0e, 0x94, 0x5b, + 0xec, 0x5e, 0xbb, 0x7a, 0x63, 0x24, 0xf1, 0xf9, + 0xd6, 0x50, 0x08, 0xc1, 0xa3, 0xcc, 0x90, 0x07, + 0x5b, 0x04, 0x04, 0x42, 0x74, 0xcf, 0x37, 0xfa, + 0xf0, 0xa5, 0xd9, 0xd3, 0x86, 0x89, 0x89, 0x18, + 0xf3, 0x4c, 0xe2, 0x11, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x90, 0xbb, 0xf9, + 0x5e, 0xba, 0x17, 0x1f, 0xac, 0x21, 0x9f, 0x6b, + 0x4a, 0x46, 0xd0, 0x6d, 0x3c, 0x8f, 0x3d, 0xf8, + 0x5e, 0x3e, 0x72, 0xaf, 0xa0, 0x1a, 0xf3, 0xff, + 0x89, 0xac, 0x5b, 0x7a, 0xe2, 0x91, 0x2a, 0x23, + 0x85, 0xc6, 0x4d, 0x47, 0x67, 0x01, 0x08, 0xa8, + 0x05, 0x1d, 0x01, 0x60, 0x50, 0x5f, 0x59, 0xad, + 0xfe, 0x7b, 0xc6, 0x0c, 0x54, 0x90, 0x68, 0x70, + 0x67, 0x2e, 0xed, 0x87, 0xf8, 0x69, 0x8a, 0xac, + 0x32, 0xfe, 0x6f, 0x90, 0x19, 0x2a, 0x64, 0x8d, + 0x82, 0x66, 0x05, 0x43, 0x88, 0xee, 0xf2, 0x30, + 0xed, 0xa4, 0x8f, 0xbf, 0xd6, 0x57, 0x20, 0xd4, + 0x43, 0x1d, 0x52, 0x96, 0x6f, 0xae, 0x09, 0x96, + 0x01, 0x52, 0x38, 0xe3, 0xaf, 0x99, 0xd7, 0xdc, + 0x14, 0x99, 0xc4, 0x8b, 0x0e, 0x04, 0x0f, 0xb3, + 0x14, 0x14, 0xd4, 0xa5, 0x93, 0xe1, 0xc9, 0x8a, + 0x81, 0xef, 0x63, 0xfc, 0x36, 0x77, 0x05, 0x06, + 0xf0, 0x2a, 0x04, 0x0a, 0xbe, 0x2e, 0xce, 0x81, + 0x3d, 0x23, 0xa1, 0xda, 0xd8, 0xeb, 0xc6, 0xea, + 0x5e, 0xcf, 0x28, 0x36, 0x51, 0x31, 0x95, 0x5e, + 0x40, 0x04, 0xed, 0xac, 0xc1, 0xc8, 0x56, 0x69, + 0x87, 0xec, 0x3b, 0x03, 0x3e, 0x9d, 0x0f, 0x4c, + 0x4c, 0xeb, 0xd7, 0xba, 0x26, 0xdf, 0xe3, 0xde, + 0x10, 0xee, 0x93, 0x62, 0x8d, 0x73, 0x52, 0x6e, + 0xff, 0x37, 0x36, 0x98, 0x7b, 0x2d, 0x56, 0x4c, + 0xba, 0x09, 0xb8, 0xa7, 0xf0, 0x3b, 0x16, 0x81, + 0xca, 0xdb, 0x43, 0xab, 0xec, 0x4c, 0x6e, 0x7c, + 0xc1, 0x0b, 0x22, 0x22, 0x43, 0x1d, 0xb6, 0x0c, + 0xc1, 0xb9, 0xcf, 0xe4, 0x53, 0xee, 0x1d, 0x3e, + 0x88, 0xa7, 0x13, 0xbe, 0x7f, 0xbd, 0xae, 0x72, + 0xcf, 0xcd, 0x63, 0xd2, 0xc3, 0x18, 0x58, 0x92, + 0xa2, 0xad, 0xb5, 0x09, 0x9d, 0x91, 0x03, 0xdd, + 0x3c, 0xe2, 0x1c, 0xde, 0x78, 0x00, 0x03, 0x88, + 0x30, 0x82, 0x03, 0x84, 0x30, 0x82, 0x02, 0x6c, + 0x02, 0x09, 0x00, 0xab, 0xed, 0xa6, 0xe4, 0x4a, + 0x2b, 0x2b, 0xf8, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, + 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, + 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, + 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x31, + 0x38, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x33, + 0x30, 0x36, 0x32, 0x35, 0x32, 0x31, 0x31, 0x38, + 0x34, 0x30, 0x5a, 0x30, 0x81, 0x80, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, + 0x6c, 0x79, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x4d, 0x79, + 0x20, 0x43, 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x6d, 0x79, 0x63, + 0x61, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, + 0x61, 0x68, 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, + 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xce, + 0x13, 0xf0, 0x72, 0xb0, 0x61, 0xc8, 0x18, 0x37, + 0x8a, 0x41, 0x3d, 0x20, 0xa1, 0x1c, 0xcb, 0xbf, + 0xf6, 0x3b, 0x74, 0x26, 0x2a, 0x96, 0x11, 0xec, + 0x53, 0xa1, 0xcc, 0x7d, 0x77, 0x56, 0x45, 0x0f, + 0x36, 0xb7, 0xf2, 0x48, 0x92, 0x1a, 0x62, 0xcc, + 0xb6, 0xc0, 0xa1, 0x2f, 0x44, 0x2b, 0xc1, 0x89, + 0xcb, 0x6e, 0x1e, 0xdb, 0x57, 0x92, 0xd5, 0x97, + 0x60, 0x8c, 0x41, 0x2c, 0xd9, 0x20, 0xfe, 0xe9, + 0x1f, 0x8e, 0xfc, 0x7f, 0x02, 0x44, 0x0f, 0x28, + 0x81, 0xd6, 0x0c, 0xcd, 0xbc, 0xf0, 0x57, 0x6c, + 0xcc, 0xa7, 0xba, 0x06, 0xa0, 0xa6, 0x91, 0xda, + 0xef, 0x46, 0x8a, 0x60, 0x0f, 0x52, 0x6c, 0x90, + 0x6c, 0x8c, 0x44, 0xaf, 0xb0, 0x9d, 0x90, 0xba, + 0x21, 0x58, 0xa0, 0x3c, 0xee, 0x54, 0xb5, 0x29, + 0x26, 0x1f, 0x0a, 0xac, 0xef, 0x48, 0x68, 0x33, + 0xd0, 0x33, 0xd0, 0x8b, 0x1a, 0xec, 0x6e, 0x2f, + 0xb5, 0x4a, 0x53, 0xc2, 0x1a, 0xd2, 0xf1, 0x50, + 0x05, 0x59, 0x5c, 0xd9, 0xda, 0x03, 0x0a, 0x47, + 0xb7, 0xdd, 0xf7, 0x3a, 0x69, 0xf5, 0x4e, 0xea, + 0x4a, 0xc2, 0xca, 0x54, 0xb0, 0x8b, 0x76, 0xe1, + 0x02, 0x2d, 0x52, 0x67, 0xb9, 0xdd, 0x50, 0xc9, + 0x3b, 0x07, 0x24, 0x22, 0x6a, 0x00, 0x1d, 0x58, + 0x83, 0xa8, 0xec, 0x95, 0xf1, 0xda, 0xe2, 0x73, + 0xa0, 0xa1, 0x72, 0x60, 0x9e, 0x86, 0x53, 0xcb, + 0x45, 0xa8, 0xc2, 0xa0, 0x50, 0xa0, 0x53, 0xd6, + 0xfc, 0x18, 0x84, 0xb5, 0x4a, 0x26, 0xd0, 0xa2, + 0xaa, 0xd0, 0xff, 0xb6, 0xfe, 0x3a, 0x9c, 0xb5, + 0x19, 0x3b, 0x3f, 0xe1, 0x48, 0x0d, 0xa4, 0x09, + 0x4f, 0x83, 0xc9, 0xc0, 0xc9, 0xa6, 0x0b, 0x58, + 0x1f, 0x1c, 0x7b, 0xac, 0xa2, 0x42, 0xbc, 0x61, + 0xf4, 0x21, 0x8a, 0x00, 0xda, 0x14, 0xa0, 0x60, + 0x03, 0xfe, 0x93, 0x12, 0x6c, 0x56, 0xcd, 0x02, + 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x25, 0x29, 0x3b, 0x1e, 0xc3, 0x58, 0x32, 0xe6, + 0x23, 0xc8, 0xee, 0x18, 0xf0, 0x1d, 0x62, 0x6d, + 0x3b, 0x59, 0x99, 0x3a, 0xfe, 0x49, 0x72, 0x07, + 0x3f, 0x58, 0x93, 0xdb, 0xc0, 0xaf, 0xb0, 0xb3, + 0x5c, 0xd1, 0x5c, 0x98, 0xc8, 0xea, 0x4a, 0xe4, + 0x58, 0x73, 0x0d, 0x57, 0xc5, 0x13, 0x7c, 0x5c, + 0x79, 0x66, 0xda, 0x04, 0x1d, 0xe5, 0x98, 0xda, + 0x35, 0x47, 0x44, 0xb0, 0xd2, 0x7a, 0x66, 0x9d, + 0xcd, 0x41, 0xa5, 0x8f, 0xa1, 0x11, 0xb2, 0x1a, + 0x87, 0xc0, 0xcd, 0x55, 0xed, 0xb4, 0x7b, 0x33, + 0x72, 0xeb, 0xf7, 0xe3, 0x7b, 0x8b, 0x02, 0x86, + 0xe9, 0x2b, 0x26, 0x32, 0x9f, 0x99, 0xf1, 0xcb, + 0x93, 0xab, 0xb9, 0x16, 0xb3, 0x9a, 0xb2, 0x22, + 0x13, 0x21, 0x1f, 0x5b, 0xcc, 0xa2, 0x59, 0xbb, + 0x69, 0xf2, 0xb8, 0x07, 0x80, 0xce, 0x0c, 0xf7, + 0x98, 0x4c, 0x85, 0xc2, 0x96, 0x6a, 0x22, 0x05, + 0xe9, 0xbe, 0x48, 0xb0, 0x02, 0x5b, 0x69, 0x28, + 0x18, 0x88, 0x96, 0xe3, 0xd7, 0xc6, 0x7a, 0xd3, + 0xe9, 0x99, 0xff, 0x9d, 0xc3, 0x61, 0x4d, 0x9a, + 0x96, 0xf2, 0xc6, 0x33, 0x4d, 0xe5, 0x5d, 0x5a, + 0x68, 0x64, 0x5a, 0x82, 0x35, 0x65, 0x25, 0xe3, + 0x8c, 0x5b, 0xb0, 0xf6, 0x96, 0x56, 0xbc, 0xbf, + 0x97, 0x76, 0x4b, 0x66, 0x44, 0x81, 0xa4, 0xc4, + 0xa7, 0x31, 0xc5, 0xa1, 0x4f, 0xe8, 0xa4, 0xca, + 0x20, 0xf5, 0x01, 0x5b, 0x99, 0x4f, 0x5a, 0xf4, + 0xf0, 0x78, 0xbf, 0x71, 0x49, 0xd5, 0xf1, 0xc1, + 0xa2, 0x18, 0xfd, 0x72, 0x5b, 0x16, 0xe8, 0x92, + 0xc7, 0x37, 0x48, 0xaf, 0xee, 0x24, 0xfc, 0x35, + 0x0b, 0xc2, 0xdd, 0x05, 0xc7, 0x6e, 0xa3, 0x29, + 0xbb, 0x29, 0x7d, 0xd3, 0x2b, 0x94, 0x80, 0xc3, + 0x40, 0x53, 0x0e, 0x03, 0x54, 0x3d, 0x7b, 0x8b, + 0xce, 0xf9, 0xa4, 0x03, 0x27, 0x63, 0xec, 0x51, + 0x00, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, + 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x09, 0x00, 0xcc, 0x22, 0x4c, 0x4b, 0x98, + 0xa2, 0x88, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x30, 0x81, 0x86, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, 0x6c, + 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, + 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, 0x67, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, + 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, 0x69, + 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x35, 0x32, 0x36, 0x32, 0x31, 0x30, + 0x35, 0x30, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x33, + 0x30, 0x35, 0x32, 0x34, 0x32, 0x31, 0x30, 0x35, + 0x30, 0x31, 0x5a, 0x30, 0x81, 0x86, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x4e, 0x59, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x42, 0x72, 0x6f, 0x6f, 0x6b, + 0x6c, 0x79, 0x6e, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x4d, 0x79, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x6d, 0x79, 0x63, 0x61, 0x2e, 0x6f, 0x72, + 0x67, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x12, 0x6a, 0x76, 0x73, 0x68, 0x61, 0x68, + 0x69, 0x64, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, + 0x02, 0x82, 0x01, 0x01, 0x00, 0xf0, 0xfb, 0xad, + 0x80, 0x5e, 0x37, 0xd3, 0x6d, 0xee, 0x2e, 0xcc, + 0xbc, 0x0c, 0xd7, 0x56, 0x4b, 0x56, 0x45, 0xcd, + 0x28, 0xb6, 0x22, 0xe9, 0xe2, 0x0f, 0xd1, 0x87, + 0x2a, 0x27, 0xce, 0x77, 0x8d, 0x6e, 0x0e, 0x0f, + 0xfb, 0x66, 0xe1, 0xb5, 0x0e, 0x9a, 0xb6, 0x05, + 0x8e, 0xb3, 0xe1, 0xc5, 0x77, 0x86, 0x5b, 0x46, + 0xd2, 0x0b, 0x92, 0x03, 0x1b, 0x89, 0x0c, 0x1b, + 0x10, 0x0e, 0x99, 0x8f, 0xe2, 0x17, 0xe8, 0xc2, + 0x30, 0x00, 0x47, 0xd6, 0xfc, 0xf9, 0x0f, 0x3b, + 0x75, 0x34, 0x8d, 0x4d, 0xb0, 0x99, 0xb7, 0xa0, + 0x6d, 0xa0, 0xb6, 0xad, 0xda, 0x07, 0x5e, 0x38, + 0x2e, 0x02, 0xe4, 0x30, 0x6d, 0xae, 0x13, 0x72, + 0xd4, 0xc8, 0xce, 0x14, 0x07, 0xae, 0x23, 0x8c, + 0x8f, 0x9e, 0x8c, 0x60, 0xd6, 0x06, 0xb9, 0xef, + 0x00, 0x18, 0xc0, 0x1d, 0x25, 0x1e, 0xda, 0x3e, + 0x2f, 0xcf, 0x2b, 0x56, 0x84, 0x9e, 0x30, 0x21, + 0xc7, 0x29, 0xf6, 0x03, 0x8a, 0x24, 0xf9, 0x34, + 0xac, 0x65, 0x9d, 0x80, 0x36, 0xc8, 0x3b, 0x15, + 0x10, 0xbd, 0x51, 0xe9, 0xbc, 0x02, 0xe1, 0xe9, + 0xb3, 0x5a, 0x9a, 0x99, 0x41, 0x1b, 0x27, 0xa0, + 0x4d, 0x50, 0x9e, 0x27, 0x7f, 0xa1, 0x7d, 0x09, + 0x87, 0xbd, 0x8a, 0xca, 0x5f, 0xb1, 0xa5, 0x08, + 0xb8, 0x04, 0xd4, 0x52, 0x89, 0xaa, 0xe0, 0x7d, + 0x42, 0x2e, 0x2f, 0x15, 0xee, 0x66, 0x57, 0x0f, + 0x13, 0x19, 0x45, 0xa8, 0x4b, 0x5d, 0x81, 0x66, + 0xcc, 0x12, 0x37, 0x94, 0x5e, 0xfd, 0x3c, 0x10, + 0x81, 0x51, 0x3f, 0xfa, 0x0f, 0xdd, 0xa1, 0x89, + 0x03, 0xa9, 0x78, 0x91, 0xf5, 0x3b, 0xf3, 0xbc, + 0xac, 0xbe, 0x93, 0x30, 0x2e, 0xbe, 0xca, 0x7f, + 0x46, 0xd3, 0x28, 0xb4, 0x4e, 0x91, 0x7b, 0x5b, + 0x43, 0x6c, 0xaf, 0x9b, 0x5c, 0x6a, 0x6d, 0x5a, + 0xdb, 0x79, 0x5e, 0x6a, 0x6b, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, 0x7d, + 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, 0x90, + 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x6b, 0x1e, 0x00, 0xa8, 0x9f, 0xfa, + 0x7d, 0x00, 0xf9, 0xe0, 0x9d, 0x0f, 0x90, 0x8c, + 0x90, 0xa8, 0xa1, 0x37, 0x6b, 0xda, 0x30, 0x0c, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, + 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0xcd, 0x6f, 0x73, 0x4d, 0x56, 0x0b, 0xf3, 0x2e, + 0x1c, 0xe2, 0x02, 0x0c, 0x14, 0xbb, 0x2f, 0xdd, + 0x3c, 0x43, 0xfe, 0xdf, 0x94, 0x2d, 0xa9, 0x89, + 0x81, 0x51, 0xf8, 0x5f, 0xa7, 0xa0, 0x13, 0xaa, + 0xcc, 0xb0, 0x18, 0xe2, 0x57, 0x3e, 0x0d, 0x29, + 0x93, 0xe8, 0x95, 0xd5, 0x1b, 0x53, 0xd2, 0x51, + 0xf2, 0xbd, 0xf5, 0x9e, 0x7b, 0x22, 0x65, 0x62, + 0x5c, 0xc4, 0x4c, 0x1d, 0xe8, 0xe9, 0xc3, 0xd4, + 0x2b, 0xe7, 0x78, 0xcb, 0x10, 0xf3, 0xfe, 0x06, + 0x83, 0xdc, 0x3a, 0x1e, 0x62, 0x10, 0xc0, 0x46, + 0x77, 0xc6, 0x9d, 0x9f, 0xab, 0x96, 0x25, 0x5c, + 0xfb, 0x26, 0xc1, 0x15, 0x1f, 0xa5, 0x33, 0xee, + 0x4f, 0x9a, 0x14, 0x6a, 0x14, 0x97, 0x93, 0x2b, + 0x95, 0x0b, 0xdc, 0xa8, 0xd7, 0x69, 0x2e, 0xf0, + 0x01, 0x0e, 0xfd, 0x4e, 0xd0, 0xd9, 0xa8, 0xe5, + 0x65, 0xde, 0xfb, 0xca, 0xca, 0x1c, 0x5f, 0xf9, + 0x53, 0xa0, 0x87, 0xe7, 0x33, 0x9b, 0x2f, 0xcf, + 0xe4, 0x13, 0xfc, 0xec, 0x7a, 0x6c, 0xb0, 0x90, + 0x13, 0x9b, 0xb6, 0xc5, 0x03, 0xf6, 0x0e, 0x5e, + 0xe2, 0xe4, 0x26, 0xc1, 0x7e, 0x53, 0xfe, 0x69, + 0xa3, 0xc7, 0xd8, 0x8e, 0x6e, 0x94, 0x32, 0xa0, + 0xde, 0xca, 0xb6, 0xcc, 0xd6, 0x01, 0xd5, 0x78, + 0x40, 0x28, 0x63, 0x9b, 0xee, 0xcf, 0x09, 0x3b, + 0x35, 0x04, 0xf0, 0x14, 0x02, 0xf6, 0x80, 0x0e, + 0x90, 0xb2, 0x94, 0xd2, 0x25, 0x16, 0xb8, 0x7a, + 0x76, 0x87, 0x84, 0x9f, 0x84, 0xc5, 0xaf, 0xc2, + 0x6d, 0x68, 0x7a, 0x84, 0x9c, 0xc6, 0x8a, 0x63, + 0x60, 0x87, 0x6a, 0x25, 0xc1, 0xa1, 0x78, 0x0f, + 0xba, 0xe8, 0x5f, 0xe1, 0xba, 0xac, 0xa4, 0x6f, + 0xdd, 0x09, 0x3f, 0x12, 0xcb, 0x1d, 0xf3, 0xcf, + 0x48, 0xd7, 0xd3, 0x26, 0xe8, 0x9c, 0xc3, 0x53, + 0xb3, 0xba, 0xdc, 0x32, 0x99, 0x98, 0x96, 0xd6, + 0x16, 0x03, 0x03, 0x00, 0x46, 0x10, 0x00, 0x00, + 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, + 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, + 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, + 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, + 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, + 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, + 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, + 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, + 0xdc, 0x5a, 0x89, 0x16, 0x03, 0x03, 0x01, 0x08, + 0x0f, 0x00, 0x01, 0x04, 0x04, 0x01, 0x01, 0x00, + 0x7e, 0xe4, 0x65, 0x02, 0x8e, 0xb3, 0x34, 0x6a, + 0x47, 0x71, 0xd1, 0xb0, 0x8d, 0x3c, 0x0c, 0xe1, + 0xde, 0x7e, 0x5f, 0xb4, 0x15, 0x2d, 0x32, 0x0a, + 0x2a, 0xdb, 0x9b, 0x40, 0xba, 0xce, 0x8b, 0xf5, + 0x74, 0xc1, 0x68, 0x20, 0x7c, 0x87, 0x23, 0x13, + 0xc3, 0x13, 0xa7, 0xdb, 0xec, 0x59, 0xa0, 0x40, + 0x9e, 0x64, 0x03, 0x60, 0xac, 0x76, 0xff, 0x01, + 0x34, 0x7b, 0x32, 0x26, 0xd9, 0x41, 0x31, 0x93, + 0xaa, 0x30, 0x51, 0x83, 0x85, 0x40, 0xeb, 0x4e, + 0x66, 0x39, 0x83, 0xb1, 0x30, 0x0d, 0x96, 0x01, + 0xee, 0x81, 0x53, 0x5e, 0xec, 0xa9, 0xc9, 0xdf, + 0x7e, 0xc1, 0x09, 0x47, 0x8b, 0x35, 0xdb, 0x10, + 0x15, 0xd4, 0xc7, 0x5a, 0x39, 0xe3, 0xc0, 0xf3, + 0x93, 0x38, 0x11, 0xdc, 0x71, 0xbb, 0xc7, 0x62, + 0x2b, 0x85, 0xad, 0x6b, 0x4f, 0x09, 0xb3, 0x31, + 0xa8, 0xe5, 0xd1, 0xb3, 0xa9, 0x21, 0x37, 0x50, + 0xc8, 0x7d, 0xc3, 0xd2, 0xf7, 0x00, 0xd3, 0xdb, + 0x0f, 0x82, 0xf2, 0x43, 0xcf, 0x36, 0x6c, 0x98, + 0x63, 0xd8, 0x1d, 0xb3, 0xf3, 0xde, 0x63, 0x79, + 0x64, 0xf0, 0xdb, 0x46, 0x04, 0xe1, 0x1c, 0x57, + 0x0f, 0x9e, 0x96, 0xb9, 0x93, 0x45, 0x71, 0x1c, + 0x8b, 0x65, 0x7d, 0x1e, 0xad, 0xbd, 0x03, 0x51, + 0xae, 0x44, 0xef, 0x97, 0x45, 0x0d, 0x8d, 0x41, + 0x5c, 0x80, 0x7b, 0xe6, 0xe0, 0xbc, 0xa6, 0x72, + 0x95, 0xa0, 0x97, 0xe1, 0xbb, 0xc0, 0xcc, 0xe5, + 0x1e, 0xc3, 0xbe, 0xd7, 0x42, 0x2a, 0xf3, 0x75, + 0x8a, 0x44, 0x67, 0x3c, 0xe5, 0x68, 0x78, 0xe5, + 0x40, 0x1f, 0xf0, 0x89, 0x57, 0xda, 0xee, 0x45, + 0xf4, 0x44, 0x81, 0x01, 0x77, 0xf0, 0x4a, 0x14, + 0xb1, 0x3f, 0x60, 0x2b, 0xeb, 0x42, 0x38, 0xa6, + 0xfb, 0xe5, 0x4d, 0x71, 0xdc, 0x7d, 0x0a, 0x72, + 0x56, 0x28, 0x9d, 0xa6, 0x8e, 0x74, 0x2d, 0xbd, + 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x31, 0x4d, 0x58, 0x94, 0x0b, + 0x0b, 0x06, 0x5f, 0xae, 0x57, 0x17, 0x98, 0x86, + 0xaa, 0x49, 0x17, 0x7f, 0xbd, 0x41, 0x05, 0xa5, + 0x74, 0x1c, 0x58, 0xc8, 0x38, 0x2d, 0x99, 0x5d, + 0xe5, 0x12, 0x43, + }, + { + 0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x03, 0x00, 0x28, 0xf2, 0x60, 0xc2, 0x75, 0x27, + 0x64, 0xf4, 0x05, 0x98, 0xc9, 0xd3, 0xa8, 0x00, + 0x4c, 0xa0, 0x49, 0x82, 0x68, 0xf1, 0x21, 0x05, + 0x7b, 0x4b, 0x25, 0x3e, 0xe1, 0x5f, 0x0f, 0x84, + 0x26, 0x2d, 0x16, 0x2e, 0xc0, 0xfd, 0xdf, 0x0a, + 0xf4, 0xba, 0x19, + }, + { + 0x17, 0x03, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x35, 0xef, 0x9d, + 0x6a, 0x86, 0x98, 0xc5, 0xca, 0x55, 0xca, 0x89, + 0x29, 0xb4, 0x55, 0xd4, 0x41, 0x08, 0x96, 0xe0, + 0xf3, 0x39, 0xfc, 0x15, 0x03, 0x03, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x02, 0x63, 0x1b, 0xaa, 0xc6, 0xc9, 0x6d, 0x72, + 0x24, 0x10, 0x55, 0xa9, 0x8c, 0x3b, 0x23, 0xce, + 0xd8, 0x4a, + }, +} + +var testClientChainCertificate = fromHex( + "2d2d2d2d2d424547494e2050524956415445204b" + + "45592d2d2d2d2d0a4d494945766749424144414e" + + "42676b71686b6947397730424151454641415343" + + "424b67776767536b41674541416f494241514367" + + "6f2b2f4252483269343347590a4a324f7a485846" + + "51706a515679386b71772b726b6e70784a706747" + + "6266716d31657638566b6e48496c35776c74336b" + + "722f367647736163416b4c4b4c313348560a776a" + + "726d676b493369554545734c7248573470446e35" + + "633544412f56625a364e3638416d78526a6f656a" + + "30794c6a6951514673354c41664c4a4244467954" + + "766a0a5a6b64587557717452506a51634749376a" + + "75316758794c3475417a4a5153764a6747354f47" + + "2b45672f45656b724d4d2f35734b4265514d334a" + + "596e4b317156470a6b574e427854375637583950" + + "6a5162416951432b4e33742b6338707741425130" + + "766b6538736d6f6f70536d45714a3349486e646d" + + "48352b714b306662335775630a715079434e7052" + + "694456772f7367473070626a4744705262374636" + + "37656d4d6b38666e5755416a426f387951423173" + + "4542454a307a7a6636384b585a3034614a0a6952" + + "6a7a544f495241674d424141454367674542414a" + + "4b613676326b5a3144596146786e586d7369624c" + + "386734426f67514c6a42307362524a6d746b6b4d" + + "54370a685343325873537551522f446c654d7148" + + "664555786731784a717579597643544d44585972" + + "473667354a5051744d4432465a424a7239626c65" + + "467138386c706a0a543766514e793571354c2b4f" + + "682f6b62433835436e623641753641656978776d" + + "2b6e77665a4f3766726b6278306d35516b715975" + + "5739392f452b69502b454e570a76396a68773436" + + "76515065563236494b79717656462b4f7362722f" + + "6152316138707948336361566e3579594a433346" + + "5855756c6f5a77516331714a6b4c434c4c0a375a" + + "49744f525a78514c486d4d4a654d44722f5a4942" + + "34675467645650636145375a4d5141714d6d3066" + + "4c6b6d7671723149526b77642f6831455a645650" + + "79320a742f6b6b43413039566336663749556575" + + "6f67706d705a50303130564e376b6277394a6348" + + "75544561564543675945417a47395679426e6d62" + + "6858496c57764f0a71583747524f2f5231636a2b" + + "6b564e35377876674b54756b35592b7a4d774a48" + + "32626c57435945513251753974446c476854756b" + + "664273385746772b6e6263460a7a6f706d535245" + + "6c6d464d2f6141536d464733574e5a7072696a68" + + "504b77726338376470636b31703131635a415478" + + "5a413168566d43743457616343673634690a4d74" + + "64507a334e2f34416147664956794d2b69624949" + + "35332f515543675945417953693556735a356f6a" + + "644a795077426e6c6142554231686f2b336b7068" + + "70770a7264572b2b4d796b51494a345564534437" + + "3052486e5a315839754359713978616671746c51" + + "664c44395963442f436d665264706461586c5673" + + "5249467a5a556c0a454630557149644e77337046" + + "68634f4a6d6e5a3241434470434342476f763542" + + "6e3068302b3137686a4b376f69315833716e4542" + + "7857326c7462593476556a500a44394c5330666e" + + "4a76703043675942504a527330714c4a4a464333" + + "6669796b712f57574d38727474354b364a584b50" + + "734b674b53644144577a7463316645434d0a7a65" + + "2b394a6a5a376b4d77557063666a644c2b745047" + + "3455563048326c524375635735414131396d7058" + + "50367454494733713737655a6b416e65516f6163" + + "41340a716c3073583051476c6a5763414e30464b" + + "6f4759733975582b6378445a6e7265362f52392f" + + "3930567766443237454c57546373677734633463" + + "514b42675143420a6f5432326e745a5a59396d6e" + + "72455a36752f492f4a332f35664e396737783733" + + "3177746e463745745a5361575453587364597256" + + "466b564f6362505135494a6f0a714a6a7249372b" + + "474a4d69376f6a4c69642f4c45656f31764f3163" + + "454158334f43723236554e38612f6c7434394f5a" + + "69354c337348556b756c475951755671650a6737" + + "6e6e4632437749544c34503645486443575a4461" + + "7a4136626d7375524f2b6462536e335a6c567651" + + "4b42674859524c5a665458536c44755264776977" + + "746b0a513148546b6d6b57694156726c4f577864" + + "5858456d546130303045574c46446145797a7358" + + "7834424863357166776b5a4e746b634a56396e58" + + "63536e647441530a35767a427a676e797a4f7962" + + "68315878484a3966427472414f3847555878446c" + + "6634394457616753393449763072596e616b7656" + + "2f673039786875415763366e0a5365757230576b" + + "5376453847666653734d485149584c456b0a2d2d" + + "2d2d2d454e442050524956415445204b45592d2d" + + "2d2d2d0a2d2d2d2d2d424547494e204345525449" + + "4649434154452d2d2d2d2d0a4d494944656a4343" + + "416d494343514330523168584b326649776a414e" + + "42676b71686b6947397730424151554641444342" + + "6744454c4d416b474131554542684d430a56564d" + + "78437a414a42674e564241674d416b355a4d5245" + + "77447759445651514844416843636d3976613278" + + "35626a45564d424d47413155454367774d54586b" + + "670a51304567513278705a5735304d5263774651" + + "5944565151444441357465574e68593278705a57" + + "35304c6d4e76625445684d423847435371475349" + + "62334451454a0a41525953616e5a7a6147466f61" + + "5752415a32316861577775593239744d42345844" + + "54457a4d4455794e6a49784e4451774d466f5844" + + "54457a4d4459794e5449780a4e4451774d466f77" + + "6654454c4d416b474131554542684d4356564d78" + + "4554415042674e564241674d4345356c6479425a" + + "62334a724d52457744775944565151480a444168" + + "43636d397661327835626a45514d413447413155" + + "454367774854586b67544756685a6a45544d4245" + + "47413155454177774b62586c735a57466d4c6d4e" + + "760a625445684d42384743537147534962334451" + + "454a41525953616e5a7a6147466f615752415a32" + + "316861577775593239744d494942496a414e4267" + + "6b71686b69470a397730424151454641414f4341" + + "5138414d49494243674b43415145416f4b507677" + + "5552396f754e786d43646a73783178554b593046" + + "63764a4b735071354a36630a536159426d333670" + + "7458722f465a4a78794a65634a6264354b2f2b72" + + "7872476e414a43796939647831634936356f4a43" + + "4e346c42424c43367831754b51352b580a4f5177" + + "50315732656a6576414a73555936486f394d6934" + + "346b4542624f5377487979515178636b3734325a" + + "4856376c7172555434304842694f343774594638" + + "690a2b4c674d7955457279594275546876684950" + + "7848704b7a44502b624367586b444e79574a7974" + + "616c5270466a5163552b3165312f543430477749" + + "6b41766a64370a666e504b634141554e4c354876" + + "4c4a714b4b5570684b6964794235335a682b6671" + + "697448323931726e4b6a38676a61555967316350" + + "374942744b5734786736550a572b78657533706a" + + "4a504835316c41497761504d6b41646242415243" + + "644d38332b76436c32644f4769596b5938307a69" + + "45514944415141424d413047435371470a534962" + + "3344514542425155414134494241514351752f6c" + + "65756863667243476661307047304730386a7a33" + + "34586a357972364161382f2b4a72467436347045" + + "710a493458475455646e4151696f425230425946" + + "42665761332b6538594d564a426f634763753759" + + "6634615971734d7635766b426b715a4932435a67" + + "5644694f37790a4d4f326b6a372f575679445551" + + "7831536c6d2b75435a5942556a6a6a72356e5833" + + "42535a7849734f42412b7a46425455705a506879" + + "597142373250384e6e63460a427641714241712b" + + "4c73364250534f6832746a72787570657a796732" + + "55544756586b414537617a4279465a70682b7737" + + "417a36644430784d363965364a742f6a0a336844" + + "756b324b4e63314a752f7a63326d487374566b79" + + "364362696e384473576763726251367673544735" + + "3877517369496b4d6474677a4275632f6b552b34" + + "640a506f696e4537352f766135797a38316a3073" + + "4d59574a4b697262554a6e5a454433547a69484e" + + "35340a2d2d2d2d2d454e44204345525449464943" + + "4154452d2d2d2d2d0a2d2d2d2d2d424547494e20" + + "43455254494649434154452d2d2d2d2d0a4d4949" + + "4468444343416d7743435143723761626b536973" + + "722b44414e42676b71686b694739773042415155" + + "4641444342686a454c4d416b474131554542684d" + + "430a56564d78437a414a42674e564241674d416b" + + "355a4d524577447759445651514844416843636d" + + "397661327835626a45684d423847413155454367" + + "775954586b670a5132567964476c6d61574e6864" + + "4755675158563061473979615852354d52457744" + + "775944565151444441687465574e684c6d39795a" + + "7a45684d423847435371470a534962334451454a" + + "41525953616e5a7a6147466f615752415a323168" + + "61577775593239744d4234584454457a4d445579" + + "4e6a49784d5467304d466f584454457a0a4d4459" + + "794e5449784d5467304d466f7767594178437a41" + + "4a42674e5642415954416c56544d517377435159" + + "445651514944414a4f575445524d413847413155" + + "450a42777749516e4a7662327473655734784654" + + "415442674e5642416f4d4445313549454e424945" + + "4e7361575675644445584d425547413155454177" + + "774f62586c6a0a59574e73615756756443356a62" + + "3230784954416642676b71686b69473977304243" + + "514557456d70326332686861476c6b5147647459" + + "576c734c6d4e76625443430a415349774451594a" + + "4b6f5a496876634e415145424251414467674550" + + "4144434341516f4367674542414d345438484b77" + + "596367594e34704250534368484d752f0a396a74" + + "304a697157456578546f63783964315a46447a61" + + "33386b6953476d4c4d747343684c30517277596e" + + "4c6268376256354c566c32434d51537a5a495037" + + "700a4834373866774a454479694231677a4e7650" + + "4258624d796e75676167707048613730614b5941" + + "3953624a42736a455376734a3251756946596f44" + + "7a75564c55700a4a68384b724f3949614450514d" + + "39434c477578754c37564b553849613076465142" + + "566c6332646f44436b6533336663366166564f36" + + "6b7243796c5377693362680a416931535a376e64" + + "554d6b37427951696167416457494f6f374a5878" + + "32754a7a6f4b4679594a364755387446714d4b67" + + "554b425431767759684c564b4a7443690a717444" + + "2f747634366e4c555a4f7a2f685341326b43552b" + + "447963444a7067745948787837724b4a43764748" + + "3049596f41326853675941502b6b784a73567330" + + "430a417745414154414e42676b71686b69473977" + + "30424151554641414f43415145414a536b374873" + + "4e594d75596a794f3459384231696254745a6d54" + + "722b535849480a5031695432384376734c4e6330" + + "567959794f704b3546687a445666464533786365" + + "5762614242336c6d4e6f3152305377306e706d6e" + + "63314270592b68456249610a6838444e56653230" + + "657a4e79362f666a6534734368756b724a6a4b66" + + "6d66484c6b36753546724f617369495449523962" + + "7a4b4a5a75326e79754165417a677a330a6d4579" + + "4677705a7149675870766b6977416c74704b4269" + + "496c755058786e7254365a6e2f6e634e68545a71" + + "573873597a54655664576d686b576f49315a5358" + + "6a0a6a46757739705a57764c2b58646b746d5249" + + "476b784b637878614650364b544b495055425735" + + "6c5057765477654c397853645878776149592f58" + + "4a62467569530a787a6449722b346b2f44554c77" + + "7430467832366a4b62737066644d726c49444451" + + "464d4f413151396534764f2b6151444a32507355" + + "513d3d0a2d2d2d2d2d454e442043455254494649" + + "434154452d2d2d2d2d0a2d2d2d2d2d424547494e" + + "2043455254494649434154452d2d2d2d2d0a4d49" + + "49443454434341736d67417749424167494a414d" + + "7769544575596f6f6a384d413047435371475349" + + "623344514542425155414d4947474d5173774351" + + "59440a5651514745774a56557a454c4d416b4741" + + "31554543417743546c6b784554415042674e5642" + + "41634d43454a796232397262486c754d53457748" + + "7759445651514b0a4442684e655342445a584a30" + + "61575a70593246305a5342426458526f62334a70" + + "64486b784554415042674e5642414d4d43473135" + + "5932457562334a6e4d5345770a4877594a4b6f5a" + + "496876634e41516b4246684a71646e4e6f595768" + + "705a45426e625746706243356a62323077486863" + + "4e4d544d774e5449324d6a45774e5441780a5768" + + "634e4d6a4d774e5449304d6a45774e544178576a" + + "4342686a454c4d416b474131554542684d435656" + + "4d78437a414a42674e564241674d416b355a4d52" + + "45770a447759445651514844416843636d397661" + + "327835626a45684d423847413155454367775954" + + "586b675132567964476c6d61574e686447556751" + + "585630614739790a615852354d52457744775944" + + "565151444441687465574e684c6d39795a7a4568" + + "4d42384743537147534962334451454a41525953" + + "616e5a7a6147466f615752410a5a323168615777" + + "75593239744d494942496a414e42676b71686b69" + + "47397730424151454641414f43415138414d4949" + + "4243674b434151454138507574674634330a3032" + + "33754c737938444e645753315a467a5369324975" + + "6e69443947484b69664f6434317544672f375a75" + + "4731447071324259367a34635633686c74473067" + + "75530a4178754a4442735144706d503468666f77" + + "6a4141523962382b5138376454534e5462435a74" + + "3642746f4c6174326764654f4334433544427472" + + "684e79314d6a4f0a46416575493479506e6f7867" + + "31676135377741597742306c48746f2b4c383872" + + "566f53654d4348484b665944696954354e4b786c" + + "6e59413279447356454c31520a3662774334656d" + + "7a5770715a5152736e6f4531516e69642f6f5830" + + "4a6837324b796c2b7870516934424e5253696172" + + "67665549754c7858755a6c635045786c460a7145" + + "74646757624d456a65555876303845494652502f" + + "6f503361474a41366c346b665537383779737670" + + "4d774c72374b663062544b4c524f6b5874625132" + + "79760a6d31787162567262655635716177494441" + + "5141426f314177546a416442674e564851344546" + + "67515561783441714a2f3666514435344a30506b" + + "497951714b45330a61396f77487759445652306a" + + "42426777466f415561783441714a2f3666514435" + + "344a30506b497951714b453361396f7744415944" + + "5652305442415577417745420a2f7a414e42676b" + + "71686b6947397730424151554641414f43415145" + + "417a57397a5456594c387934633467494d464c73" + + "76335478442f742b554c616d4a675648340a5836" + + "65674536724d73426a69567a344e4b5a506f6c64" + + "556255394a52387233316e6e73695a574a637845" + + "7764364f6e443143766e654d7351382f34476739" + + "77360a486d495177455a33787032667135596c58" + + "50736d775255667054507554356f55616853586b" + + "7975564339796f31326b753841454f2f55375132" + + "616a6c5a6437370a79736f63582f6c546f49666e" + + "4d3573767a2b51542f4f7836624c435145357532" + + "78515032446c376935436242666c502b61615048" + + "324935756c444b67337371320a7a4e5942315868" + + "414b474f623773384a4f7a554538425143396f41" + + "4f6b4c4b55306955577548703268345366684d57" + + "76776d316f656f5363786f706a594964710a4a63" + + "476865412b3636462f687571796b6239304a5078" + + "4c4c48665050534e66544a75696377314f7a7574" + + "77796d5a695731673d3d0a2d2d2d2d2d454e4420" + + "43455254494649434154452d2d2d2d2d0a", +) + +// Script of interaction with openssl implementation: +// +// openssl s_server -cipher ECDHE-ECDSA-AES128-SHA \ +// -key server.key -cert server.crt -port 10443 +// +// The values for this test are obtained by building and running in client mode: +// % go test -test.run "TestRunClient" -connect -ciphersuites=0xc009 +// The recorded bytes are written to stdout. +// +// The server private key is: +// +// -----BEGIN EC PARAMETERS----- +// BgUrgQQAIw== +// -----END EC PARAMETERS----- +// -----BEGIN EC PRIVATE KEY----- +// MIHcAgEBBEIBmIPpCa0Kyeo9M/nq5mHxeFIGlw+MqakWcvHu3Keo7xK9ZWG7JG3a +// XfS01efjqSZJvF2DoL+Sly4A5iBn0Me9mdegBwYFK4EEACOhgYkDgYYABADEoe2+ +// mPkLSHM2fsMWVhEi8j1TwztNIT3Na3Xm9rDcmt8mwbyyh/ByMnyzZC8ckLzqaCMQ +// fv7jJcBIOmngKG3TNwDvBGLdDaCccGKD2IHTZDGqnpcxvZawaMCbI952ZD8aXH/p +// Eg5YWLZfcN2b2OrV1/XVzLm2nzBmW2aaIOIn5b/+Ow== +// -----END EC PRIVATE KEY----- +// +// and certificate is: +// +// -----BEGIN CERTIFICATE----- +// MIICADCCAWICCQC4vy1HoNLr9DAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw +// EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +// eSBMdGQwHhcNMTIxMTIyMTUwNjMyWhcNMjIxMTIwMTUwNjMyWjBFMQswCQYDVQQG +// EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk +// Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAxKHtvpj5C0hz +// Nn7DFlYRIvI9U8M7TSE9zWt15vaw3JrfJsG8sofwcjJ8s2QvHJC86mgjEH7+4yXA +// SDpp4Cht0zcA7wRi3Q2gnHBig9iB02Qxqp6XMb2WsGjAmyPedmQ/Glx/6RIOWFi2 +// X3Ddm9jq1df11cy5tp8wZltmmiDiJ+W//jswCQYHKoZIzj0EAQOBjAAwgYgCQgGI +// ok/r4kXFSH0brPXtmJ2uR3DAXhu2L73xtk23YUDTEaLO7gt+kn7/dp3DO36lP876 +// EOJZ7EctfKzaTpcOFaBv0AJCAU38vmcTnC0FDr0/o4wlwTMTgw2UBrvUN3r27HrJ +// hi7d1xFpf4V8Vt77MXgr5Md4Da7Lvp5ONiQxe2oPOZUSB48q +// -----END CERTIFICATE----- +var ecdheECDSAAESClientScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0x4a, 0x01, 0x00, 0x00, + 0x46, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x09, + 0x01, 0x00, 0x00, 0x1b, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x54, 0x02, 0x00, 0x00, + 0x50, 0x03, 0x01, 0x50, 0xd7, 0x19, 0xc9, 0x03, + 0xc2, 0x3a, 0xc6, 0x1f, 0x0a, 0x84, 0x9e, 0xd7, + 0xf4, 0x7e, 0x07, 0x6d, 0xa8, 0xe4, 0xa9, 0x4f, + 0x22, 0x50, 0xa2, 0x19, 0x24, 0x44, 0x42, 0x65, + 0xaa, 0xba, 0x3a, 0x20, 0x90, 0x70, 0xb7, 0xe5, + 0x57, 0xed, 0xb1, 0xb1, 0x43, 0x4b, 0xa1, 0x4e, + 0xee, 0x7a, 0x5b, 0x88, 0xf6, 0xa6, 0x73, 0x3b, + 0xcb, 0xa7, 0xbd, 0x57, 0x50, 0xf2, 0x72, 0x8c, + 0xbc, 0x45, 0x73, 0xaa, 0xc0, 0x09, 0x00, 0x00, + 0x08, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, + 0x02, 0x16, 0x03, 0x01, 0x02, 0x0e, 0x0b, 0x00, + 0x02, 0x0a, 0x00, 0x02, 0x07, 0x00, 0x02, 0x04, + 0x30, 0x82, 0x02, 0x00, 0x30, 0x82, 0x01, 0x62, + 0x02, 0x09, 0x00, 0xb8, 0xbf, 0x2d, 0x47, 0xa0, + 0xd2, 0xeb, 0xf4, 0x30, 0x09, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30, 0x45, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, + 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, + 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x32, 0x31, 0x31, 0x32, 0x32, 0x31, + 0x35, 0x30, 0x36, 0x33, 0x32, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x31, 0x31, 0x32, 0x30, 0x31, 0x35, + 0x30, 0x36, 0x33, 0x32, 0x5a, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9b, 0x30, + 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, + 0x23, 0x03, 0x81, 0x86, 0x00, 0x04, 0x00, 0xc4, + 0xa1, 0xed, 0xbe, 0x98, 0xf9, 0x0b, 0x48, 0x73, + 0x36, 0x7e, 0xc3, 0x16, 0x56, 0x11, 0x22, 0xf2, + 0x3d, 0x53, 0xc3, 0x3b, 0x4d, 0x21, 0x3d, 0xcd, + 0x6b, 0x75, 0xe6, 0xf6, 0xb0, 0xdc, 0x9a, 0xdf, + 0x26, 0xc1, 0xbc, 0xb2, 0x87, 0xf0, 0x72, 0x32, + 0x7c, 0xb3, 0x64, 0x2f, 0x1c, 0x90, 0xbc, 0xea, + 0x68, 0x23, 0x10, 0x7e, 0xfe, 0xe3, 0x25, 0xc0, + 0x48, 0x3a, 0x69, 0xe0, 0x28, 0x6d, 0xd3, 0x37, + 0x00, 0xef, 0x04, 0x62, 0xdd, 0x0d, 0xa0, 0x9c, + 0x70, 0x62, 0x83, 0xd8, 0x81, 0xd3, 0x64, 0x31, + 0xaa, 0x9e, 0x97, 0x31, 0xbd, 0x96, 0xb0, 0x68, + 0xc0, 0x9b, 0x23, 0xde, 0x76, 0x64, 0x3f, 0x1a, + 0x5c, 0x7f, 0xe9, 0x12, 0x0e, 0x58, 0x58, 0xb6, + 0x5f, 0x70, 0xdd, 0x9b, 0xd8, 0xea, 0xd5, 0xd7, + 0xf5, 0xd5, 0xcc, 0xb9, 0xb6, 0x9f, 0x30, 0x66, + 0x5b, 0x66, 0x9a, 0x20, 0xe2, 0x27, 0xe5, 0xbf, + 0xfe, 0x3b, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x81, 0x8c, + 0x00, 0x30, 0x81, 0x88, 0x02, 0x42, 0x01, 0x88, + 0xa2, 0x4f, 0xeb, 0xe2, 0x45, 0xc5, 0x48, 0x7d, + 0x1b, 0xac, 0xf5, 0xed, 0x98, 0x9d, 0xae, 0x47, + 0x70, 0xc0, 0x5e, 0x1b, 0xb6, 0x2f, 0xbd, 0xf1, + 0xb6, 0x4d, 0xb7, 0x61, 0x40, 0xd3, 0x11, 0xa2, + 0xce, 0xee, 0x0b, 0x7e, 0x92, 0x7e, 0xff, 0x76, + 0x9d, 0xc3, 0x3b, 0x7e, 0xa5, 0x3f, 0xce, 0xfa, + 0x10, 0xe2, 0x59, 0xec, 0x47, 0x2d, 0x7c, 0xac, + 0xda, 0x4e, 0x97, 0x0e, 0x15, 0xa0, 0x6f, 0xd0, + 0x02, 0x42, 0x01, 0x4d, 0xfc, 0xbe, 0x67, 0x13, + 0x9c, 0x2d, 0x05, 0x0e, 0xbd, 0x3f, 0xa3, 0x8c, + 0x25, 0xc1, 0x33, 0x13, 0x83, 0x0d, 0x94, 0x06, + 0xbb, 0xd4, 0x37, 0x7a, 0xf6, 0xec, 0x7a, 0xc9, + 0x86, 0x2e, 0xdd, 0xd7, 0x11, 0x69, 0x7f, 0x85, + 0x7c, 0x56, 0xde, 0xfb, 0x31, 0x78, 0x2b, 0xe4, + 0xc7, 0x78, 0x0d, 0xae, 0xcb, 0xbe, 0x9e, 0x4e, + 0x36, 0x24, 0x31, 0x7b, 0x6a, 0x0f, 0x39, 0x95, + 0x12, 0x07, 0x8f, 0x2a, 0x16, 0x03, 0x01, 0x00, + 0xd6, 0x0c, 0x00, 0x00, 0xd2, 0x03, 0x00, 0x17, + 0x41, 0x04, 0x33, 0xed, 0xe1, 0x10, 0x3d, 0xe2, + 0xb0, 0x81, 0x5e, 0x01, 0x1b, 0x00, 0x4a, 0x7d, + 0xdc, 0xc5, 0x78, 0x02, 0xb1, 0x9a, 0x78, 0x92, + 0x34, 0xd9, 0x23, 0xcc, 0x01, 0xfb, 0x0c, 0x49, + 0x1c, 0x4a, 0x59, 0x8a, 0x80, 0x1b, 0x34, 0xf0, + 0xe8, 0x87, 0x1b, 0x7c, 0xfb, 0x72, 0xf5, 0xea, + 0xf9, 0xf3, 0xff, 0xa6, 0x3e, 0x4e, 0xac, 0xbc, + 0xee, 0x14, 0x2b, 0x87, 0xd4, 0x0b, 0xda, 0x19, + 0x60, 0x2b, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02, + 0x42, 0x01, 0x75, 0x46, 0x4f, 0x97, 0x9f, 0xc5, + 0xf9, 0x4c, 0x38, 0xcf, 0x3b, 0x37, 0x1a, 0x6b, + 0x53, 0xfc, 0x05, 0x73, 0x7d, 0x98, 0x2c, 0x5b, + 0x76, 0xd4, 0x37, 0x1f, 0x50, 0x6d, 0xad, 0xc6, + 0x0f, 0x8f, 0x7b, 0xcc, 0x60, 0x8e, 0x04, 0x00, + 0x21, 0x80, 0xa8, 0xa5, 0x98, 0xf2, 0x42, 0xf2, + 0xc3, 0xf6, 0x44, 0x50, 0xc4, 0x7a, 0xae, 0x6f, + 0x74, 0xa0, 0x7f, 0x07, 0x7a, 0x0b, 0xbb, 0x41, + 0x9e, 0x3c, 0x0b, 0x02, 0x42, 0x01, 0xbe, 0x64, + 0xaa, 0x12, 0x03, 0xfb, 0xd8, 0x4f, 0x93, 0xf9, + 0x92, 0x54, 0x0d, 0x9c, 0x9d, 0x53, 0x88, 0x19, + 0x69, 0x94, 0xfc, 0xd6, 0xf7, 0x60, 0xcf, 0x70, + 0x64, 0x15, 0x1b, 0x02, 0x22, 0x56, 0xb0, 0x2c, + 0xb1, 0x72, 0x4c, 0x9e, 0x7b, 0xf0, 0x53, 0x97, + 0x43, 0xac, 0x11, 0x62, 0xe5, 0x5a, 0xf1, 0x7e, + 0x87, 0x8f, 0x5c, 0x43, 0x1d, 0xae, 0x56, 0x28, + 0xdb, 0x76, 0x15, 0xd8, 0x1c, 0x73, 0xce, 0x16, + 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x46, 0x10, 0x00, 0x00, + 0x42, 0x41, 0x04, 0x1e, 0x18, 0x37, 0xef, 0x0d, + 0x19, 0x51, 0x88, 0x35, 0x75, 0x71, 0xb5, 0xe5, + 0x54, 0x5b, 0x12, 0x2e, 0x8f, 0x09, 0x67, 0xfd, + 0xa7, 0x24, 0x20, 0x3e, 0xb2, 0x56, 0x1c, 0xce, + 0x97, 0x28, 0x5e, 0xf8, 0x2b, 0x2d, 0x4f, 0x9e, + 0xf1, 0x07, 0x9f, 0x6c, 0x4b, 0x5b, 0x83, 0x56, + 0xe2, 0x32, 0x42, 0xe9, 0x58, 0xb6, 0xd7, 0x49, + 0xa6, 0xb5, 0x68, 0x1a, 0x41, 0x03, 0x56, 0x6b, + 0xdc, 0x5a, 0x89, 0x14, 0x03, 0x01, 0x00, 0x01, + 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x1a, 0x45, + 0x92, 0x3b, 0xac, 0x8d, 0x91, 0x89, 0xd3, 0x2c, + 0xf4, 0x3c, 0x5f, 0x70, 0xf1, 0x79, 0xa5, 0x6a, + 0xcf, 0x97, 0x8f, 0x3f, 0x73, 0x08, 0xca, 0x3f, + 0x55, 0xb0, 0x28, 0xd1, 0x6f, 0xcd, 0x9b, 0xca, + 0xb6, 0xb7, 0xd0, 0xa5, 0x21, 0x5b, 0x08, 0xf8, + 0x42, 0xe2, 0xdf, 0x25, 0x6a, 0x16, + }, + { + 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, + 0x01, 0x00, 0x30, 0x30, 0x83, 0xb6, 0x51, 0x8a, + 0x85, 0x4a, 0xee, 0xe4, 0xb6, 0xae, 0xf3, 0xc1, + 0xdc, 0xd2, 0x04, 0xb3, 0xd0, 0x25, 0x47, 0x5f, + 0xac, 0x83, 0xa3, 0x7d, 0xcf, 0x47, 0x92, 0xed, + 0x92, 0x6c, 0xd1, 0x6e, 0xfd, 0x63, 0xf5, 0x2d, + 0x89, 0xd8, 0x04, 0x8c, 0x62, 0x71, 0xae, 0x5e, + 0x32, 0x48, 0xf8, + }, + { + 0x17, 0x03, 0x01, 0x00, 0x20, 0xcf, 0x5e, 0xba, + 0xf4, 0x47, 0x32, 0x35, 0x9b, 0x85, 0xdc, 0xb3, + 0xff, 0x77, 0x90, 0xd9, 0x2b, 0xbd, 0x59, 0x2a, + 0x33, 0xe4, 0x6e, 0x9b, 0xfc, 0x1c, 0x73, 0x3f, + 0x5e, 0x1e, 0xe3, 0xa4, 0xc2, 0x17, 0x03, 0x01, + 0x00, 0x20, 0x05, 0xdf, 0x2d, 0x9b, 0x29, 0x7f, + 0x97, 0xcd, 0x49, 0x04, 0x53, 0x22, 0x1a, 0xa1, + 0xa1, 0xe6, 0x38, 0x3a, 0x56, 0x37, 0x1f, 0xd8, + 0x3a, 0x12, 0x2c, 0xf0, 0xeb, 0x61, 0x35, 0x76, + 0xe5, 0xf0, 0x15, 0x03, 0x01, 0x00, 0x20, 0xa5, + 0x56, 0xb5, 0x49, 0x4b, 0xc2, 0xd4, 0x4c, 0xf6, + 0x95, 0x15, 0x7d, 0x41, 0x1d, 0x5c, 0x00, 0x0e, + 0x20, 0xb1, 0x0a, 0xbc, 0xc9, 0x2a, 0x09, 0x17, + 0xb4, 0xaa, 0x1c, 0x79, 0xda, 0x79, 0x27, + }, +} diff --git a/libgo/go/crypto/tls/handshake_messages.go b/libgo/go/crypto/tls/handshake_messages.go index cdd49170777..83952000f6e 100644 --- a/libgo/go/crypto/tls/handshake_messages.go +++ b/libgo/go/crypto/tls/handshake_messages.go @@ -20,6 +20,7 @@ type clientHelloMsg struct { supportedPoints []uint8 ticketSupported bool sessionTicket []uint8 + signatureAndHashes []signatureAndHash } func (m *clientHelloMsg) equal(i interface{}) bool { @@ -40,7 +41,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool { eqUint16s(m.supportedCurves, m1.supportedCurves) && bytes.Equal(m.supportedPoints, m1.supportedPoints) && m.ticketSupported == m1.ticketSupported && - bytes.Equal(m.sessionTicket, m1.sessionTicket) + bytes.Equal(m.sessionTicket, m1.sessionTicket) && + eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) } func (m *clientHelloMsg) marshal() []byte { @@ -74,6 +76,10 @@ func (m *clientHelloMsg) marshal() []byte { extensionsLength += len(m.sessionTicket) numExtensions++ } + if len(m.signatureAndHashes) > 0 { + extensionsLength += 2 + 2*len(m.signatureAndHashes) + numExtensions++ + } if numExtensions > 0 { extensionsLength += 4 * numExtensions length += 2 + extensionsLength @@ -199,6 +205,25 @@ func (m *clientHelloMsg) marshal() []byte { copy(z, m.sessionTicket) z = z[len(m.sessionTicket):] } + if len(m.signatureAndHashes) > 0 { + // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + z[0] = byte(extensionSignatureAlgorithms >> 8) + z[1] = byte(extensionSignatureAlgorithms) + l := 2 + 2*len(m.signatureAndHashes) + z[2] = byte(l >> 8) + z[3] = byte(l) + z = z[4:] + + l -= 2 + z[0] = byte(l >> 8) + z[1] = byte(l) + z = z[2:] + for _, sigAndHash := range m.signatureAndHashes { + z[0] = sigAndHash.hash + z[1] = sigAndHash.signature + z = z[2:] + } + } m.raw = x @@ -249,6 +274,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { m.ocspStapling = false m.ticketSupported = false m.sessionTicket = nil + m.signatureAndHashes = nil if len(data) == 0 { // ClientHello is optionally followed by extension data @@ -336,6 +362,23 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { // http://tools.ietf.org/html/rfc5077#section-3.2 m.ticketSupported = true m.sessionTicket = data[:length] + case extensionSignatureAlgorithms: + // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + if length < 2 || length&1 != 0 { + return false + } + l := int(data[0])<<8 | int(data[1]) + if l != length-2 { + return false + } + n := l / 2 + d := data[2:] + m.signatureAndHashes = make([]signatureAndHash, n) + for i := range m.signatureAndHashes { + m.signatureAndHashes[i].hash = d[0] + m.signatureAndHashes[i].signature = d[1] + d = d[2:] + } } data = data[length:] } @@ -899,8 +942,14 @@ func (m *nextProtoMsg) unmarshal(data []byte) bool { } type certificateRequestMsg struct { - raw []byte + raw []byte + // hasSignatureAndHash indicates whether this message includes a list + // of signature and hash functions. This change was introduced with TLS + // 1.2. + hasSignatureAndHash bool + certificateTypes []byte + signatureAndHashes []signatureAndHash certificateAuthorities [][]byte } @@ -912,7 +961,8 @@ func (m *certificateRequestMsg) equal(i interface{}) bool { return bytes.Equal(m.raw, m1.raw) && bytes.Equal(m.certificateTypes, m1.certificateTypes) && - eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) + eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) && + eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) } func (m *certificateRequestMsg) marshal() (x []byte) { @@ -928,6 +978,10 @@ func (m *certificateRequestMsg) marshal() (x []byte) { } length += casLength + if m.hasSignatureAndHash { + length += 2 + 2*len(m.signatureAndHashes) + } + x = make([]byte, 4+length) x[0] = typeCertificateRequest x[1] = uint8(length >> 16) @@ -938,6 +992,19 @@ func (m *certificateRequestMsg) marshal() (x []byte) { copy(x[5:], m.certificateTypes) y := x[5+len(m.certificateTypes):] + + if m.hasSignatureAndHash { + n := len(m.signatureAndHashes) * 2 + y[0] = uint8(n >> 8) + y[1] = uint8(n) + y = y[2:] + for _, sigAndHash := range m.signatureAndHashes { + y[0] = sigAndHash.hash + y[1] = sigAndHash.signature + y = y[2:] + } + } + y[0] = uint8(casLength >> 8) y[1] = uint8(casLength) y = y[2:] @@ -978,6 +1045,27 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool { data = data[numCertTypes:] + if m.hasSignatureAndHash { + if len(data) < 2 { + return false + } + sigAndHashLen := uint16(data[0])<<8 | uint16(data[1]) + data = data[2:] + if sigAndHashLen&1 != 0 { + return false + } + if len(data) < int(sigAndHashLen) { + return false + } + numSigAndHash := sigAndHashLen / 2 + m.signatureAndHashes = make([]signatureAndHash, numSigAndHash) + for i := range m.signatureAndHashes { + m.signatureAndHashes[i].hash = data[0] + m.signatureAndHashes[i].signature = data[1] + data = data[2:] + } + } + if len(data) < 2 { return false } @@ -1013,8 +1101,10 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool { } type certificateVerifyMsg struct { - raw []byte - signature []byte + raw []byte + hasSignatureAndHash bool + signatureAndHash signatureAndHash + signature []byte } func (m *certificateVerifyMsg) equal(i interface{}) bool { @@ -1024,6 +1114,9 @@ func (m *certificateVerifyMsg) equal(i interface{}) bool { } return bytes.Equal(m.raw, m1.raw) && + m.hasSignatureAndHash == m1.hasSignatureAndHash && + m.signatureAndHash.hash == m1.signatureAndHash.hash && + m.signatureAndHash.signature == m1.signatureAndHash.signature && bytes.Equal(m.signature, m1.signature) } @@ -1035,14 +1128,23 @@ func (m *certificateVerifyMsg) marshal() (x []byte) { // See http://tools.ietf.org/html/rfc4346#section-7.4.8 siglength := len(m.signature) length := 2 + siglength + if m.hasSignatureAndHash { + length += 2 + } x = make([]byte, 4+length) x[0] = typeCertificateVerify x[1] = uint8(length >> 16) x[2] = uint8(length >> 8) x[3] = uint8(length) - x[4] = uint8(siglength >> 8) - x[5] = uint8(siglength) - copy(x[6:], m.signature) + y := x[4:] + if m.hasSignatureAndHash { + y[0] = m.signatureAndHash.hash + y[1] = m.signatureAndHash.signature + y = y[2:] + } + y[0] = uint8(siglength >> 8) + y[1] = uint8(siglength) + copy(y[2:], m.signature) m.raw = x @@ -1061,12 +1163,23 @@ func (m *certificateVerifyMsg) unmarshal(data []byte) bool { return false } - siglength := int(data[4])<<8 + int(data[5]) - if len(data)-6 != siglength { + data = data[4:] + if m.hasSignatureAndHash { + m.signatureAndHash.hash = data[0] + m.signatureAndHash.signature = data[1] + data = data[2:] + } + + if len(data) < 2 { + return false + } + siglength := int(data[0])<<8 + int(data[1]) + data = data[2:] + if len(data) != siglength { return false } - m.signature = data[6:] + m.signature = data return true } @@ -1165,3 +1278,16 @@ func eqByteSlices(x, y [][]byte) bool { } return true } + +func eqSignatureAndHashes(x, y []signatureAndHash) bool { + if len(x) != len(y) { + return false + } + for i, v := range x { + v2 := y[i] + if v.hash != v2.hash || v.signature != v2.signature { + return false + } + } + return true +} diff --git a/libgo/go/crypto/tls/handshake_messages_test.go b/libgo/go/crypto/tls/handshake_messages_test.go index 3434bad9fba..4f569eeb138 100644 --- a/libgo/go/crypto/tls/handshake_messages_test.go +++ b/libgo/go/crypto/tls/handshake_messages_test.go @@ -135,6 +135,9 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { m.sessionTicket = randomBytes(rand.Intn(300), rand) } } + if rand.Intn(10) > 5 { + m.signatureAndHashes = supportedSKXSignatureAlgorithms + } return reflect.ValueOf(m) } diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index 823730c605c..c9ccf675cd8 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -6,9 +6,11 @@ package tls import ( "crypto" + "crypto/ecdsa" "crypto/rsa" "crypto/subtle" "crypto/x509" + "encoding/asn1" "errors" "io" ) @@ -21,10 +23,12 @@ type serverHandshakeState struct { hello *serverHelloMsg suite *cipherSuite ellipticOk bool + ecdsaOk bool sessionState *sessionState finishedHash finishedHash masterSecret []byte certsFromClient [][]byte + cert *Certificate } // serverHandshake performs a TLS handshake as a server. @@ -98,7 +102,7 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) { if !ok { return false, c.sendAlert(alertUnexpectedMessage) } - c.vers, ok = mutualVersion(hs.clientHello.vers) + c.vers, ok = config.mutualVersion(hs.clientHello.vers) if !ok { return false, c.sendAlert(alertProtocolVersion) } @@ -156,11 +160,25 @@ Curves: if len(hs.clientHello.serverName) > 0 { c.serverName = hs.clientHello.serverName } - if hs.clientHello.nextProtoNeg { + // Although sending an empty NPN extension is reasonable, Firefox has + // had a bug around this. Best to send nothing at all if + // config.NextProtos is empty. See + // https://code.google.com/p/go/issues/detail?id=5445. + if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 { hs.hello.nextProtoNeg = true hs.hello.nextProtos = config.NextProtos } + if len(config.Certificates) == 0 { + return false, c.sendAlert(alertInternalError) + } + hs.cert = &config.Certificates[0] + if len(hs.clientHello.serverName) > 0 { + hs.cert = config.getCertificateForName(hs.clientHello.serverName) + } + + _, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey) + if hs.checkForResumption() { return true, nil } @@ -175,7 +193,7 @@ Curves: } for _, id := range preferenceList { - if hs.suite = c.tryCipherSuite(id, supportedList, hs.ellipticOk); hs.suite != nil { + if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil { break } } @@ -199,7 +217,7 @@ func (hs *serverHandshakeState) checkForResumption() bool { if hs.sessionState.vers > hs.clientHello.vers { return false } - if vers, ok := mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers { + if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers { return false } @@ -216,7 +234,7 @@ func (hs *serverHandshakeState) checkForResumption() bool { } // Check that we also support the ciphersuite from the session. - hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.ellipticOk) + hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk) if hs.suite == nil { return false } @@ -258,15 +276,7 @@ func (hs *serverHandshakeState) doFullHandshake() error { config := hs.c.config c := hs.c - if len(config.Certificates) == 0 { - return c.sendAlert(alertInternalError) - } - cert := &config.Certificates[0] - if len(hs.clientHello.serverName) > 0 { - cert = config.getCertificateForName(hs.clientHello.serverName) - } - - if hs.clientHello.ocspStapling && len(cert.OCSPStaple) > 0 { + if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { hs.hello.ocspStapling = true } @@ -276,20 +286,20 @@ func (hs *serverHandshakeState) doFullHandshake() error { c.writeRecord(recordTypeHandshake, hs.hello.marshal()) certMsg := new(certificateMsg) - certMsg.certificates = cert.Certificate + certMsg.certificates = hs.cert.Certificate hs.finishedHash.Write(certMsg.marshal()) c.writeRecord(recordTypeHandshake, certMsg.marshal()) if hs.hello.ocspStapling { certStatus := new(certificateStatusMsg) certStatus.statusType = statusTypeOCSP - certStatus.response = cert.OCSPStaple + certStatus.response = hs.cert.OCSPStaple hs.finishedHash.Write(certStatus.marshal()) c.writeRecord(recordTypeHandshake, certStatus.marshal()) } - keyAgreement := hs.suite.ka() - skx, err := keyAgreement.generateServerKeyExchange(config, cert, hs.clientHello, hs.hello) + keyAgreement := hs.suite.ka(c.vers) + skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello) if err != nil { c.sendAlert(alertHandshakeFailure) return err @@ -302,7 +312,14 @@ func (hs *serverHandshakeState) doFullHandshake() error { if config.ClientAuth >= RequestClientCert { // Request a client certificate certReq := new(certificateRequestMsg) - certReq.certificateTypes = []byte{certTypeRSASign} + certReq.certificateTypes = []byte{ + byte(certTypeRSASign), + byte(certTypeECDSASign), + } + if c.vers >= VersionTLS12 { + certReq.hasSignatureAndHash = true + certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms + } // An empty list of certificateAuthorities signals to // the client that it may send any certificate in response @@ -320,7 +337,7 @@ func (hs *serverHandshakeState) doFullHandshake() error { hs.finishedHash.Write(helloDone.marshal()) c.writeRecord(recordTypeHandshake, helloDone.marshal()) - var pub *rsa.PublicKey // public key for client auth, if any + var pub crypto.PublicKey // public key for client auth, if any msg, err := c.readHandshake() if err != nil { @@ -365,7 +382,7 @@ func (hs *serverHandshakeState) doFullHandshake() error { // If we received a client cert in response to our certificate request message, // the client will send us a certificateVerifyMsg immediately after the - // clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preceding + // clientKeyExchangeMsg. This message is a digest of all preceding // handshake-layer messages that is signed using the private key corresponding // to the client's certificate. This allows us to verify that the client is in // possession of the private key of the certificate. @@ -379,10 +396,25 @@ func (hs *serverHandshakeState) doFullHandshake() error { return c.sendAlert(alertUnexpectedMessage) } - digest := make([]byte, 0, 36) - digest = hs.finishedHash.serverMD5.Sum(digest) - digest = hs.finishedHash.serverSHA1.Sum(digest) - err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature) + switch key := pub.(type) { + case *ecdsa.PublicKey: + 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("ECDSA signature contained zero or negative values") + break + } + digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA) + if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) { + err = errors.New("ECDSA verification failure") + break + } + case *rsa.PublicKey: + digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA) + err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature) + } if err != nil { c.sendAlert(alertBadCertificate) return errors.New("could not validate signature of connection nonces: " + err.Error()) @@ -391,7 +423,7 @@ func (hs *serverHandshakeState) doFullHandshake() error { hs.finishedHash.Write(certVerify.marshal()) } - preMasterSecret, err := keyAgreement.processClientKeyExchange(config, cert, ckx, c.vers) + preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers) if err != nil { c.sendAlert(alertHandshakeFailure) return err @@ -407,12 +439,20 @@ func (hs *serverHandshakeState) establishKeys() error { clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - clientCipher := hs.suite.cipher(clientKey, clientIV, true /* for reading */) - clientHash := hs.suite.mac(c.vers, clientMAC) - c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) + var clientCipher, serverCipher interface{} + var clientHash, serverHash macFunction - serverCipher := hs.suite.cipher(serverKey, serverIV, false /* not for reading */) - serverHash := hs.suite.mac(c.vers, serverMAC) + if hs.suite.aead == nil { + clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) + clientHash = hs.suite.mac(c.vers, clientMAC) + serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) + serverHash = hs.suite.mac(c.vers, serverMAC) + } else { + clientCipher = hs.suite.aead(clientKey, clientIV) + serverCipher = hs.suite.aead(serverKey, serverIV) + } + + c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) return nil @@ -502,7 +542,7 @@ func (hs *serverHandshakeState) sendFinished() error { // processCertsFromClient takes a chain of client certificates either from a // Certificates message or from a sessionState and verifies them. It returns // the public key of the leaf certificate. -func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (*rsa.PublicKey, error) { +func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) { c := hs.c hs.certsFromClient = certificates @@ -549,8 +589,11 @@ func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (* } if len(certs) > 0 { - pub, ok := certs[0].PublicKey.(*rsa.PublicKey) - if !ok { + var pub crypto.PublicKey + switch key := certs[0].PublicKey.(type) { + case *ecdsa.PublicKey, *rsa.PublicKey: + pub = key + default: return nil, c.sendAlert(alertUnsupportedCertificate) } c.peerCertificates = certs @@ -562,7 +605,7 @@ func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (* // tryCipherSuite returns a cipherSuite with the given id if that cipher suite // is acceptable to use. -func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, ellipticOk bool) *cipherSuite { +func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite { for _, supported := range supportedCipherSuites { if id == supported { var candidate *cipherSuite @@ -578,7 +621,13 @@ func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, ellipti } // Don't select a ciphersuite which we can't // support for this client. - if candidate.elliptic && !ellipticOk { + if (candidate.flags&suiteECDHE != 0) && !ellipticOk { + continue + } + if (candidate.flags&suiteECDSA != 0) != ecdsaOk { + continue + } + if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { continue } return candidate diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index bf8cbe3ae6b..c08eba7f17c 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -6,6 +6,8 @@ package tls import ( "bytes" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rsa" "crypto/x509" "encoding/hex" @@ -41,13 +43,15 @@ func init() { testConfig.Time = func() time.Time { return time.Unix(0, 0) } testConfig.Rand = zeroSource{} testConfig.Certificates = make([]Certificate, 2) - testConfig.Certificates[0].Certificate = [][]byte{testCertificate} - testConfig.Certificates[0].PrivateKey = testPrivateKey + testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate} + testConfig.Certificates[0].PrivateKey = testRSAPrivateKey testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate} - testConfig.Certificates[1].PrivateKey = testPrivateKey + testConfig.Certificates[1].PrivateKey = testRSAPrivateKey testConfig.BuildNameToCertificate() testConfig.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA} testConfig.InsecureSkipVerify = true + testConfig.MinVersion = VersionSSL30 + testConfig.MaxVersion = VersionTLS10 } func testClientHelloFailure(t *testing.T, m handshakeMessage, expected error) { @@ -100,6 +104,53 @@ func TestNoCompressionOverlap(t *testing.T) { testClientHelloFailure(t, clientHello, alertHandshakeFailure) } +func TestTLS12OnlyCipherSuites(t *testing.T) { + // Test that a Server doesn't select a TLS 1.2-only cipher suite when + // the client negotiates TLS 1.1. + var zeros [32]byte + + clientHello := &clientHelloMsg{ + vers: VersionTLS11, + random: zeros[:], + cipherSuites: []uint16{ + // The Server, by default, will use the client's + // preference order. So the GCM cipher suite + // will be selected unless it's excluded because + // of the version in this ClientHello. + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_RC4_128_SHA, + }, + compressionMethods: []uint8{compressionNone}, + supportedCurves: []uint16{curveP256, curveP384, curveP521}, + supportedPoints: []uint8{pointFormatUncompressed}, + } + + c, s := net.Pipe() + var reply interface{} + var clientErr error + go func() { + cli := Client(c, testConfig) + cli.vers = clientHello.vers + cli.writeRecord(recordTypeHandshake, clientHello.marshal()) + reply, clientErr = cli.readHandshake() + c.Close() + }() + config := *testConfig + config.CipherSuites = clientHello.cipherSuites + Server(s, &config).Handshake() + s.Close() + if clientErr != nil { + t.Fatal(clientErr) + } + serverHello, ok := reply.(*serverHelloMsg) + if !ok { + t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply) + } + if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA { + t.Fatalf("bad cipher suite from server: %x", s) + } +} + func TestAlertForwarding(t *testing.T) { c, s := net.Pipe() go func() { @@ -110,7 +161,7 @@ func TestAlertForwarding(t *testing.T) { err := Server(s, testConfig).Handshake() s.Close() if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) { - t.Errorf("Got error: %s; expected: %s", err, alertUnknownCA) + t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA)) } } @@ -145,6 +196,7 @@ func TestCipherSuitePreference(t *testing.T) { serverConfig := &Config{ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, Certificates: testConfig.Certificates, + MaxVersion: VersionTLS11, } clientConfig := &Config{ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA}, @@ -211,22 +263,33 @@ func testServerScript(t *testing.T, name string, serverScript [][]byte, config * } } -func TestHandshakeServerRC4(t *testing.T) { - testServerScript(t, "RC4", rc4ServerScript, testConfig, nil) +func TestHandshakeServerRSARC4(t *testing.T) { + testServerScript(t, "RSA-RC4", rsaRC4ServerScript, testConfig, nil) } -func TestHandshakeServer3DES(t *testing.T) { +func TestHandshakeServerRSA3DES(t *testing.T) { des3Config := new(Config) *des3Config = *testConfig des3Config.CipherSuites = []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA} - testServerScript(t, "3DES", des3ServerScript, des3Config, nil) + testServerScript(t, "RSA-3DES", rsaDES3ServerScript, des3Config, nil) } -func TestHandshakeServerAES(t *testing.T) { +func TestHandshakeServerRSAAES(t *testing.T) { aesConfig := new(Config) *aesConfig = *testConfig aesConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_CBC_SHA} - testServerScript(t, "AES", aesServerScript, aesConfig, nil) + testServerScript(t, "RSA-AES", rsaAESServerScript, aesConfig, nil) +} + +func TestHandshakeServerECDHEECDSAAES(t *testing.T) { + ecdsaConfig := new(Config) + *ecdsaConfig = *testConfig + ecdsaConfig.Certificates = make([]Certificate, 1) + ecdsaConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate} + ecdsaConfig.Certificates[0].PrivateKey = testECDSAPrivateKey + ecdsaConfig.BuildNameToCertificate() + ecdsaConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} + testServerScript(t, "ECDHE-ECDSA-AES", ecdheECDSAAESServerScript, ecdsaConfig, nil) } func TestHandshakeServerSSLv3(t *testing.T) { @@ -245,6 +308,15 @@ func TestResumption(t *testing.T) { testServerScript(t, "Resume", serverResumeTest, testConfig, nil) } +func TestTLS12ClientCertServer(t *testing.T) { + config := *testConfig + config.MaxVersion = VersionTLS12 + config.ClientAuth = RequireAnyClientCert + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA} + + testServerScript(t, "TLS12", tls12ServerScript, &config, nil) +} + type clientauthTest struct { name string clientauth ClientAuthType @@ -252,16 +324,67 @@ type clientauthTest struct { script [][]byte } -func TestClientAuth(t *testing.T) { - for _, cat := range clientauthTests { +func TestClientAuthRSA(t *testing.T) { + for _, cat := range clientauthRSATests { + t.Log("running", cat.name) + cfg := new(Config) + *cfg = *testConfig + cfg.ClientAuth = cat.clientauth + testServerScript(t, cat.name, cat.script, cfg, cat.peers) + } +} + +func TestClientAuthECDSA(t *testing.T) { + for _, cat := range clientauthECDSATests { t.Log("running", cat.name) cfg := new(Config) *cfg = *testConfig + cfg.Certificates = make([]Certificate, 1) + cfg.Certificates[0].Certificate = [][]byte{testECDSACertificate} + cfg.Certificates[0].PrivateKey = testECDSAPrivateKey + cfg.BuildNameToCertificate() + cfg.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} cfg.ClientAuth = cat.clientauth testServerScript(t, cat.name, cat.script, cfg, cat.peers) } } +// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with +// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate. +func TestCipherSuiteCertPreferance(t *testing.T) { + var config = *testConfig + config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} + config.MaxVersion = VersionTLS11 + config.PreferServerCipherSuites = true + testServerScript(t, "CipherSuiteCertPreference", tls11ECDHEAESServerScript, &config, nil) + + config = *testConfig + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} + config.Certificates = []Certificate{ + Certificate{ + Certificate: [][]byte{testECDSACertificate}, + PrivateKey: testECDSAPrivateKey, + }, + } + config.BuildNameToCertificate() + config.PreferServerCipherSuites = true + testServerScript(t, "CipherSuiteCertPreference2", ecdheECDSAAESServerScript, &config, nil) +} + +func TestTLS11Server(t *testing.T) { + var config = *testConfig + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA} + config.MaxVersion = VersionTLS11 + testServerScript(t, "TLS11", tls11ECDHEAESServerScript, &config, nil) +} + +func TestAESGCM(t *testing.T) { + var config = *testConfig + config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256} + config.MaxVersion = VersionTLS12 + testServerScript(t, "AES-GCM", aesGCMServerScript, &config, nil) +} + // recordingConn is a net.Conn that records the traffic that passes through it. // WriteTo can be used to produce Go code that contains the recorded traffic. type recordingConn struct { @@ -331,10 +454,28 @@ var serve = flag.Bool("serve", false, "run a TLS server on :10443") var testCipherSuites = flag.String("ciphersuites", "0x"+strconv.FormatInt(int64(TLS_RSA_WITH_RC4_128_SHA), 16), "cipher suites to accept in serving mode") +var testMinVersion = flag.String("minversion", + "0x"+strconv.FormatInt(int64(VersionSSL30), 16), + "minimum version to negotiate") +var testMaxVersion = flag.String("maxversion", + "0x"+strconv.FormatInt(int64(VersionTLS10), 16), + "maximum version to negotiate") var testClientAuth = flag.Int("clientauth", 0, "value for tls.Config.ClientAuth") func GetTestConfig() *Config { var config = *testConfig + + minVersion, err := strconv.ParseUint(*testMinVersion, 0, 64) + if err != nil { + panic(err) + } + config.MinVersion = uint16(minVersion) + maxVersion, err := strconv.ParseUint(*testMaxVersion, 0, 64) + if err != nil { + panic(err) + } + config.MaxVersion = uint16(maxVersion) + suites := strings.Split(*testCipherSuites, ",") config.CipherSuites = make([]uint16, len(suites)) for i := range suites { @@ -345,6 +486,25 @@ func GetTestConfig() *Config { config.CipherSuites[i] = uint16(suite) } + ecdsa := false + for _, suite := range config.CipherSuites { + switch suite { + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + ecdsa = true + } + } + if ecdsa { + config.Certificates = nil + if !*connect { + config.Certificates = make([]Certificate, 1) + config.Certificates[0].Certificate = [][]byte{testECDSACertificate} + config.Certificates[0].PrivateKey = testECDSAPrivateKey + } + config.BuildNameToCertificate() + } + config.ClientAuth = ClientAuthType(*testClientAuth) return &config } @@ -403,11 +563,13 @@ func fromHex(s string) []byte { return b } -var testCertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9") +var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9") + +var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186000400c4a1edbe98f90b4873367ec316561122f23d53c33b4d213dcd6b75e6f6b0dc9adf26c1bcb287f072327cb3642f1c90bcea6823107efee325c0483a69e0286dd33700ef0462dd0da09c706283d881d36431aa9e9731bd96b068c09b23de76643f1a5c7fe9120e5858b65f70dd9bd8ead5d7f5d5ccb9b69f30665b669a20e227e5bffe3b300906072a8648ce3d040103818c0030818802420188a24febe245c5487d1bacf5ed989dae4770c05e1bb62fbdf1b64db76140d311a2ceee0b7e927eff769dc33b7ea53fcefa10e259ec472d7cacda4e970e15a06fd00242014dfcbe67139c2d050ebd3fa38c25c13313830d9406bbd4377af6ec7ac9862eddd711697f857c56defb31782be4c7780daecbbe9e4e3624317b6a0f399512078f2a") var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a864886f70d01010530283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d301e170d3132303431313137343033355a170d3133303431313137343533355a30283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d30819d300b06092a864886f70d01010103818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a3323030300e0603551d0f0101ff0404030200a0300d0603551d0e0406040401020304300f0603551d2304083006800401020304300b06092a864886f70d0101050381810089c6455f1c1f5ef8eb1ab174ee2439059f5c4259bb1a8d86cdb1d056f56a717da40e95ab90f59e8deaf627c157995094db0802266eb34fc6842dea8a4b68d9c1389103ab84fb9e1f85d9b5d23ff2312c8670fbb540148245a4ebafe264d90c8a4cf4f85b0fac12ac2fc4a3154bad52462868af96c62c6525d652b6e31845bdcc") -var testPrivateKey = &rsa.PrivateKey{ +var testRSAPrivateKey = &rsa.PrivateKey{ PublicKey: rsa.PublicKey{ N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"), E: 65537, @@ -419,6 +581,22 @@ var testPrivateKey = &rsa.PrivateKey{ }, } +var testECDSAPrivateKey = &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: &elliptic.CurveParams{ + P: bigFromString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), + N: bigFromString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449"), + B: bigFromString("1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984"), + Gx: bigFromString("2661740802050217063228768716723360960729859168756973147706671368418802944996427808491545080627771902352094241225065558662157113545570916814161637315895999846"), + Gy: bigFromString("3757180025770020463545507224491183603594455134769762486694567779615544477440556316691234405012945539562144444537289428522585666729196580810124344277578376784"), + BitSize: 521, + }, + X: bigFromString("2636411247892461147287360222306590634450676461695221912739908880441342231985950069527906976759812296359387337367668045707086543273113073382714101597903639351"), + Y: bigFromString("3204695818431246682253994090650952614555094516658732116404513121125038617915183037601737180082382202488628239201196033284060130040574800684774115478859677243"), + }, + D: bigFromString("5477294338614160138026852784385529180817726002953041720191098180813046231640184669647735805135001309477695746518160084669446643325196003346204701381388769751"), +} + func loadPEMCert(in string) *x509.Certificate { block, _ := pem.Decode([]byte(in)) if block.Type == "CERTIFICATE" && len(block.Headers) == 0 { @@ -435,7 +613,7 @@ func loadPEMCert(in string) *x509.Certificate { // The values for this test are obtained by building and running in server mode: // % go test -test.run "TestRunServer" -serve // The recorded bytes are written to stdout. -var rc4ServerScript = [][]byte{ +var rsaRC4ServerScript = [][]byte{ { 0x16, 0x03, 0x01, 0x00, 0x54, 0x01, 0x00, 0x00, 0x50, 0x03, 0x01, 0x50, 0x77, 0x3d, 0xbd, 0x32, @@ -592,7 +770,7 @@ var rc4ServerScript = [][]byte{ }, } -var des3ServerScript = [][]byte{ +var rsaDES3ServerScript = [][]byte{ { 0x16, 0x03, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x00, 0xc1, 0x03, 0x03, 0x50, 0xae, 0x5d, 0x38, 0xec, @@ -801,7 +979,7 @@ var des3ServerScript = [][]byte{ }, } -var aesServerScript = [][]byte{ +var rsaAESServerScript = [][]byte{ { 0x16, 0x03, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x00, 0xc1, 0x03, 0x03, 0x50, 0xae, 0x5c, 0xe9, 0x5e, @@ -1027,6 +1205,216 @@ var aesServerScript = [][]byte{ }, } +// Generated using: +// $ go test -test.run TestRunServer -serve -ciphersuites=0xc00a +// $ openssl s_client -host 127.0.0.1 -port 10443 -cipher ECDHE-ECDSA-AES256-SHA +var ecdheECDSAAESServerScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x9c, 0x03, 0x03, 0x50, 0xd7, 0x18, 0x31, 0x49, + 0xde, 0x19, 0x8d, 0x08, 0x5c, 0x4b, 0x60, 0x67, + 0x0f, 0xfe, 0xd0, 0x62, 0xf9, 0x31, 0x48, 0x17, + 0x9e, 0x50, 0xc1, 0xd8, 0x35, 0x24, 0x0e, 0xa6, + 0x09, 0x06, 0x51, 0x00, 0x00, 0x04, 0xc0, 0x0a, + 0x00, 0xff, 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, + 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, + 0x00, 0x34, 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, + 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, + 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, + 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, + 0x00, 0x15, 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, + 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, + 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, + 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, + 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, + 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, + 0x00, 0x0f, 0x00, 0x01, 0x01, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0a, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, + 0x02, 0x0e, 0x0b, 0x00, 0x02, 0x0a, 0x00, 0x02, + 0x07, 0x00, 0x02, 0x04, 0x30, 0x82, 0x02, 0x00, + 0x30, 0x82, 0x01, 0x62, 0x02, 0x09, 0x00, 0xb8, + 0xbf, 0x2d, 0x47, 0xa0, 0xd2, 0xeb, 0xf4, 0x30, + 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x04, 0x01, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x31, + 0x31, 0x32, 0x32, 0x31, 0x35, 0x30, 0x36, 0x33, + 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x31, 0x31, + 0x32, 0x30, 0x31, 0x35, 0x30, 0x36, 0x33, 0x32, + 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, + 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, + 0x30, 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, + 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, + 0x00, 0x04, 0x00, 0xc4, 0xa1, 0xed, 0xbe, 0x98, + 0xf9, 0x0b, 0x48, 0x73, 0x36, 0x7e, 0xc3, 0x16, + 0x56, 0x11, 0x22, 0xf2, 0x3d, 0x53, 0xc3, 0x3b, + 0x4d, 0x21, 0x3d, 0xcd, 0x6b, 0x75, 0xe6, 0xf6, + 0xb0, 0xdc, 0x9a, 0xdf, 0x26, 0xc1, 0xbc, 0xb2, + 0x87, 0xf0, 0x72, 0x32, 0x7c, 0xb3, 0x64, 0x2f, + 0x1c, 0x90, 0xbc, 0xea, 0x68, 0x23, 0x10, 0x7e, + 0xfe, 0xe3, 0x25, 0xc0, 0x48, 0x3a, 0x69, 0xe0, + 0x28, 0x6d, 0xd3, 0x37, 0x00, 0xef, 0x04, 0x62, + 0xdd, 0x0d, 0xa0, 0x9c, 0x70, 0x62, 0x83, 0xd8, + 0x81, 0xd3, 0x64, 0x31, 0xaa, 0x9e, 0x97, 0x31, + 0xbd, 0x96, 0xb0, 0x68, 0xc0, 0x9b, 0x23, 0xde, + 0x76, 0x64, 0x3f, 0x1a, 0x5c, 0x7f, 0xe9, 0x12, + 0x0e, 0x58, 0x58, 0xb6, 0x5f, 0x70, 0xdd, 0x9b, + 0xd8, 0xea, 0xd5, 0xd7, 0xf5, 0xd5, 0xcc, 0xb9, + 0xb6, 0x9f, 0x30, 0x66, 0x5b, 0x66, 0x9a, 0x20, + 0xe2, 0x27, 0xe5, 0xbf, 0xfe, 0x3b, 0x30, 0x09, + 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x01, 0x03, 0x81, 0x8c, 0x00, 0x30, 0x81, 0x88, + 0x02, 0x42, 0x01, 0x88, 0xa2, 0x4f, 0xeb, 0xe2, + 0x45, 0xc5, 0x48, 0x7d, 0x1b, 0xac, 0xf5, 0xed, + 0x98, 0x9d, 0xae, 0x47, 0x70, 0xc0, 0x5e, 0x1b, + 0xb6, 0x2f, 0xbd, 0xf1, 0xb6, 0x4d, 0xb7, 0x61, + 0x40, 0xd3, 0x11, 0xa2, 0xce, 0xee, 0x0b, 0x7e, + 0x92, 0x7e, 0xff, 0x76, 0x9d, 0xc3, 0x3b, 0x7e, + 0xa5, 0x3f, 0xce, 0xfa, 0x10, 0xe2, 0x59, 0xec, + 0x47, 0x2d, 0x7c, 0xac, 0xda, 0x4e, 0x97, 0x0e, + 0x15, 0xa0, 0x6f, 0xd0, 0x02, 0x42, 0x01, 0x4d, + 0xfc, 0xbe, 0x67, 0x13, 0x9c, 0x2d, 0x05, 0x0e, + 0xbd, 0x3f, 0xa3, 0x8c, 0x25, 0xc1, 0x33, 0x13, + 0x83, 0x0d, 0x94, 0x06, 0xbb, 0xd4, 0x37, 0x7a, + 0xf6, 0xec, 0x7a, 0xc9, 0x86, 0x2e, 0xdd, 0xd7, + 0x11, 0x69, 0x7f, 0x85, 0x7c, 0x56, 0xde, 0xfb, + 0x31, 0x78, 0x2b, 0xe4, 0xc7, 0x78, 0x0d, 0xae, + 0xcb, 0xbe, 0x9e, 0x4e, 0x36, 0x24, 0x31, 0x7b, + 0x6a, 0x0f, 0x39, 0x95, 0x12, 0x07, 0x8f, 0x2a, + 0x16, 0x03, 0x01, 0x01, 0x1a, 0x0c, 0x00, 0x01, + 0x16, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, + 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, + 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, + 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, + 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, + 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, + 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, + 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, + 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, + 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, + 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, + 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, + 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, + 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, + 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, + 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, + 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, + 0x90, 0x33, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02, + 0x42, 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, + 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, + 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, + 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, + 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, + 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, + 0xff, 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, + 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, + 0xe5, 0xbd, 0x66, 0x02, 0x42, 0x00, 0xad, 0x7d, + 0x06, 0x35, 0xab, 0xec, 0x8d, 0xac, 0xd4, 0xba, + 0x1b, 0x49, 0x5e, 0x05, 0x5f, 0xf0, 0x97, 0x93, + 0x82, 0xb8, 0x2b, 0x8d, 0x91, 0x98, 0x63, 0x8e, + 0xb4, 0x14, 0x62, 0xdb, 0x1e, 0xc9, 0x2b, 0x30, + 0xf8, 0x41, 0x9b, 0xa6, 0xe6, 0xbc, 0xde, 0x0e, + 0x68, 0x30, 0x22, 0x50, 0xe6, 0x98, 0x97, 0x7b, + 0x69, 0xf7, 0x93, 0xed, 0xcd, 0x19, 0x2f, 0x44, + 0x6c, 0x2e, 0xdf, 0x25, 0xee, 0xcc, 0x46, 0x16, + 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x8a, 0x10, 0x00, 0x00, + 0x86, 0x85, 0x04, 0x00, 0x1c, 0xc5, 0xe8, 0xb3, + 0x42, 0xb4, 0xad, 0xca, 0x45, 0xcd, 0x42, 0x7b, + 0xfb, 0x0c, 0xea, 0x32, 0x26, 0xd4, 0x8a, 0xef, + 0xdf, 0xc9, 0xff, 0xd2, 0xe0, 0x36, 0xea, 0x4e, + 0xbb, 0x3e, 0xf4, 0x9c, 0x76, 0x4f, 0x44, 0xbd, + 0x84, 0x72, 0xdd, 0xcb, 0xe5, 0x28, 0x8d, 0x31, + 0x72, 0x3b, 0xd3, 0xf2, 0x9a, 0x13, 0xfb, 0x8a, + 0xa7, 0x72, 0xca, 0x21, 0x6c, 0xea, 0xbf, 0xe9, + 0x8c, 0x0a, 0xcc, 0x8f, 0xd6, 0x00, 0x20, 0x87, + 0xf3, 0x7d, 0x18, 0xc5, 0xfd, 0x9e, 0xdd, 0x6b, + 0x06, 0xdc, 0x52, 0xeb, 0x14, 0xc0, 0x67, 0x5a, + 0x06, 0xd8, 0x98, 0x19, 0x14, 0xe7, 0xd4, 0x36, + 0x32, 0xee, 0xb7, 0xfa, 0xe2, 0x85, 0x4a, 0x16, + 0x42, 0x0c, 0xa6, 0x21, 0xcf, 0x1f, 0xae, 0x10, + 0x8b, 0x28, 0x32, 0x19, 0xa4, 0x0a, 0xd7, 0xce, + 0xe6, 0xe1, 0x93, 0xfb, 0x5f, 0x08, 0x8b, 0x42, + 0xa2, 0x20, 0xed, 0x0d, 0x62, 0xca, 0xed, 0x14, + 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, + 0x00, 0x30, 0x2e, 0x33, 0xc0, 0x57, 0x6c, 0xb4, + 0x1b, 0xd2, 0x63, 0xe8, 0x67, 0x10, 0x2d, 0x87, + 0x71, 0x6e, 0x19, 0x60, 0xf4, 0xa4, 0x10, 0x52, + 0x73, 0x2d, 0x09, 0x5e, 0xdb, 0x6c, 0xdc, 0xcf, + 0x2d, 0xff, 0x03, 0x11, 0x95, 0x76, 0x90, 0xd7, + 0x87, 0x54, 0x43, 0xed, 0xc2, 0x36, 0x69, 0x14, + 0x72, 0x4a, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xe8, 0x8b, 0xde, 0xef, 0xba, 0xc5, 0x7e, 0x04, + 0xab, 0xfd, 0x79, 0x56, 0xf3, 0xe1, 0xa5, 0x3e, + 0x02, 0xdf, 0x69, 0x6d, 0x1f, 0x41, 0x9f, 0xbc, + 0x93, 0xe2, 0x6c, 0xf1, 0xb1, 0x38, 0xf5, 0x2b, + 0x8c, 0x4c, 0xf4, 0x74, 0xe1, 0x79, 0x35, 0x34, + 0x97, 0x9b, 0xd5, 0xba, 0xfd, 0xf7, 0x2f, 0x2d, + 0x9e, 0x84, 0x54, 0xee, 0x77, 0x59, 0x23, 0x8f, + 0xc8, 0x84, 0xb4, 0xd6, 0xea, 0x4c, 0x44, 0x8a, + 0xc6, 0x9c, 0xf9, 0x9b, 0x27, 0xea, 0x4f, 0x28, + 0x72, 0x33, 0x12, 0x20, 0x7c, 0xd7, 0x3f, 0x56, + 0xa6, 0x76, 0xc7, 0x48, 0xe4, 0x2d, 0x6f, 0x14, + 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, + 0x00, 0x30, 0x36, 0xe3, 0xd4, 0xf7, 0xb1, 0x69, + 0x18, 0x8d, 0x09, 0xba, 0x52, 0x1e, 0xd5, 0x7d, + 0x2c, 0x15, 0x3a, 0xd6, 0xe3, 0x99, 0x30, 0x2c, + 0x99, 0x97, 0xbc, 0x19, 0x3c, 0x63, 0xa1, 0x25, + 0x68, 0xbc, 0x8a, 0x16, 0x47, 0xec, 0xae, 0x13, + 0xa4, 0x03, 0x96, 0x29, 0x11, 0x92, 0x90, 0x1a, + 0xc8, 0xa4, 0x17, 0x03, 0x01, 0x00, 0x20, 0xc1, + 0x10, 0x1d, 0xa6, 0xf1, 0xe2, 0x8a, 0xcc, 0x37, + 0x7d, 0x8e, 0x05, 0x00, 0xfb, 0xd1, 0x9f, 0xc7, + 0x11, 0xd2, 0x00, 0xb4, 0x27, 0x0a, 0x25, 0x14, + 0xd9, 0x79, 0x1b, 0xcb, 0x4d, 0x81, 0x61, 0x17, + 0x03, 0x01, 0x00, 0x30, 0x5c, 0x7c, 0x2d, 0xc0, + 0x9e, 0xa6, 0xc4, 0x8e, 0xfd, 0xf4, 0xe2, 0xe5, + 0xe4, 0xe6, 0x56, 0x9f, 0x7d, 0x4c, 0x4c, 0x2d, + 0xb7, 0xa9, 0xac, 0xfa, 0x9f, 0x12, 0x7f, 0x2d, + 0x30, 0x57, 0xe4, 0x8e, 0x30, 0x86, 0x65, 0x59, + 0xcd, 0x24, 0xda, 0xe2, 0x8a, 0x7b, 0x0c, 0x5e, + 0x86, 0x05, 0x06, 0x2a, 0x15, 0x03, 0x01, 0x00, + 0x20, 0xd6, 0xb7, 0x70, 0xf8, 0x47, 0xbc, 0x0f, + 0xf4, 0x66, 0x98, 0x1b, 0x1e, 0x8a, 0x8c, 0x0b, + 0xa1, 0x4a, 0x04, 0x29, 0x60, 0x72, 0x8b, 0xc4, + 0x73, 0xc1, 0xd6, 0x41, 0x72, 0xb7, 0x17, 0x39, + 0xda, + }, +} + var sslv3ServerScript = [][]byte{ { 0x16, 0x03, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, @@ -1559,38 +1947,115 @@ var serverResumeTest = [][]byte{ }, } -var clientauthTests = []clientauthTest{ +var clientauthRSATests = []clientauthTest{ // Server asks for cert with empty CA list, client doesn't give it. // go test -run "TestRunServer" -serve -clientauth 1 {"RequestClientCert, none given", RequestClientCert, nil, [][]byte{ { - 0x16, 0x03, 0x01, 0x00, 0x54, 0x01, 0x00, 0x00, - 0x50, 0x03, 0x01, 0x50, 0x77, 0x43, 0x9e, 0x31, - 0xe6, 0x36, 0x5e, 0x5e, 0x24, 0xe4, 0x0d, 0x26, - 0x34, 0xa7, 0x1c, 0x2e, 0x59, 0x6d, 0xa5, 0x3e, - 0x72, 0xf3, 0xa3, 0x1c, 0xbc, 0xb3, 0x27, 0xaf, - 0x92, 0x5b, 0x7d, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, + 0x16, 0x03, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, + 0x1a, 0x03, 0x03, 0x51, 0xe5, 0x6c, 0xb5, 0x5a, + 0xc2, 0xf5, 0xf0, 0x92, 0x94, 0x8a, 0x64, 0x18, + 0xa4, 0x2b, 0x82, 0x07, 0xbc, 0xd9, 0xd9, 0xf9, + 0x7b, 0xd2, 0xd0, 0xee, 0xa2, 0x70, 0x4e, 0x23, + 0x88, 0x7c, 0x95, 0x00, 0x00, 0x82, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, + 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, + 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, + 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, + 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, + 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, + 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, + 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, + 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, + 0x00, 0x12, 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, + 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, + 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, + 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, + 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, + 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, + 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, + 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, + 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, + 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, + 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, + 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, + 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, + 0x00, 0x01, 0x01, }, { - 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00, - 0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, - 0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, - 0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, - 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, + 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, + 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, + 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, + 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, + 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, + 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, + 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, + 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, + 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, + 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, + 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, + 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, + 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, + 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, + 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, + 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, + 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, + 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, + 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, + 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, + 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, + 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, + 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, + 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, + 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, + 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, + 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, + 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, + 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, + 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, + 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, + 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, @@ -1599,158 +2064,200 @@ var clientauthTests = []clientauthTest{ 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, - 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, - 0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, - 0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, - 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, - 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, - 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, - 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, - 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, - 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, - 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, - 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, - 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, - 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, - 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, - 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, - 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, - 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, - 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, - 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, - 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, - 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, - 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, - 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, - 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, - 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, - 0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, - 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, - 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, - 0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, - 0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, - 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, - 0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, - 0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, - 0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, - 0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, - 0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, - 0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, - 0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, - 0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, - 0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, - 0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, - 0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, - 0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, - 0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, - 0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, - 0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, - 0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x08, 0x0d, - 0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x16, - 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, + 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, + 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, + 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, + 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, + 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, + 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, + 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, + 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, + 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, + 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, + 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, + 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, + 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, + 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, + 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, + 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, + 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, + 0x16, 0x03, 0x01, 0x00, 0x09, 0x0d, 0x00, 0x00, + 0x05, 0x02, 0x01, 0x40, 0x00, 0x00, 0x16, 0x03, + 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, }, { 0x16, 0x03, 0x01, 0x00, 0x07, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, 0x00, - 0x86, 0x10, 0x00, 0x00, 0x82, 0x00, 0x80, 0x04, - 0x58, 0x63, 0x26, 0x32, 0x1b, 0x34, 0xbe, 0x10, - 0xe4, 0xe4, 0x3e, 0xcd, 0x36, 0x7f, 0xa8, 0xa8, - 0xe0, 0x19, 0xe8, 0x94, 0x13, 0xd9, 0x35, 0xc4, - 0x71, 0xb4, 0x91, 0xd4, 0xbc, 0x74, 0x57, 0x9f, - 0x93, 0xb7, 0x5d, 0x3b, 0x9c, 0xff, 0x5d, 0x79, - 0xdb, 0x86, 0xfc, 0xdc, 0x74, 0x1e, 0x0c, 0xc6, - 0xe8, 0x93, 0xcf, 0xaf, 0xba, 0x1d, 0xfd, 0x8a, - 0xeb, 0xef, 0xbf, 0xfa, 0xa6, 0xe7, 0x53, 0x98, - 0x60, 0x4e, 0x0e, 0x60, 0x7d, 0xea, 0x40, 0x8d, - 0x1d, 0x8f, 0xa3, 0xc6, 0x83, 0xbc, 0xef, 0xb7, - 0x9a, 0x4a, 0xe7, 0x99, 0xee, 0x0b, 0xc7, 0x46, - 0x75, 0x45, 0x66, 0xe8, 0x5f, 0x4b, 0x08, 0xa4, - 0xc1, 0x36, 0xd0, 0x36, 0x2c, 0xf2, 0x9a, 0x44, - 0x1e, 0x5f, 0x22, 0xf4, 0xbe, 0x66, 0x66, 0x17, - 0xd8, 0xb6, 0x0a, 0x89, 0xed, 0x22, 0x80, 0xdb, - 0xad, 0x05, 0xd1, 0xb5, 0x93, 0xa1, 0x1c, 0x14, + 0x86, 0x10, 0x00, 0x00, 0x82, 0x00, 0x80, 0x36, + 0xfc, 0xd8, 0xc8, 0xa2, 0x67, 0xc8, 0xc6, 0xf4, + 0x28, 0x70, 0xe1, 0x5a, 0x02, 0x8f, 0xef, 0x42, + 0xe0, 0xd3, 0xb8, 0xd6, 0x6b, 0xe4, 0xee, 0x5c, + 0xcf, 0x42, 0xc4, 0xfa, 0xcd, 0x0f, 0xfe, 0xf4, + 0x76, 0x76, 0x47, 0x73, 0xa8, 0x72, 0x8f, 0xa2, + 0x56, 0x81, 0x83, 0xb8, 0x84, 0x72, 0x67, 0xdd, + 0xbe, 0x05, 0x4b, 0x84, 0xd9, 0xd2, 0xb6, 0xc2, + 0xe7, 0x20, 0xac, 0x1f, 0x46, 0x9d, 0x05, 0x47, + 0x8e, 0x89, 0xc0, 0x42, 0x57, 0x4a, 0xa2, 0x98, + 0xe5, 0x39, 0x4f, 0xc4, 0x27, 0x6d, 0x43, 0xa8, + 0x83, 0x76, 0xe6, 0xad, 0xe3, 0x17, 0x68, 0x31, + 0xcb, 0x7e, 0xfc, 0xe7, 0x4b, 0x76, 0x3d, 0x3c, + 0xfa, 0x77, 0x65, 0xc9, 0x4c, 0x5b, 0xce, 0x5e, + 0xf7, 0x8b, 0xa8, 0xa6, 0xdd, 0xb2, 0xef, 0x0b, + 0x46, 0x83, 0xdf, 0x0a, 0x8c, 0x22, 0x12, 0x6e, + 0xe1, 0x45, 0x54, 0x88, 0xd1, 0xe8, 0xd2, 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, - 0x00, 0x24, 0x62, 0x6f, 0x3d, 0x30, 0x56, 0x97, - 0xde, 0x03, 0x67, 0xa9, 0x63, 0x21, 0xb6, 0xe6, - 0x05, 0x69, 0x94, 0xfb, 0x50, 0xc1, 0x99, 0xdd, - 0xf6, 0xe8, 0x60, 0xbd, 0xe6, 0xba, 0xe3, 0x50, - 0x0a, 0xcd, 0xde, 0x14, 0x16, 0xc4, + 0x00, 0x24, 0x30, 0x8c, 0x7d, 0x40, 0xfc, 0x5e, + 0x80, 0x9c, 0xc4, 0x7c, 0x62, 0x01, 0xa1, 0x37, + 0xcf, 0x1a, 0x75, 0x28, 0x8d, 0xeb, 0x63, 0xcc, + 0x02, 0xa6, 0x66, 0xdf, 0x36, 0x01, 0xb3, 0x9d, + 0x38, 0x42, 0x16, 0x91, 0xf0, 0x02, }, { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0xf0, 0x21, 0xf6, 0x84, 0x6a, - 0xe3, 0x6b, 0x8a, 0xc5, 0x46, 0x50, 0xca, 0x40, - 0xea, 0x4e, 0x82, 0xc1, 0x70, 0x25, 0xd8, 0x7d, - 0x60, 0xf5, 0x51, 0x7f, 0x64, 0x03, 0x9f, 0x53, - 0xec, 0xfb, 0x57, 0xa9, 0xfc, 0x26, 0x15, 0x17, - 0x03, 0x01, 0x00, 0x21, 0xa6, 0xc6, 0x94, 0x2b, - 0xa9, 0xcb, 0x93, 0xff, 0xb6, 0xa6, 0xe7, 0xc5, - 0x37, 0x86, 0x15, 0x37, 0x57, 0xce, 0xef, 0x54, - 0x96, 0x5d, 0x50, 0xa0, 0x50, 0x69, 0x5e, 0x82, - 0x61, 0x8d, 0x42, 0xfb, 0x78, 0x15, 0x03, 0x01, - 0x00, 0x16, 0x45, 0xd1, 0x86, 0x68, 0x59, 0xc1, - 0xaf, 0xac, 0x5c, 0x46, 0x8a, 0x68, 0x69, 0x0c, - 0xd7, 0x67, 0xbf, 0xf0, 0x3e, 0xee, 0x45, 0x55, + 0x16, 0x03, 0x01, 0x00, 0x72, 0x04, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xe8, 0x4b, 0xd1, 0xef, 0xba, 0x96, 0x9a, 0x2a, + 0x6c, 0x8c, 0x7e, 0x38, 0x10, 0x46, 0x86, 0x1d, + 0x19, 0x1d, 0x62, 0x29, 0x3f, 0x58, 0xfb, 0x6d, + 0x89, 0xd2, 0x81, 0x9a, 0x1c, 0xb3, 0x58, 0xb3, + 0x19, 0x39, 0x17, 0x47, 0x49, 0xc9, 0xfe, 0x4a, + 0x7a, 0x32, 0xac, 0x2c, 0x43, 0xf9, 0xa9, 0xea, + 0xec, 0x51, 0x46, 0xf1, 0xb8, 0x59, 0x23, 0x70, + 0xce, 0x7c, 0xb9, 0x47, 0x70, 0xa3, 0xc9, 0xae, + 0x47, 0x7b, 0x7e, 0xc7, 0xcf, 0x76, 0x12, 0x76, + 0x18, 0x90, 0x12, 0xcd, 0xf3, 0xd4, 0x27, 0x81, + 0xfc, 0x46, 0x03, 0x3e, 0x05, 0x87, 0x6f, 0x14, + 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, + 0x00, 0x24, 0xc3, 0xa0, 0x29, 0xb1, 0x52, 0x82, + 0xef, 0x85, 0xa1, 0x64, 0x0f, 0xe4, 0xa3, 0xfb, + 0xa7, 0x1d, 0x22, 0x4c, 0xcb, 0xd6, 0x5b, 0x18, + 0x61, 0xc7, 0x7c, 0xf2, 0x67, 0x4a, 0xc7, 0x11, + 0x9d, 0x8e, 0x0e, 0x15, 0x22, 0xcf, 0x17, 0x03, + 0x01, 0x00, 0x21, 0xfd, 0xbb, 0xf1, 0xa9, 0x7c, + 0xbf, 0x92, 0xb3, 0xfa, 0x2c, 0x08, 0x6f, 0x22, + 0x78, 0x80, 0xf2, 0x2e, 0x86, 0x26, 0x21, 0x36, + 0x3f, 0x32, 0xdf, 0xb6, 0x47, 0xa5, 0xf8, 0x27, + 0xc1, 0xe9, 0x53, 0x90, 0x15, 0x03, 0x01, 0x00, + 0x16, 0xfe, 0xef, 0x2e, 0xa0, 0x5d, 0xe0, 0xce, + 0x94, 0x20, 0x56, 0x61, 0x6e, 0xe5, 0x62, 0xce, + 0x27, 0x57, 0x3e, 0x30, 0x32, 0x77, 0x53, }, }}, + // Server asks for cert with empty CA list, client gives one // go test -run "TestRunServer" -serve -clientauth 1 {"RequestClientCert, client gives it", RequestClientCert, []*x509.Certificate{clientCertificate}, [][]byte{ { - 0x16, 0x03, 0x01, 0x00, 0x54, 0x01, 0x00, 0x00, - 0x50, 0x03, 0x01, 0x50, 0x77, 0x43, 0x47, 0xfd, - 0x1d, 0xb0, 0x60, 0x4c, 0x25, 0x86, 0x45, 0x4a, - 0xe5, 0x3f, 0x80, 0x56, 0x18, 0x91, 0x5c, 0xe2, - 0x62, 0xc5, 0x77, 0xc2, 0x92, 0xdd, 0xdc, 0x39, - 0x23, 0x1d, 0xc5, 0x00, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x16, 0x00, 0x13, - 0x00, 0x0a, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2f, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, - 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x02, 0x01, - 0x00, + 0x16, 0x03, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, + 0x1a, 0x03, 0x03, 0x51, 0xe5, 0x74, 0x0e, 0x95, + 0x6f, 0x4f, 0x4a, 0xbf, 0xb7, 0xc0, 0x6c, 0xac, + 0xd9, 0xfe, 0x7d, 0xd0, 0x51, 0x19, 0x62, 0x62, + 0x1c, 0x6e, 0x57, 0x77, 0xd2, 0x31, 0xaf, 0x88, + 0xb9, 0xc0, 0x1d, 0x00, 0x00, 0x82, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, + 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, + 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, + 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, + 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, + 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, + 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, + 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, + 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, + 0x00, 0x12, 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, + 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, + 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, + 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, + 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, + 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, + 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, + 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, + 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, + 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, + 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, + 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, + 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, + 0x00, 0x01, 0x01, }, { - 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00, - 0x26, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, - 0x03, 0x01, 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, - 0x00, 0x02, 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, - 0x02, 0xb0, 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, - 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, + 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, + 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, + 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, + 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, + 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, + 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, + 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, + 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, + 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, + 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, + 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, + 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, + 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, + 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, + 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, + 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, + 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, + 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, + 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, + 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, + 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, + 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, + 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, + 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, + 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, + 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, + 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, + 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, + 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, + 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, + 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, + 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, @@ -1759,82 +2266,31 @@ var clientauthTests = []clientauthTest{ 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, - 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x30, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, - 0x30, 0x39, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, - 0x31, 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, - 0x39, 0x33, 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, - 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, - 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, - 0x4c, 0x74, 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, - 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, - 0xbb, 0x79, 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, - 0x46, 0x10, 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, - 0x07, 0x43, 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, - 0x43, 0x85, 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, - 0x4c, 0x2c, 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, - 0x82, 0xe5, 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, - 0xa5, 0x2c, 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, - 0x7a, 0x56, 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, - 0x7b, 0x26, 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, - 0xc9, 0x21, 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, - 0x5a, 0xbf, 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, - 0x99, 0x07, 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, - 0x04, 0x39, 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, - 0x7c, 0xe3, 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, - 0xcf, 0xaf, 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, - 0xdb, 0xdb, 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, - 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, - 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, - 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, - 0x88, 0x39, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, - 0xad, 0xe2, 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, - 0x69, 0xce, 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, - 0x18, 0x88, 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, - 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, - 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, - 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, - 0x00, 0x85, 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, - 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, - 0xb1, 0x59, 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, - 0x14, 0xd7, 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, - 0x5a, 0x95, 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, - 0x12, 0x66, 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, - 0x60, 0xd3, 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, - 0x25, 0x13, 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, - 0x1d, 0xba, 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, - 0xd7, 0x31, 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, - 0xea, 0x50, 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, - 0x5a, 0x5f, 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, - 0x90, 0x96, 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, - 0x98, 0x1f, 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, - 0xa3, 0x1b, 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, - 0xe9, 0x70, 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, - 0x26, 0x6e, 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, - 0xbd, 0xd9, 0x16, 0x03, 0x01, 0x00, 0x08, 0x0d, - 0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00, 0x16, - 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, + 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, + 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, + 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, + 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, + 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, + 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, + 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, + 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, + 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, + 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, + 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, + 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, + 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, + 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, + 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, + 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, + 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, + 0x16, 0x03, 0x01, 0x00, 0x09, 0x0d, 0x00, 0x00, + 0x05, 0x02, 0x01, 0x40, 0x00, 0x00, 0x16, 0x03, + 0x01, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, }, { 0x16, 0x03, 0x01, 0x01, 0xfb, 0x0b, 0x00, 0x01, @@ -1902,66 +2358,778 @@ var clientauthTests = []clientauthTest{ 0x51, 0x8d, 0x10, 0x7e, 0x4f, 0x94, 0x67, 0xdf, 0xa3, 0x4e, 0x70, 0x73, 0x8e, 0x90, 0x91, 0x85, 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0x81, 0x46, 0x43, 0xf9, 0xe7, - 0xda, 0x8c, 0x92, 0x3a, 0x78, 0x1a, 0x86, 0xb3, - 0xbe, 0x83, 0x22, 0xb6, 0xaa, 0x57, 0x37, 0x68, - 0x9e, 0x54, 0x3f, 0xd3, 0xce, 0x4d, 0x5e, 0x2a, - 0xdc, 0xb0, 0x49, 0x02, 0xbb, 0xc0, 0x45, 0x58, - 0x79, 0x10, 0xc7, 0x94, 0x60, 0x9f, 0x1b, 0x5f, - 0x18, 0x31, 0x37, 0x9c, 0xe0, 0xe6, 0xdf, 0x5e, - 0x70, 0x44, 0xf6, 0x8b, 0xdf, 0xf1, 0xf6, 0x43, - 0xc8, 0x2f, 0xd1, 0xce, 0xd0, 0xd6, 0x64, 0x4f, - 0xe8, 0x2b, 0xfa, 0xd3, 0xd0, 0xd1, 0x2e, 0xaa, - 0x9b, 0x1d, 0x13, 0x5c, 0xbe, 0x57, 0x41, 0x6c, - 0x5e, 0x8d, 0xea, 0xa9, 0x3c, 0x58, 0xa0, 0x30, - 0x92, 0x77, 0x7a, 0xed, 0x64, 0x58, 0xe5, 0x7f, - 0x6a, 0x93, 0x89, 0x66, 0x3d, 0x13, 0x16, 0x56, - 0xa0, 0xad, 0xdc, 0x68, 0x95, 0x87, 0x81, 0xd0, - 0x90, 0x4d, 0x5f, 0xfe, 0x3e, 0x83, 0x15, 0x2e, - 0x50, 0x3c, 0xdd, 0x16, 0x03, 0x01, 0x00, 0x86, - 0x0f, 0x00, 0x00, 0x82, 0x00, 0x80, 0x2b, 0xf8, - 0x56, 0x48, 0xbb, 0x02, 0x37, 0x15, 0x02, 0x74, - 0x33, 0x53, 0x65, 0xa7, 0x7c, 0x2f, 0xc6, 0x5d, - 0x80, 0x59, 0xc1, 0xc2, 0x3b, 0xa9, 0xde, 0x4e, - 0x70, 0x51, 0xd2, 0xde, 0x58, 0x7f, 0xd8, 0xb9, - 0xb6, 0x3b, 0xc8, 0xaa, 0xfc, 0x3d, 0x53, 0x2d, - 0x61, 0x4d, 0xf5, 0x60, 0x12, 0xc2, 0xa5, 0x39, - 0x0c, 0xa7, 0xc6, 0xac, 0x26, 0x4b, 0xf4, 0x5f, - 0xe9, 0xf4, 0xf2, 0x73, 0x48, 0xe4, 0x3b, 0xee, - 0xf2, 0xee, 0xc0, 0xee, 0xfb, 0x5b, 0x60, 0xc2, - 0x74, 0xe6, 0xf6, 0x43, 0x3e, 0xa4, 0xf7, 0x97, - 0x3d, 0xfc, 0xe9, 0x44, 0x21, 0x18, 0x46, 0x05, - 0x33, 0xf8, 0xfe, 0x35, 0x5b, 0xe6, 0x8f, 0xef, - 0x4d, 0x4c, 0x87, 0xf6, 0xb4, 0x6e, 0x6b, 0x39, - 0xd8, 0xaa, 0x1b, 0x33, 0xc9, 0x1c, 0x66, 0x48, - 0xbe, 0xfa, 0xb5, 0x92, 0x09, 0xfd, 0xb9, 0xb9, - 0xca, 0xe6, 0x6d, 0x71, 0xc6, 0x89, 0x14, 0x03, + 0x82, 0x00, 0x80, 0x0a, 0x4e, 0x89, 0xdf, 0x3a, + 0x3f, 0xf0, 0x4f, 0xef, 0x1a, 0x90, 0xd4, 0x3c, + 0xaf, 0x10, 0x57, 0xb0, 0xa1, 0x5f, 0xcd, 0x62, + 0x01, 0xe9, 0x0c, 0x36, 0x42, 0xfd, 0xaf, 0x23, + 0xf9, 0x14, 0xa6, 0x72, 0x26, 0x4e, 0x01, 0xdb, + 0xac, 0xb7, 0x4c, 0xe6, 0xa9, 0x52, 0xe2, 0xec, + 0x26, 0x8c, 0x7a, 0x64, 0xf8, 0x0b, 0x4c, 0x2f, + 0xa9, 0xcb, 0x75, 0xaf, 0x60, 0xd4, 0xb4, 0xe6, + 0xe8, 0xdb, 0x78, 0x78, 0x85, 0xf6, 0x0c, 0x95, + 0xcc, 0xb6, 0x55, 0xb9, 0xba, 0x9e, 0x91, 0xbc, + 0x66, 0xdb, 0x1e, 0x28, 0xab, 0x73, 0xce, 0x8b, + 0xd0, 0xd3, 0xe8, 0xbc, 0xd0, 0x21, 0x28, 0xbd, + 0xfb, 0x74, 0x64, 0xde, 0x3b, 0x3b, 0xd3, 0x4c, + 0x32, 0x40, 0x82, 0xba, 0x91, 0x1e, 0xe8, 0x47, + 0xc2, 0x09, 0xb7, 0x16, 0xaa, 0x25, 0xa9, 0x3c, + 0x6c, 0xa7, 0xf8, 0xc9, 0x54, 0x84, 0xc6, 0xf7, + 0x56, 0x05, 0xa4, 0x16, 0x03, 0x01, 0x00, 0x86, + 0x0f, 0x00, 0x00, 0x82, 0x00, 0x80, 0x4b, 0xab, + 0xda, 0xac, 0x2a, 0xb3, 0xe6, 0x34, 0x55, 0xcd, + 0xf2, 0x4b, 0x67, 0xe3, 0xd3, 0xff, 0xa3, 0xf4, + 0x79, 0x82, 0x01, 0x47, 0x8a, 0xe3, 0x9f, 0x89, + 0x70, 0xbe, 0x24, 0x24, 0xb7, 0x69, 0x60, 0xed, + 0x55, 0xa0, 0xca, 0x72, 0xb6, 0x4a, 0xbc, 0x1d, + 0xe2, 0x3f, 0xb5, 0x31, 0xda, 0x02, 0xf6, 0x37, + 0x51, 0xf8, 0x4c, 0x88, 0x2e, 0xb3, 0x8a, 0xe8, + 0x7b, 0x4a, 0x90, 0x36, 0xe4, 0xa6, 0x31, 0x95, + 0x8b, 0xa0, 0xc6, 0x91, 0x12, 0xb9, 0x35, 0x4e, + 0x72, 0xeb, 0x5c, 0xa2, 0xe8, 0x4c, 0x68, 0xf9, + 0x69, 0xfa, 0x70, 0x60, 0x6c, 0x7f, 0x32, 0x99, + 0xf1, 0xc3, 0x2d, 0xb4, 0x59, 0x58, 0x87, 0xaf, + 0x67, 0x62, 0x90, 0xe7, 0x8d, 0xd0, 0xa3, 0x77, + 0x33, 0xc2, 0x9b, 0xd5, 0x9c, 0xc7, 0xea, 0x25, + 0x98, 0x76, 0x9c, 0xe0, 0x6a, 0x03, 0x3a, 0x10, + 0xfd, 0x10, 0x3d, 0x55, 0x53, 0xa0, 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, - 0x24, 0xe3, 0x2b, 0xef, 0x17, 0xd5, 0xa6, 0x4c, - 0x2e, 0x10, 0xac, 0x9c, 0xfe, 0x0f, 0x18, 0x43, - 0x95, 0x00, 0x81, 0xf7, 0x7c, 0x00, 0x5b, 0x89, - 0x52, 0x41, 0xe4, 0x8a, 0x8a, 0x34, 0x31, 0x09, - 0x48, 0x7c, 0xc5, 0xc3, 0x83, + 0x24, 0xd5, 0x12, 0xfc, 0xb9, 0x5a, 0xe3, 0x27, + 0x01, 0xbe, 0xc3, 0x77, 0x17, 0x1a, 0xbb, 0x4f, + 0xae, 0xd5, 0xa7, 0xee, 0x56, 0x61, 0x0d, 0x40, + 0xf4, 0xa4, 0xb5, 0xcc, 0x76, 0xfd, 0xbd, 0x13, + 0x04, 0xe1, 0xb8, 0xc7, 0x36, }, { - 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x01, 0x00, 0x24, 0x24, 0xaa, 0xaa, 0x56, 0x8b, - 0x41, 0x87, 0x01, 0xbe, 0x80, 0x05, 0x51, 0x36, - 0x08, 0xfc, 0xaf, 0xff, 0x7f, 0xf4, 0x74, 0x84, - 0x88, 0xdc, 0xb8, 0x8e, 0x70, 0x6c, 0x22, 0x04, - 0xee, 0x45, 0x8d, 0xda, 0xed, 0xc6, 0x05, 0x17, - 0x03, 0x01, 0x00, 0x21, 0x91, 0x49, 0x4b, 0xed, - 0xa3, 0x41, 0xe9, 0x88, 0x3b, 0xa3, 0x01, 0xee, - 0x77, 0x4e, 0x12, 0xb4, 0xcd, 0x5e, 0xcc, 0x45, - 0x02, 0x5a, 0x20, 0xd6, 0xe8, 0xac, 0xcb, 0x60, - 0xcb, 0x1b, 0xef, 0xf9, 0xc2, 0x15, 0x03, 0x01, - 0x00, 0x16, 0xd4, 0xcd, 0x92, 0x3c, 0x10, 0x93, - 0x68, 0xc3, 0xdd, 0xaf, 0xe9, 0xcb, 0x5d, 0x94, - 0x1a, 0x06, 0x81, 0xa7, 0x78, 0x0f, 0xc3, 0x03, + 0x16, 0x03, 0x01, 0x02, 0x67, 0x04, 0x00, 0x02, + 0x63, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xe8, 0x4b, 0xd1, 0xef, 0xba, 0x1f, 0xe2, 0x69, + 0x07, 0x7f, 0x85, 0x2d, 0x4e, 0x2a, 0x2e, 0xbd, + 0x05, 0xe9, 0xc1, 0x6c, 0x9e, 0xbf, 0x47, 0x18, + 0x91, 0x77, 0xf7, 0xe8, 0xb6, 0x27, 0x37, 0xa6, + 0x6b, 0x87, 0x29, 0xbb, 0x3b, 0xe5, 0x68, 0x62, + 0x04, 0x3e, 0xad, 0x4d, 0xff, 0xad, 0xf1, 0x22, + 0x87, 0x8d, 0xf6, 0x04, 0x3b, 0x59, 0x22, 0xf7, + 0xfd, 0x88, 0x0e, 0xa4, 0x09, 0xc0, 0x0d, 0x10, + 0x80, 0x10, 0x79, 0xee, 0x70, 0x96, 0xdb, 0x22, + 0x8b, 0xb7, 0xac, 0xe0, 0x98, 0xad, 0xe9, 0xe3, + 0xcb, 0xea, 0x9f, 0xe6, 0x83, 0x28, 0x7c, 0x7e, + 0x4e, 0x9a, 0x8d, 0xd9, 0xf3, 0x86, 0xf4, 0x89, + 0x8b, 0x79, 0x8f, 0xbb, 0xe9, 0x74, 0x02, 0x02, + 0x14, 0x04, 0xea, 0xba, 0x16, 0x10, 0xa1, 0x85, + 0xbe, 0x4e, 0x4e, 0x92, 0xc5, 0x83, 0xf6, 0x1e, + 0x1f, 0xd4, 0x25, 0xc2, 0xc2, 0xb9, 0xce, 0x33, + 0x63, 0x66, 0x79, 0x1f, 0x54, 0x35, 0xc1, 0xe8, + 0x89, 0x34, 0x78, 0x94, 0x36, 0x14, 0xef, 0x01, + 0x1f, 0xf1, 0xbd, 0x77, 0x2c, 0x4d, 0xac, 0x5c, + 0x5c, 0x4a, 0xc6, 0xed, 0xd8, 0x0e, 0x72, 0x84, + 0x83, 0xdc, 0x56, 0x84, 0xc8, 0xf3, 0x89, 0x56, + 0xfd, 0x89, 0xc1, 0xc9, 0x9a, 0x29, 0x91, 0x7e, + 0x19, 0xe9, 0x8b, 0x5b, 0x11, 0x15, 0x4e, 0x6c, + 0xf4, 0x89, 0xe7, 0x6d, 0x68, 0x1e, 0xf9, 0x6c, + 0x23, 0x72, 0x05, 0x68, 0x82, 0x60, 0x84, 0x1f, + 0x83, 0x20, 0x09, 0x86, 0x10, 0x81, 0xec, 0xec, + 0xdc, 0x25, 0x53, 0x20, 0xfa, 0xa9, 0x41, 0x64, + 0xd6, 0x20, 0xf3, 0xf4, 0x52, 0xf2, 0x80, 0x62, + 0x83, 0xc9, 0x23, 0x66, 0x44, 0x95, 0x5a, 0x99, + 0x8a, 0xe1, 0x26, 0x63, 0xc1, 0x8b, 0x31, 0xf9, + 0x21, 0x06, 0x77, 0x04, 0x27, 0xf2, 0x0c, 0x63, + 0x83, 0x45, 0xa0, 0xa9, 0x7b, 0xcf, 0xdf, 0xd7, + 0x56, 0x75, 0xbc, 0xdd, 0x95, 0x36, 0xb1, 0x75, + 0x39, 0x05, 0x00, 0x3c, 0x8a, 0x79, 0xd6, 0xe9, + 0xf0, 0x4b, 0xdc, 0x51, 0x6b, 0x01, 0x94, 0x16, + 0x87, 0x12, 0x92, 0x6c, 0x07, 0xc1, 0xf5, 0x58, + 0xb7, 0x2a, 0x81, 0xf5, 0xa0, 0x37, 0x8b, 0xa6, + 0x22, 0xfe, 0x28, 0x0a, 0x7e, 0x68, 0xe2, 0xda, + 0x6c, 0x53, 0xee, 0x0e, 0x8d, 0x2d, 0x8b, 0x0b, + 0xda, 0xf8, 0x99, 0x3e, 0x0e, 0xed, 0x9f, 0xc1, + 0x2b, 0xf6, 0xfe, 0xe9, 0x52, 0x38, 0x7b, 0x83, + 0x9a, 0x50, 0xa6, 0xd7, 0x49, 0x83, 0x43, 0x7e, + 0x82, 0xec, 0xc7, 0x09, 0x3d, 0x3d, 0xb1, 0xee, + 0xe8, 0xc5, 0x6a, 0xc3, 0x3d, 0x4b, 0x4c, 0x6a, + 0xbb, 0x0b, 0x2c, 0x24, 0x2e, 0xdb, 0x7d, 0x57, + 0x87, 0xb4, 0x80, 0xa5, 0xae, 0xff, 0x54, 0xa8, + 0xa5, 0x27, 0x69, 0x95, 0xc8, 0xe7, 0x79, 0xc7, + 0x89, 0x2a, 0x73, 0x49, 0xcb, 0xf5, 0xc5, 0xbc, + 0x4a, 0xe0, 0x73, 0xa9, 0xbc, 0x88, 0x64, 0x96, + 0x98, 0xa5, 0x1e, 0xe3, 0x43, 0xc1, 0x7d, 0x78, + 0xc7, 0x94, 0x72, 0xd4, 0x2c, 0x6e, 0x85, 0x39, + 0x9a, 0xaf, 0xdb, 0xa1, 0xe9, 0xe2, 0xcb, 0x37, + 0x04, 0xc6, 0x8c, 0x81, 0xd3, 0x2a, 0xb7, 0xbe, + 0x6c, 0x07, 0x1f, 0x5e, 0xd9, 0x00, 0xd2, 0xf7, + 0xe1, 0xa7, 0xbc, 0x0c, 0xb6, 0x6d, 0xfb, 0x3f, + 0x3d, 0x24, 0xaa, 0xfb, 0x7e, 0xe1, 0xb5, 0x1b, + 0xff, 0x38, 0xaa, 0x69, 0x59, 0x38, 0x52, 0x9a, + 0x0e, 0x6d, 0xbc, 0xde, 0x4f, 0x13, 0x09, 0x17, + 0xc4, 0xa9, 0x05, 0x84, 0xbc, 0x50, 0xef, 0x40, + 0xb0, 0x4c, 0x24, 0x32, 0xed, 0x94, 0x2c, 0xdd, + 0xda, 0x20, 0x24, 0x67, 0xe2, 0xea, 0x71, 0x3d, + 0x4a, 0x04, 0x0d, 0x98, 0x29, 0x20, 0x4c, 0xeb, + 0x70, 0xce, 0x45, 0x9e, 0x5a, 0xaf, 0xb6, 0xa3, + 0x92, 0xc8, 0x28, 0xf2, 0xe3, 0xe8, 0x8a, 0x5d, + 0x0a, 0x33, 0x79, 0x9b, 0x6a, 0xf3, 0x30, 0x01, + 0x1d, 0x47, 0xbd, 0x01, 0xcc, 0x4d, 0x71, 0xc0, + 0x56, 0xfa, 0xfd, 0x37, 0xed, 0x0f, 0x27, 0xc0, + 0xbb, 0xa0, 0xee, 0xc3, 0x79, 0x8b, 0xe7, 0x41, + 0x8f, 0xfa, 0x3a, 0xcb, 0x45, 0x3b, 0x85, 0x9f, + 0x06, 0x90, 0xb2, 0x51, 0x7a, 0xc3, 0x11, 0x41, + 0x4b, 0xe3, 0x26, 0x94, 0x3e, 0xa2, 0xfd, 0x0a, + 0xda, 0x50, 0xf6, 0x50, 0x78, 0x19, 0x6c, 0x52, + 0xd1, 0x12, 0x76, 0xc2, 0x50, 0x2f, 0x0b, 0xca, + 0x33, 0xe5, 0x79, 0x93, 0x14, 0x03, 0x01, 0x00, + 0x01, 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0x2b, + 0x51, 0x42, 0x95, 0x6b, 0xca, 0x9f, 0x42, 0x5d, + 0xd2, 0xd9, 0x67, 0xf9, 0x49, 0x30, 0xfd, 0x2a, + 0x46, 0xd3, 0x04, 0xf4, 0x86, 0xf9, 0x11, 0x34, + 0x82, 0xac, 0xe2, 0xc2, 0x2d, 0xc4, 0xd0, 0xfe, + 0xa9, 0xc9, 0x4b, 0x17, 0x03, 0x01, 0x00, 0x21, + 0x65, 0x1c, 0xe9, 0x5c, 0xb6, 0xe2, 0x7c, 0x8e, + 0x49, 0x12, 0x1b, 0xe6, 0x40, 0xd3, 0x97, 0x21, + 0x76, 0x01, 0xe5, 0x80, 0x5e, 0xf3, 0x11, 0x47, + 0x25, 0x02, 0x78, 0x8e, 0x6b, 0xae, 0xb3, 0xf3, + 0x59, 0x15, 0x03, 0x01, 0x00, 0x16, 0x38, 0xc1, + 0x99, 0x2e, 0xf8, 0x6f, 0x45, 0xa4, 0x10, 0x79, + 0x5b, 0xc1, 0x47, 0x9a, 0xf6, 0x5c, 0x90, 0xeb, + 0xa6, 0xe3, 0x1a, 0x24, }, }}, } +var tls11ECDHEAESServerScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x01, 0x46, 0x01, 0x00, 0x01, + 0x42, 0x03, 0x03, 0x51, 0x9f, 0xa3, 0xb0, 0xb7, + 0x1d, 0x26, 0x93, 0x36, 0xc0, 0x8d, 0x7e, 0xf8, + 0x4f, 0x6f, 0xc9, 0x3c, 0x31, 0x1e, 0x7f, 0xb1, + 0xf0, 0xc1, 0x0f, 0xf9, 0x0c, 0xa2, 0xd5, 0xca, + 0x48, 0xe5, 0x35, 0x00, 0x00, 0xd0, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0xc0, 0x22, 0xc0, 0x21, 0x00, 0xa5, + 0x00, 0xa3, 0x00, 0xa1, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x6a, 0x00, 0x69, 0x00, 0x68, 0x00, 0x39, + 0x00, 0x38, 0x00, 0x37, 0x00, 0x36, 0x00, 0x88, + 0x00, 0x87, 0x00, 0x86, 0x00, 0x85, 0xc0, 0x32, + 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, + 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, + 0x00, 0x84, 0xc0, 0x12, 0xc0, 0x08, 0xc0, 0x1c, + 0xc0, 0x1b, 0x00, 0x16, 0x00, 0x13, 0x00, 0x10, + 0x00, 0x0d, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, + 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, + 0xc0, 0x13, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x1e, + 0x00, 0xa4, 0x00, 0xa2, 0x00, 0xa0, 0x00, 0x9e, + 0x00, 0x67, 0x00, 0x40, 0x00, 0x3f, 0x00, 0x3e, + 0x00, 0x33, 0x00, 0x32, 0x00, 0x31, 0x00, 0x30, + 0x00, 0x9a, 0x00, 0x99, 0x00, 0x98, 0x00, 0x97, + 0x00, 0x45, 0x00, 0x44, 0x00, 0x43, 0x00, 0x42, + 0xc0, 0x31, 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, + 0xc0, 0x0e, 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, + 0x00, 0x2f, 0x00, 0x96, 0x00, 0x41, 0x00, 0x07, + 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, + 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, + 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x14, + 0x00, 0x11, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x08, + 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x01, 0x00, + 0x00, 0x49, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, + 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, + 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, + 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, + 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, + 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, + 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x01, 0x01, + }, + { + 0x16, 0x03, 0x02, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x13, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x02, + 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, + 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, + 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, + 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, + 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, + 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, + 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, + 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, + 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, + 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, + 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, + 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, + 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, + 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, + 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, + 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, + 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, + 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, + 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, + 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, + 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, + 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, + 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, + 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, + 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, + 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, + 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, + 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, + 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, + 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, + 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, + 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, + 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, + 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, + 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, + 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, + 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, + 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, + 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, + 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, + 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, + 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, + 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, + 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, + 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, + 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, + 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, + 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, + 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, + 0x16, 0x03, 0x02, 0x01, 0x0f, 0x0c, 0x00, 0x01, + 0x0b, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, + 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, + 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, + 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, + 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, + 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, + 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, + 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, + 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, + 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, + 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, + 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, + 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, + 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, + 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, + 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, + 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, + 0x90, 0x33, 0x00, 0x80, 0x16, 0x83, 0x9b, 0xf9, + 0x72, 0xdb, 0x9f, 0x55, 0x02, 0xe1, 0x04, 0xf7, + 0xb5, 0x3f, 0x4c, 0x71, 0x13, 0x5a, 0x91, 0xe9, + 0x1d, 0xeb, 0x9d, 0x9c, 0xfb, 0x88, 0xef, 0xca, + 0xec, 0x7d, 0x9b, 0xdd, 0xd9, 0xee, 0x2b, 0x8e, + 0xef, 0xf8, 0xb6, 0xc7, 0x7d, 0xfe, 0xda, 0x7f, + 0x90, 0x2e, 0x53, 0xf1, 0x64, 0x95, 0xfc, 0x66, + 0xfc, 0x87, 0x27, 0xb6, 0x9f, 0xc8, 0x3a, 0x95, + 0x68, 0x17, 0xe1, 0x7d, 0xf1, 0x88, 0xe8, 0x17, + 0x5f, 0x99, 0x90, 0x3f, 0x47, 0x47, 0x81, 0x06, + 0xe2, 0x8e, 0x22, 0x56, 0x8f, 0xc2, 0x14, 0xe5, + 0x62, 0xa7, 0x0d, 0x41, 0x3c, 0xc7, 0x4a, 0x0a, + 0x74, 0x4b, 0xda, 0x00, 0x8e, 0x4f, 0x90, 0xe6, + 0xd7, 0x68, 0xe5, 0x8b, 0xf2, 0x3f, 0x53, 0x1d, + 0x7a, 0xe6, 0xb3, 0xe9, 0x8a, 0xc9, 0x4d, 0x19, + 0xa6, 0xcf, 0xf9, 0xed, 0x5e, 0x26, 0xdc, 0x90, + 0x1c, 0x41, 0xad, 0x7c, 0x16, 0x03, 0x02, 0x00, + 0x04, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x02, 0x00, 0x8a, 0x10, 0x00, 0x00, + 0x86, 0x85, 0x04, 0x01, 0x11, 0xf2, 0xa4, 0x2d, + 0x1a, 0x75, 0x6c, 0xbc, 0x2d, 0x91, 0x95, 0x07, + 0xbe, 0xd6, 0x41, 0x7a, 0xbb, 0xc2, 0x7b, 0xa6, + 0x9b, 0xe3, 0xdc, 0x41, 0x7f, 0x1e, 0x2e, 0xcc, + 0x6d, 0xa3, 0x85, 0x53, 0x98, 0x9f, 0x2d, 0xe6, + 0x3c, 0xb9, 0x82, 0xa6, 0x80, 0x53, 0x9b, 0x71, + 0xfd, 0x27, 0xe5, 0xe5, 0xdf, 0x13, 0xba, 0x56, + 0x62, 0x30, 0x4a, 0x57, 0x27, 0xa7, 0xcc, 0x26, + 0x54, 0xe8, 0x65, 0x6e, 0x4d, 0x00, 0xbf, 0x8a, + 0xcc, 0x89, 0x6a, 0x6c, 0x88, 0xda, 0x79, 0x4f, + 0xc5, 0xad, 0x6d, 0x1d, 0x7c, 0x53, 0x7b, 0x1a, + 0x96, 0xf2, 0xf8, 0x30, 0x01, 0x0b, 0xc2, 0xf0, + 0x78, 0x41, 0xf4, 0x0d, 0xe0, 0xbe, 0xb9, 0x36, + 0xe0, 0xb7, 0xee, 0x16, 0xeb, 0x25, 0x67, 0x04, + 0xc0, 0x2e, 0xd8, 0x34, 0x4a, 0x65, 0xa5, 0xf1, + 0x95, 0x75, 0xc7, 0x39, 0xa9, 0x68, 0xa9, 0x53, + 0x93, 0x5b, 0xca, 0x7b, 0x7f, 0xc0, 0x63, 0x14, + 0x03, 0x02, 0x00, 0x01, 0x01, 0x16, 0x03, 0x02, + 0x00, 0x40, 0x01, 0xb1, 0xae, 0x1b, 0x8a, 0x65, + 0xf8, 0x37, 0x50, 0x39, 0x76, 0xef, 0xaa, 0xda, + 0x84, 0xc9, 0x5f, 0x80, 0xdc, 0xfa, 0xe0, 0x46, + 0x5a, 0xc7, 0x77, 0x9d, 0x76, 0x03, 0xa6, 0xd5, + 0x0e, 0xbf, 0x25, 0x30, 0x5c, 0x99, 0x7d, 0xcd, + 0x2b, 0xaa, 0x2e, 0x8c, 0xdd, 0xda, 0xaa, 0xd7, + 0xf1, 0xf6, 0x33, 0x47, 0x51, 0x1e, 0x83, 0xa1, + 0x83, 0x04, 0xd2, 0xb2, 0xc8, 0xbc, 0x11, 0xc5, + 0x1a, 0x87, + }, + { + 0x16, 0x03, 0x02, 0x00, 0x72, 0x04, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xeb, 0x8b, 0xc7, 0xef, 0xba, 0xe8, 0x0f, 0x69, + 0xfe, 0xfb, 0xc3, 0x3d, 0x90, 0x5d, 0xd7, 0xb2, + 0x51, 0x64, 0xac, 0xc3, 0xae, 0x33, 0x03, 0x42, + 0x45, 0x2d, 0xa7, 0x57, 0xbd, 0xa3, 0x85, 0x64, + 0xa6, 0xfe, 0x5c, 0x33, 0x04, 0x93, 0xf2, 0x7c, + 0x06, 0x6d, 0xd7, 0xd7, 0xcf, 0x4a, 0xaf, 0xb2, + 0xdd, 0x06, 0xdc, 0x28, 0x14, 0x59, 0x23, 0x02, + 0xef, 0x97, 0x6a, 0xe8, 0xec, 0xca, 0x10, 0x44, + 0xcd, 0xb8, 0x50, 0x16, 0x46, 0x5a, 0x05, 0xda, + 0x04, 0xb3, 0x0e, 0xe9, 0xf0, 0x74, 0xc5, 0x23, + 0xc2, 0x0e, 0xa1, 0x54, 0x66, 0x7b, 0xe8, 0x14, + 0x03, 0x02, 0x00, 0x01, 0x01, 0x16, 0x03, 0x02, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6b, 0x43, 0x1c, 0x58, 0xbc, 0x85, + 0xf7, 0xc1, 0x76, 0xbc, 0x72, 0x33, 0x41, 0x6b, + 0xb8, 0xf8, 0xfd, 0x53, 0x21, 0xc2, 0x41, 0x1b, + 0x72, 0x4f, 0xce, 0x97, 0xca, 0x14, 0x23, 0x4d, + 0xbc, 0x44, 0xd6, 0xd7, 0xfc, 0xbc, 0xfd, 0xfd, + 0x5d, 0x33, 0x42, 0x1b, 0x52, 0x40, 0x0a, 0x2b, + 0x6c, 0x98, 0x17, 0x03, 0x02, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, + 0x31, 0xef, 0x03, 0x7d, 0xa5, 0x74, 0x92, 0x24, + 0x34, 0xae, 0x4e, 0xc9, 0xfc, 0x59, 0xcb, 0x64, + 0xf4, 0x45, 0xb1, 0xac, 0x02, 0xf2, 0x87, 0xe7, + 0x2f, 0xfd, 0x01, 0xca, 0x78, 0x02, 0x2e, 0x3a, + 0x38, 0xcd, 0xb1, 0xe0, 0xf2, 0x2e, 0xf6, 0x27, + 0xa0, 0xac, 0x1f, 0x91, 0x43, 0xc2, 0x3d, 0x15, + 0x03, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9f, 0x30, 0x24, 0x56, + 0x2c, 0xde, 0xa0, 0xe6, 0x44, 0x35, 0x30, 0x51, + 0xec, 0xd4, 0x69, 0x2d, 0x46, 0x64, 0x04, 0x21, + 0xfe, 0x7c, 0x4d, 0xc5, 0xd0, 0x8c, 0xf9, 0xd2, + 0x3f, 0x88, 0x69, 0xd5, + }, +} + +// $ go test -run TestRunServer -serve -clientauth 1 \ +// -ciphersuites=0xc011 -minversion=0x0303 -maxversion=0x0303 +var tls12ServerScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, + 0x1a, 0x03, 0x03, 0x51, 0xe5, 0x76, 0x84, 0x0e, + 0xb9, 0x17, 0xca, 0x08, 0x47, 0xd9, 0xbd, 0xd0, + 0x94, 0xd1, 0x97, 0xca, 0x5b, 0xe7, 0x20, 0xac, + 0x8e, 0xbb, 0xc7, 0x29, 0xe9, 0x26, 0xcf, 0x7d, + 0xb3, 0xdc, 0x99, 0x00, 0x00, 0x82, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, + 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, + 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, + 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, + 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, + 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, + 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, + 0x00, 0x07, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, + 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, + 0x00, 0x12, 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, + 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, + 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, + 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, + 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, + 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, + 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, + 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, + 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, + 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, + 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, + 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, + 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, + 0x00, 0x01, 0x01, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x11, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x03, + 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, + 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, + 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, + 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, + 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, + 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, + 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, + 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, + 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, + 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, + 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, + 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, + 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, + 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, + 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, + 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, + 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, + 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, + 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, + 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, + 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, + 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, + 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, + 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, + 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, + 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, + 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, + 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, + 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, + 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, + 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, + 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, + 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, + 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, + 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, + 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, + 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, + 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, + 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, + 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, + 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, + 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, + 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, + 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, + 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, + 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, + 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, + 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, + 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, + 0x16, 0x03, 0x03, 0x01, 0x11, 0x0c, 0x00, 0x01, + 0x0d, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, + 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, + 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, + 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, + 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, + 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, + 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, + 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, + 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, + 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, + 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, + 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, + 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, + 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, + 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, + 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, + 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, + 0x90, 0x33, 0x04, 0x01, 0x00, 0x80, 0x4a, 0xf9, + 0xf5, 0x0a, 0x61, 0x37, 0x7e, 0x4e, 0x92, 0xb5, + 0x1c, 0x91, 0x21, 0xb2, 0xb5, 0x17, 0x00, 0xbf, + 0x01, 0x5f, 0x30, 0xec, 0x62, 0x08, 0xd6, 0x9d, + 0x1a, 0x08, 0x05, 0x72, 0x8b, 0xf4, 0x49, 0x85, + 0xa7, 0xbf, 0x3f, 0x75, 0x58, 0x3e, 0x26, 0x82, + 0xc3, 0x28, 0x07, 0xf9, 0x41, 0x7d, 0x03, 0x14, + 0x3b, 0xc3, 0x05, 0x64, 0xff, 0x52, 0xf4, 0x75, + 0x6a, 0x87, 0xcd, 0xdf, 0x93, 0x31, 0x0a, 0x71, + 0x60, 0x17, 0xc6, 0x33, 0xf0, 0x79, 0xb6, 0x7b, + 0xd0, 0x9c, 0xa0, 0x5f, 0x74, 0x14, 0x2c, 0x5a, + 0xb4, 0x3f, 0x39, 0xf5, 0xe4, 0x9f, 0xbe, 0x6d, + 0x21, 0xd2, 0xa9, 0x42, 0xf7, 0xdc, 0xa6, 0x65, + 0xb7, 0x6a, 0x7e, 0x2e, 0x14, 0xd3, 0xf6, 0xf3, + 0x4b, 0x4c, 0x5b, 0x1a, 0x70, 0x7a, 0xbc, 0xb0, + 0x12, 0xf3, 0x6e, 0x0c, 0xcf, 0x43, 0x22, 0xae, + 0x5b, 0xba, 0x00, 0xf8, 0xfd, 0xaf, 0x16, 0x03, + 0x03, 0x00, 0x0f, 0x0d, 0x00, 0x00, 0x0b, 0x02, + 0x01, 0x40, 0x00, 0x04, 0x04, 0x01, 0x04, 0x03, + 0x00, 0x00, 0x16, 0x03, 0x03, 0x00, 0x04, 0x0e, + 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x03, 0x01, 0xfb, 0x0b, 0x00, 0x01, + 0xf7, 0x00, 0x01, 0xf4, 0x00, 0x01, 0xf1, 0x30, + 0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x58, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x00, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x30, 0x26, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, + 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d, + 0x31, 0x31, 0x31, 0x32, 0x30, 0x38, 0x30, 0x37, + 0x35, 0x35, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x31, + 0x32, 0x31, 0x32, 0x30, 0x37, 0x30, 0x38, 0x30, + 0x30, 0x31, 0x32, 0x5a, 0x30, 0x26, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x07, 0x41, 0x63, 0x6d, 0x65, 0x20, 0x43, 0x6f, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, + 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9c, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x03, 0x81, 0x8c, 0x00, + 0x30, 0x81, 0x88, 0x02, 0x81, 0x80, 0x4e, 0xd0, + 0x7b, 0x31, 0xe3, 0x82, 0x64, 0xd9, 0x59, 0xc0, + 0xc2, 0x87, 0xa4, 0x5e, 0x1e, 0x8b, 0x73, 0x33, + 0xc7, 0x63, 0x53, 0xdf, 0x66, 0x92, 0x06, 0x84, + 0xf6, 0x64, 0xd5, 0x8f, 0xe4, 0x36, 0xa7, 0x1d, + 0x2b, 0xe8, 0xb3, 0x20, 0x36, 0x45, 0x23, 0xb5, + 0xe3, 0x95, 0xae, 0xed, 0xe0, 0xf5, 0x20, 0x9c, + 0x8d, 0x95, 0xdf, 0x7f, 0x5a, 0x12, 0xef, 0x87, + 0xe4, 0x5b, 0x68, 0xe4, 0xe9, 0x0e, 0x74, 0xec, + 0x04, 0x8a, 0x7f, 0xde, 0x93, 0x27, 0xc4, 0x01, + 0x19, 0x7a, 0xbd, 0xf2, 0xdc, 0x3d, 0x14, 0xab, + 0xd0, 0x54, 0xca, 0x21, 0x0c, 0xd0, 0x4d, 0x6e, + 0x87, 0x2e, 0x5c, 0xc5, 0xd2, 0xbb, 0x4d, 0x4b, + 0x4f, 0xce, 0xb6, 0x2c, 0xf7, 0x7e, 0x88, 0xec, + 0x7c, 0xd7, 0x02, 0x91, 0x74, 0xa6, 0x1e, 0x0c, + 0x1a, 0xda, 0xe3, 0x4a, 0x5a, 0x2e, 0xde, 0x13, + 0x9c, 0x4c, 0x40, 0x88, 0x59, 0x93, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x32, 0x30, 0x30, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0xa0, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x06, + 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x08, 0x30, + 0x06, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x03, 0x81, 0x81, 0x00, + 0x36, 0x1f, 0xb3, 0x7a, 0x0c, 0x75, 0xc9, 0x6e, + 0x37, 0x46, 0x61, 0x2b, 0xd5, 0xbd, 0xc0, 0xa7, + 0x4b, 0xcc, 0x46, 0x9a, 0x81, 0x58, 0x7c, 0x85, + 0x79, 0x29, 0xc8, 0xc8, 0xc6, 0x67, 0xdd, 0x32, + 0x56, 0x45, 0x2b, 0x75, 0xb6, 0xe9, 0x24, 0xa9, + 0x50, 0x9a, 0xbe, 0x1f, 0x5a, 0xfa, 0x1a, 0x15, + 0xd9, 0xcc, 0x55, 0x95, 0x72, 0x16, 0x83, 0xb9, + 0xc2, 0xb6, 0x8f, 0xfd, 0x88, 0x8c, 0x38, 0x84, + 0x1d, 0xab, 0x5d, 0x92, 0x31, 0x13, 0x4f, 0xfd, + 0x83, 0x3b, 0xc6, 0x9d, 0xf1, 0x11, 0x62, 0xb6, + 0x8b, 0xec, 0xab, 0x67, 0xbe, 0xc8, 0x64, 0xb0, + 0x11, 0x50, 0x46, 0x58, 0x17, 0x6b, 0x99, 0x1c, + 0xd3, 0x1d, 0xfc, 0x06, 0xf1, 0x0e, 0xe5, 0x96, + 0xa8, 0x0c, 0xf9, 0x78, 0x20, 0xb7, 0x44, 0x18, + 0x51, 0x8d, 0x10, 0x7e, 0x4f, 0x94, 0x67, 0xdf, + 0xa3, 0x4e, 0x70, 0x73, 0x8e, 0x90, 0x91, 0x85, + 0x16, 0x03, 0x03, 0x00, 0x8a, 0x10, 0x00, 0x00, + 0x86, 0x85, 0x04, 0x01, 0x5d, 0x3a, 0x92, 0x59, + 0x7f, 0x9a, 0x22, 0x36, 0x0e, 0x1b, 0x1d, 0x2a, + 0x05, 0xb7, 0xa4, 0xb6, 0x5d, 0xfc, 0x51, 0x6e, + 0x15, 0xe5, 0x89, 0x7c, 0xe2, 0xfa, 0x87, 0x38, + 0x05, 0x79, 0x15, 0x92, 0xb4, 0x8f, 0x88, 0x8f, + 0x9d, 0x5d, 0xa0, 0xaf, 0xf8, 0xce, 0xf9, 0x6f, + 0x83, 0xf4, 0x08, 0x69, 0xe4, 0x91, 0xc5, 0xed, + 0xb9, 0xc5, 0xa8, 0x1f, 0x4b, 0xec, 0xef, 0x91, + 0xc1, 0xa3, 0x34, 0x24, 0x18, 0x00, 0x2d, 0xcd, + 0xe6, 0x44, 0xef, 0x5a, 0x3e, 0x52, 0x63, 0x5b, + 0x36, 0x1f, 0x7e, 0xce, 0x9e, 0xaa, 0xda, 0x8d, + 0xb5, 0xc9, 0xea, 0xd8, 0x1b, 0xd1, 0x1c, 0x7c, + 0x07, 0xfc, 0x3c, 0x2d, 0x70, 0x1f, 0xf9, 0x4d, + 0xcb, 0xaa, 0xad, 0x07, 0xd5, 0x6d, 0xbd, 0xa6, + 0x61, 0xf3, 0x2f, 0xa3, 0x9c, 0x45, 0x02, 0x4a, + 0xac, 0x6c, 0xb6, 0x37, 0x95, 0xb1, 0x4a, 0xb5, + 0x0a, 0x4e, 0x60, 0x67, 0xd7, 0xe0, 0x04, 0x16, + 0x03, 0x03, 0x00, 0x88, 0x0f, 0x00, 0x00, 0x84, + 0x04, 0x01, 0x00, 0x80, 0x08, 0x83, 0x53, 0xf0, + 0xf8, 0x14, 0xf5, 0xc2, 0xd1, 0x8b, 0xf0, 0xa5, + 0xc1, 0xd8, 0x1a, 0x36, 0x4b, 0x75, 0x77, 0x02, + 0x19, 0xd8, 0x11, 0x3f, 0x5a, 0x36, 0xfc, 0xe9, + 0x2b, 0x4b, 0xf9, 0xfe, 0xda, 0x8a, 0x0f, 0x6e, + 0x3d, 0xd3, 0x52, 0x87, 0xf7, 0x9c, 0x78, 0x39, + 0xa8, 0xf1, 0xd7, 0xf7, 0x4e, 0x35, 0x33, 0xf9, + 0xc5, 0x76, 0xa8, 0x12, 0xc4, 0x91, 0x33, 0x1d, + 0x93, 0x8c, 0xbf, 0xb1, 0x83, 0x00, 0x90, 0xc5, + 0x52, 0x3e, 0xe0, 0x0a, 0xe8, 0x92, 0x75, 0xdf, + 0x54, 0x5f, 0x9f, 0x95, 0x76, 0x62, 0xb5, 0x85, + 0x69, 0xa4, 0x86, 0x85, 0x6c, 0xf3, 0x6b, 0x2a, + 0x72, 0x7b, 0x4d, 0x42, 0x33, 0x67, 0x4a, 0xce, + 0xb5, 0xdb, 0x9b, 0xae, 0xc0, 0xb0, 0x10, 0xeb, + 0x3b, 0xf4, 0xc2, 0x9a, 0x64, 0x47, 0x4c, 0x1e, + 0xa5, 0x91, 0x7f, 0x6d, 0xd1, 0x03, 0xf5, 0x4a, + 0x90, 0x69, 0x18, 0xb1, 0x14, 0x03, 0x03, 0x00, + 0x01, 0x01, 0x16, 0x03, 0x03, 0x00, 0x24, 0x59, + 0xfc, 0x7e, 0xae, 0xb3, 0xbf, 0xab, 0x4d, 0xdb, + 0x4e, 0xab, 0xa9, 0x6d, 0x6b, 0x4c, 0x60, 0xb6, + 0x16, 0xe0, 0xab, 0x7f, 0x52, 0x2d, 0xa1, 0xfc, + 0xe1, 0x80, 0xd2, 0x8a, 0xa1, 0xe5, 0x8f, 0xa1, + 0x70, 0x93, 0x23, + }, + { + 0x16, 0x03, 0x03, 0x02, 0x67, 0x04, 0x00, 0x02, + 0x63, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xea, 0x8b, 0xc5, 0xef, 0xba, 0x64, 0xb7, 0x23, + 0x08, 0x86, 0x4f, 0x37, 0xe0, 0x8f, 0xbd, 0x75, + 0x71, 0x2b, 0xcb, 0x20, 0x75, 0x11, 0x3b, 0xa2, + 0x9e, 0x39, 0x3c, 0x03, 0xef, 0x6e, 0x41, 0xd7, + 0xcf, 0x1a, 0x2c, 0xf2, 0xfe, 0xc2, 0xd3, 0x65, + 0x59, 0x00, 0x9d, 0x03, 0xb4, 0xf2, 0x20, 0xe4, + 0x33, 0x80, 0xcd, 0xf6, 0xe4, 0x59, 0x22, 0xf7, + 0xfd, 0x88, 0x0e, 0xa4, 0x09, 0xc0, 0x0d, 0x10, + 0x80, 0x10, 0x79, 0xee, 0x70, 0x96, 0xdb, 0x22, + 0x8b, 0xb7, 0xac, 0xe0, 0x98, 0xad, 0xe9, 0xe3, + 0xcb, 0xea, 0x9f, 0xe6, 0x83, 0x28, 0x7c, 0x7e, + 0x4e, 0x9a, 0x8d, 0xd9, 0xf3, 0x86, 0xf4, 0x89, + 0x8b, 0x79, 0x8f, 0xbb, 0xe9, 0x74, 0x02, 0x02, + 0x14, 0x04, 0xea, 0xba, 0x16, 0x10, 0xa1, 0x85, + 0xbe, 0x4e, 0x4e, 0x92, 0xc5, 0x83, 0xf6, 0x1e, + 0x1f, 0xd4, 0x25, 0xc2, 0xc2, 0xb9, 0xce, 0x33, + 0x63, 0x66, 0x79, 0x1f, 0x54, 0x35, 0xc1, 0xe8, + 0x89, 0x34, 0x78, 0x94, 0x36, 0x14, 0xef, 0x01, + 0x1f, 0xf1, 0xbd, 0x77, 0x2c, 0x4d, 0xac, 0x5c, + 0x5c, 0x4a, 0xc6, 0xed, 0xd8, 0x0e, 0x72, 0x84, + 0x83, 0xdc, 0x56, 0x84, 0xc8, 0xf3, 0x89, 0x56, + 0xfd, 0x89, 0xc1, 0xc9, 0x9a, 0x29, 0x91, 0x7e, + 0x19, 0xe9, 0x8b, 0x5b, 0x11, 0x15, 0x4e, 0x6c, + 0xf4, 0x89, 0xe7, 0x6d, 0x68, 0x1e, 0xf9, 0x6c, + 0x23, 0x72, 0x05, 0x68, 0x82, 0x60, 0x84, 0x1f, + 0x83, 0x20, 0x09, 0x86, 0x10, 0x81, 0xec, 0xec, + 0xdc, 0x25, 0x53, 0x20, 0xfa, 0xa9, 0x41, 0x64, + 0xd6, 0x20, 0xf3, 0xf4, 0x52, 0xf2, 0x80, 0x62, + 0x83, 0xc9, 0x23, 0x66, 0x44, 0x95, 0x5a, 0x99, + 0x8a, 0xe1, 0x26, 0x63, 0xc1, 0x8b, 0x31, 0xf9, + 0x21, 0x06, 0x77, 0x04, 0x27, 0xf2, 0x0c, 0x63, + 0x83, 0x45, 0xa0, 0xa9, 0x7b, 0xcf, 0xdf, 0xd7, + 0x56, 0x75, 0xbc, 0xdd, 0x95, 0x36, 0xb1, 0x75, + 0x39, 0x05, 0x00, 0x3c, 0x8a, 0x79, 0xd6, 0xe9, + 0xf0, 0x4b, 0xdc, 0x51, 0x6b, 0x01, 0x94, 0x16, + 0x87, 0x12, 0x92, 0x6c, 0x07, 0xc1, 0xf5, 0x58, + 0xb7, 0x2a, 0x81, 0xf5, 0xa0, 0x37, 0x8b, 0xa6, + 0x22, 0xfe, 0x28, 0x0a, 0x7e, 0x68, 0xe2, 0xda, + 0x6c, 0x53, 0xee, 0x0e, 0x8d, 0x2d, 0x8b, 0x0b, + 0xda, 0xf8, 0x99, 0x3e, 0x0e, 0xed, 0x9f, 0xc1, + 0x2b, 0xf6, 0xfe, 0xe9, 0x52, 0x38, 0x7b, 0x83, + 0x9a, 0x50, 0xa6, 0xd7, 0x49, 0x83, 0x43, 0x7e, + 0x82, 0xec, 0xc7, 0x09, 0x3d, 0x3d, 0xb1, 0xee, + 0xe8, 0xc5, 0x6a, 0xc3, 0x3d, 0x4b, 0x4c, 0x6a, + 0xbb, 0x0b, 0x2c, 0x24, 0x2e, 0xdb, 0x7d, 0x57, + 0x87, 0xb4, 0x80, 0xa5, 0xae, 0xff, 0x54, 0xa8, + 0xa5, 0x27, 0x69, 0x95, 0xc8, 0xe7, 0x79, 0xc7, + 0x89, 0x2a, 0x73, 0x49, 0xcb, 0xf5, 0xc5, 0xbc, + 0x4a, 0xe0, 0x73, 0xa9, 0xbc, 0x88, 0x64, 0x96, + 0x98, 0xa5, 0x1e, 0xe3, 0x43, 0xc1, 0x7d, 0x78, + 0xc7, 0x94, 0x72, 0xd4, 0x2c, 0x6e, 0x85, 0x39, + 0x9a, 0xaf, 0xdb, 0xa1, 0xe9, 0xe2, 0xcb, 0x37, + 0x04, 0xc6, 0x8c, 0x81, 0xd3, 0x2a, 0xb7, 0xbe, + 0x6c, 0x07, 0x1f, 0x5e, 0xd9, 0x00, 0xd2, 0xf7, + 0xe1, 0xa7, 0xbc, 0x0c, 0xb6, 0x6d, 0xfb, 0x3f, + 0x3d, 0x24, 0xaa, 0xfb, 0x7e, 0xe1, 0xb5, 0x1b, + 0xff, 0x38, 0xaa, 0x69, 0x59, 0x38, 0x52, 0x9a, + 0x0e, 0x6d, 0xbc, 0xde, 0x4f, 0x13, 0x09, 0x17, + 0xc4, 0xa9, 0x05, 0x84, 0xbc, 0x50, 0xef, 0x40, + 0xb0, 0x4c, 0x24, 0x32, 0xed, 0x94, 0x2c, 0xdd, + 0xda, 0x20, 0x24, 0x67, 0xe2, 0xea, 0x71, 0x3d, + 0x4a, 0x04, 0x0d, 0x98, 0x29, 0x20, 0x4c, 0xeb, + 0x70, 0xce, 0x45, 0x9e, 0x5a, 0xaf, 0xb6, 0xa3, + 0x92, 0xc8, 0x28, 0xf2, 0xe3, 0xe8, 0x8a, 0x5d, + 0x0a, 0x33, 0x79, 0x9b, 0x6a, 0xf3, 0x30, 0x01, + 0x1d, 0x47, 0xbd, 0x01, 0xcc, 0x4d, 0x71, 0xc0, + 0x56, 0xfa, 0xfd, 0x37, 0xed, 0x0f, 0x27, 0xc0, + 0xbb, 0xa0, 0xee, 0xc3, 0x79, 0x8b, 0xe7, 0x41, + 0x8f, 0xfa, 0x3a, 0xcb, 0x45, 0x3b, 0x85, 0x9f, + 0x06, 0x90, 0xb2, 0x51, 0xc0, 0x48, 0x10, 0xac, + 0x2a, 0xec, 0xec, 0x48, 0x7a, 0x19, 0x47, 0xc4, + 0x2a, 0xeb, 0xb3, 0xa2, 0x07, 0x22, 0x32, 0x78, + 0xf4, 0x73, 0x5e, 0x92, 0x42, 0x15, 0xa1, 0x90, + 0x91, 0xd0, 0xeb, 0x12, 0x14, 0x03, 0x03, 0x00, + 0x01, 0x01, 0x16, 0x03, 0x03, 0x00, 0x24, 0x45, + 0x4b, 0x80, 0x42, 0x46, 0xde, 0xbb, 0xe7, 0x76, + 0xd1, 0x33, 0x92, 0xfc, 0x46, 0x17, 0x6d, 0x21, + 0xf6, 0x0e, 0x16, 0xca, 0x9b, 0x9b, 0x04, 0x65, + 0x16, 0x40, 0x44, 0x64, 0xbc, 0x58, 0xfa, 0x2a, + 0x49, 0xe9, 0xed, 0x17, 0x03, 0x03, 0x00, 0x21, + 0x89, 0x71, 0xcd, 0x56, 0x54, 0xbf, 0x73, 0xde, + 0xfb, 0x4b, 0x4e, 0xf1, 0x7f, 0xc6, 0x75, 0xa6, + 0xbd, 0x6b, 0x6c, 0xd9, 0xdc, 0x0c, 0x71, 0xb4, + 0xb9, 0xbb, 0x6e, 0xfa, 0x9e, 0xc7, 0xc7, 0x4c, + 0x24, 0x15, 0x03, 0x03, 0x00, 0x16, 0x62, 0xea, + 0x65, 0x69, 0x68, 0x4a, 0xce, 0xa7, 0x9e, 0xce, + 0xc0, 0xf1, 0x5c, 0x96, 0xd9, 0x1f, 0x49, 0xac, + 0x2d, 0x05, 0x89, 0x94, + }, +} + // cert.pem and key.pem were generated with generate_cert.go // Thus, they have no ExtKeyUsage fields and trigger an error // when verification is turned on. @@ -1999,3 +3167,630 @@ qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN 1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvA -----END RSA PRIVATE KEY----- */ + +var clientECDSACertificate = loadPEMCert(` +-----BEGIN CERTIFICATE----- +MIIB/DCCAV4CCQCaMIRsJjXZFzAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQwHhcNMTIxMTE0MTMyNTUzWhcNMjIxMTEyMTMyNTUzWjBBMQswCQYDVQQG +EwJBVTEMMAoGA1UECBMDTlNXMRAwDgYDVQQHEwdQeXJtb250MRIwEAYDVQQDEwlK +b2VsIFNpbmcwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACVjJF1FMBexFe01MNv +ja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd3kfDdq0Z9kUs +jLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx+U56jb0JuK7q +ixgnTy5w/hOWusPTQBbNZU6sER7m8TAJBgcqhkjOPQQBA4GMADCBiAJCAOAUxGBg +C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa +2RU6+b0DeoeiIzXsAkIBo9SKeDUcSpoj0gq+KxAxnZxfvuiRs9oa9V2jI/Umi0Vw +jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes= +-----END CERTIFICATE----- +`) + +/* corresponding key for cert is: +-----BEGIN EC PARAMETERS----- +BgUrgQQAIw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8 +k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1 +FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd +3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx ++U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q== +-----END EC PRIVATE KEY----- +*/ +var clientauthECDSATests = []clientauthTest{ + // Server asks for cert with empty CA list, client gives one + // go test -run "TestRunServer" -serve \ + // -clientauth 1 -ciphersuites=0xc00a + // openssl s_client -host 127.0.0.1 -port 10443 \ + // -cipher ECDHE-ECDSA-AES256-SHA -key client.key -cert client.crt + {"RequestClientCert, client gives it", RequestClientCert, []*x509.Certificate{clientECDSACertificate}, [][]byte{ + { + 0x16, 0x03, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x9c, 0x03, 0x03, 0x51, 0xe5, 0x73, 0xc5, 0xae, + 0x51, 0x94, 0xb4, 0xf2, 0xe8, 0xf6, 0x03, 0x0e, + 0x3b, 0x34, 0xaf, 0xf0, 0xdc, 0x1b, 0xcc, 0xd8, + 0x0c, 0x45, 0x82, 0xd4, 0xd6, 0x76, 0x04, 0x6e, + 0x4f, 0x7a, 0x24, 0x00, 0x00, 0x04, 0xc0, 0x0a, + 0x00, 0xff, 0x01, 0x00, 0x00, 0x6f, 0x00, 0x0b, + 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, + 0x00, 0x34, 0x00, 0x32, 0x00, 0x0e, 0x00, 0x0d, + 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x18, + 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x17, + 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x14, + 0x00, 0x15, 0x00, 0x04, 0x00, 0x05, 0x00, 0x12, + 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, + 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, + 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, + 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, + 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, + 0x00, 0x0f, 0x00, 0x01, 0x01, + }, + { + 0x16, 0x03, 0x01, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0a, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x01, + 0x02, 0x0e, 0x0b, 0x00, 0x02, 0x0a, 0x00, 0x02, + 0x07, 0x00, 0x02, 0x04, 0x30, 0x82, 0x02, 0x00, + 0x30, 0x82, 0x01, 0x62, 0x02, 0x09, 0x00, 0xb8, + 0xbf, 0x2d, 0x47, 0xa0, 0xd2, 0xeb, 0xf4, 0x30, + 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x04, 0x01, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x31, + 0x31, 0x32, 0x32, 0x31, 0x35, 0x30, 0x36, 0x33, + 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x31, 0x31, + 0x32, 0x30, 0x31, 0x35, 0x30, 0x36, 0x33, 0x32, + 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, + 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, + 0x30, 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, + 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, + 0x00, 0x04, 0x00, 0xc4, 0xa1, 0xed, 0xbe, 0x98, + 0xf9, 0x0b, 0x48, 0x73, 0x36, 0x7e, 0xc3, 0x16, + 0x56, 0x11, 0x22, 0xf2, 0x3d, 0x53, 0xc3, 0x3b, + 0x4d, 0x21, 0x3d, 0xcd, 0x6b, 0x75, 0xe6, 0xf6, + 0xb0, 0xdc, 0x9a, 0xdf, 0x26, 0xc1, 0xbc, 0xb2, + 0x87, 0xf0, 0x72, 0x32, 0x7c, 0xb3, 0x64, 0x2f, + 0x1c, 0x90, 0xbc, 0xea, 0x68, 0x23, 0x10, 0x7e, + 0xfe, 0xe3, 0x25, 0xc0, 0x48, 0x3a, 0x69, 0xe0, + 0x28, 0x6d, 0xd3, 0x37, 0x00, 0xef, 0x04, 0x62, + 0xdd, 0x0d, 0xa0, 0x9c, 0x70, 0x62, 0x83, 0xd8, + 0x81, 0xd3, 0x64, 0x31, 0xaa, 0x9e, 0x97, 0x31, + 0xbd, 0x96, 0xb0, 0x68, 0xc0, 0x9b, 0x23, 0xde, + 0x76, 0x64, 0x3f, 0x1a, 0x5c, 0x7f, 0xe9, 0x12, + 0x0e, 0x58, 0x58, 0xb6, 0x5f, 0x70, 0xdd, 0x9b, + 0xd8, 0xea, 0xd5, 0xd7, 0xf5, 0xd5, 0xcc, 0xb9, + 0xb6, 0x9f, 0x30, 0x66, 0x5b, 0x66, 0x9a, 0x20, + 0xe2, 0x27, 0xe5, 0xbf, 0xfe, 0x3b, 0x30, 0x09, + 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x01, 0x03, 0x81, 0x8c, 0x00, 0x30, 0x81, 0x88, + 0x02, 0x42, 0x01, 0x88, 0xa2, 0x4f, 0xeb, 0xe2, + 0x45, 0xc5, 0x48, 0x7d, 0x1b, 0xac, 0xf5, 0xed, + 0x98, 0x9d, 0xae, 0x47, 0x70, 0xc0, 0x5e, 0x1b, + 0xb6, 0x2f, 0xbd, 0xf1, 0xb6, 0x4d, 0xb7, 0x61, + 0x40, 0xd3, 0x11, 0xa2, 0xce, 0xee, 0x0b, 0x7e, + 0x92, 0x7e, 0xff, 0x76, 0x9d, 0xc3, 0x3b, 0x7e, + 0xa5, 0x3f, 0xce, 0xfa, 0x10, 0xe2, 0x59, 0xec, + 0x47, 0x2d, 0x7c, 0xac, 0xda, 0x4e, 0x97, 0x0e, + 0x15, 0xa0, 0x6f, 0xd0, 0x02, 0x42, 0x01, 0x4d, + 0xfc, 0xbe, 0x67, 0x13, 0x9c, 0x2d, 0x05, 0x0e, + 0xbd, 0x3f, 0xa3, 0x8c, 0x25, 0xc1, 0x33, 0x13, + 0x83, 0x0d, 0x94, 0x06, 0xbb, 0xd4, 0x37, 0x7a, + 0xf6, 0xec, 0x7a, 0xc9, 0x86, 0x2e, 0xdd, 0xd7, + 0x11, 0x69, 0x7f, 0x85, 0x7c, 0x56, 0xde, 0xfb, + 0x31, 0x78, 0x2b, 0xe4, 0xc7, 0x78, 0x0d, 0xae, + 0xcb, 0xbe, 0x9e, 0x4e, 0x36, 0x24, 0x31, 0x7b, + 0x6a, 0x0f, 0x39, 0x95, 0x12, 0x07, 0x8f, 0x2a, + 0x16, 0x03, 0x01, 0x01, 0x1a, 0x0c, 0x00, 0x01, + 0x16, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, + 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, + 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, + 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, + 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, + 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, + 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, + 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, + 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, + 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, + 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, + 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, + 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, + 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, + 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, + 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, + 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, + 0x90, 0x33, 0x00, 0x8b, 0x30, 0x81, 0x88, 0x02, + 0x42, 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, + 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, + 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, + 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, + 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, + 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, + 0xff, 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, + 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, + 0xe5, 0xbd, 0x66, 0x02, 0x42, 0x00, 0xad, 0x7d, + 0x06, 0x35, 0xab, 0xec, 0x8d, 0xac, 0xd4, 0xba, + 0x1b, 0x49, 0x5e, 0x05, 0x5f, 0xf0, 0x97, 0x93, + 0x82, 0xb8, 0x2b, 0x8d, 0x91, 0x98, 0x63, 0x8e, + 0xb4, 0x14, 0x62, 0xdb, 0x1e, 0xc9, 0x2b, 0x30, + 0xf8, 0x41, 0x9b, 0xa6, 0xe6, 0xbc, 0xde, 0x0e, + 0x68, 0x30, 0x21, 0xf4, 0xa8, 0xa9, 0x1b, 0xec, + 0x44, 0x4f, 0x5d, 0x02, 0x2f, 0x60, 0x45, 0x60, + 0xba, 0xe0, 0x4e, 0xc0, 0xd4, 0x3b, 0x01, 0x16, + 0x03, 0x01, 0x00, 0x09, 0x0d, 0x00, 0x00, 0x05, + 0x02, 0x01, 0x40, 0x00, 0x00, 0x16, 0x03, 0x01, + 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x01, 0x02, 0x0a, 0x0b, 0x00, 0x02, + 0x06, 0x00, 0x02, 0x03, 0x00, 0x02, 0x00, 0x30, + 0x82, 0x01, 0xfc, 0x30, 0x82, 0x01, 0x5e, 0x02, + 0x09, 0x00, 0x9a, 0x30, 0x84, 0x6c, 0x26, 0x35, + 0xd9, 0x17, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, + 0x31, 0x32, 0x31, 0x31, 0x31, 0x34, 0x31, 0x33, + 0x32, 0x35, 0x35, 0x33, 0x5a, 0x17, 0x0d, 0x32, + 0x32, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x32, + 0x35, 0x35, 0x33, 0x5a, 0x30, 0x41, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x55, 0x31, 0x0c, 0x30, 0x0a, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x13, 0x03, 0x4e, 0x53, + 0x57, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x13, 0x07, 0x50, 0x79, 0x72, 0x6d, + 0x6f, 0x6e, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x4a, 0x6f, + 0x65, 0x6c, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x30, + 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, + 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, 0x00, + 0x04, 0x00, 0x95, 0x8c, 0x91, 0x75, 0x14, 0xc0, + 0x5e, 0xc4, 0x57, 0xb4, 0xd4, 0xc3, 0x6f, 0x8d, + 0xae, 0x68, 0x1e, 0xdd, 0x6f, 0xce, 0x86, 0xe1, + 0x7e, 0x6e, 0xb2, 0x48, 0x3e, 0x81, 0xe5, 0x4e, + 0xe2, 0xc6, 0x88, 0x4b, 0x64, 0xdc, 0xf5, 0x30, + 0xbb, 0xd3, 0xff, 0x65, 0xcc, 0x5b, 0xf4, 0xdd, + 0xb5, 0x6a, 0x3e, 0x3e, 0xd0, 0x1d, 0xde, 0x47, + 0xc3, 0x76, 0xad, 0x19, 0xf6, 0x45, 0x2c, 0x8c, + 0xbc, 0xd8, 0x1d, 0x01, 0x4c, 0x1f, 0x70, 0x90, + 0x46, 0x76, 0x48, 0x8b, 0x8f, 0x83, 0xcc, 0x4a, + 0x5c, 0x8f, 0x40, 0x76, 0xda, 0xe0, 0x89, 0xec, + 0x1d, 0x2b, 0xc4, 0x4e, 0x30, 0x76, 0x28, 0x41, + 0xb2, 0x62, 0xa8, 0xfb, 0x5b, 0xf1, 0xf9, 0x4e, + 0x7a, 0x8d, 0xbd, 0x09, 0xb8, 0xae, 0xea, 0x8b, + 0x18, 0x27, 0x4f, 0x2e, 0x70, 0xfe, 0x13, 0x96, + 0xba, 0xc3, 0xd3, 0x40, 0x16, 0xcd, 0x65, 0x4e, + 0xac, 0x11, 0x1e, 0xe6, 0xf1, 0x30, 0x09, 0x06, + 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, + 0x03, 0x81, 0x8c, 0x00, 0x30, 0x81, 0x88, 0x02, + 0x42, 0x00, 0xe0, 0x14, 0xc4, 0x60, 0x60, 0x0b, + 0x72, 0x68, 0xb0, 0x32, 0x5d, 0x61, 0x4a, 0x02, + 0x74, 0x5c, 0xc2, 0x81, 0xb9, 0x16, 0xa8, 0x3f, + 0x29, 0xc8, 0x36, 0xc7, 0x81, 0xff, 0x6c, 0xb6, + 0x5b, 0xd9, 0x70, 0xf1, 0x38, 0x3b, 0x50, 0x48, + 0x28, 0x94, 0xcb, 0x09, 0x1a, 0x52, 0xf1, 0x5d, + 0xee, 0x8d, 0xf2, 0xb9, 0xf0, 0xf0, 0xda, 0xd9, + 0x15, 0x3a, 0xf9, 0xbd, 0x03, 0x7a, 0x87, 0xa2, + 0x23, 0x35, 0xec, 0x02, 0x42, 0x01, 0xa3, 0xd4, + 0x8a, 0x78, 0x35, 0x1c, 0x4a, 0x9a, 0x23, 0xd2, + 0x0a, 0xbe, 0x2b, 0x10, 0x31, 0x9d, 0x9c, 0x5f, + 0xbe, 0xe8, 0x91, 0xb3, 0xda, 0x1a, 0xf5, 0x5d, + 0xa3, 0x23, 0xf5, 0x26, 0x8b, 0x45, 0x70, 0x8d, + 0x65, 0x62, 0x9b, 0x7e, 0x01, 0x99, 0x3d, 0x18, + 0xf6, 0x10, 0x9a, 0x38, 0x61, 0x9b, 0x2e, 0x57, + 0xe4, 0xfa, 0xcc, 0xb1, 0x8a, 0xce, 0xe2, 0x23, + 0xa0, 0x87, 0xf0, 0xe1, 0x67, 0x51, 0xeb, 0x16, + 0x03, 0x01, 0x00, 0x8a, 0x10, 0x00, 0x00, 0x86, + 0x85, 0x04, 0x00, 0xcd, 0x1c, 0xe8, 0x66, 0x5b, + 0xa8, 0x9d, 0x83, 0x2f, 0x7e, 0x1d, 0x0b, 0x59, + 0x23, 0xbc, 0x30, 0xcf, 0xa3, 0xaf, 0x21, 0xdc, + 0xf2, 0x57, 0x49, 0x56, 0x30, 0x25, 0x7c, 0x84, + 0x5d, 0xad, 0xaa, 0x9c, 0x7b, 0x2a, 0x95, 0x58, + 0x3d, 0x30, 0x87, 0x01, 0x3b, 0xb7, 0xea, 0xcb, + 0xc4, 0xa3, 0xeb, 0x22, 0xbf, 0x2d, 0x61, 0x17, + 0x8c, 0x9b, 0xe8, 0x1b, 0xb2, 0x87, 0x16, 0x78, + 0xd5, 0xfd, 0x8b, 0xdd, 0x00, 0x0f, 0xda, 0x8e, + 0xfd, 0x28, 0x36, 0xeb, 0xe4, 0xc5, 0x42, 0x14, + 0xc7, 0xbd, 0x29, 0x5e, 0x9a, 0xed, 0x5e, 0xc1, + 0xf7, 0xf4, 0xbd, 0xbd, 0x15, 0x9c, 0xe8, 0x44, + 0x71, 0xa7, 0xb6, 0xe9, 0xfa, 0x7e, 0x97, 0xcb, + 0x96, 0x3e, 0x53, 0x76, 0xfb, 0x11, 0x1f, 0x36, + 0x8f, 0x30, 0xfb, 0x71, 0x3a, 0x75, 0x3a, 0x25, + 0x7b, 0xa2, 0xc1, 0xf9, 0x3e, 0x58, 0x5f, 0x07, + 0x16, 0xed, 0xe1, 0xf7, 0xc1, 0xb1, 0x16, 0x03, + 0x01, 0x00, 0x90, 0x0f, 0x00, 0x00, 0x8c, 0x00, + 0x8a, 0x30, 0x81, 0x87, 0x02, 0x42, 0x00, 0xb2, + 0xd3, 0x91, 0xe6, 0xd5, 0x9b, 0xb2, 0xb8, 0x03, + 0xf4, 0x85, 0x4d, 0x43, 0x79, 0x1f, 0xb6, 0x6f, + 0x0c, 0xcd, 0x67, 0x5f, 0x5e, 0xca, 0xee, 0xb3, + 0xe4, 0xab, 0x1e, 0x58, 0xc3, 0x04, 0xa9, 0x8a, + 0xa7, 0xcf, 0xaa, 0x33, 0x88, 0xd5, 0x35, 0xd2, + 0x80, 0x8f, 0xfa, 0x1b, 0x3c, 0x3d, 0xf7, 0x80, + 0x50, 0xde, 0x80, 0x30, 0x64, 0xee, 0xc0, 0xb3, + 0x91, 0x6e, 0x5d, 0x1e, 0xc0, 0xdc, 0x3a, 0x93, + 0x02, 0x41, 0x4e, 0xca, 0x98, 0x41, 0x8c, 0x36, + 0xf2, 0x12, 0xbf, 0x8e, 0x0f, 0x69, 0x8e, 0xf8, + 0x7b, 0x9d, 0xba, 0x9c, 0x5c, 0x48, 0x79, 0xf4, + 0xba, 0x3d, 0x06, 0xa5, 0xab, 0x47, 0xe0, 0x1a, + 0x45, 0x28, 0x3a, 0x8f, 0xbf, 0x14, 0x24, 0x36, + 0xd1, 0x1d, 0x29, 0xdc, 0xde, 0x72, 0x5b, 0x76, + 0x41, 0x67, 0xe8, 0xe5, 0x71, 0x4a, 0x77, 0xe9, + 0xed, 0x02, 0x19, 0xdd, 0xe4, 0xaa, 0xe9, 0x2d, + 0xe7, 0x47, 0x32, 0x14, 0x03, 0x01, 0x00, 0x01, + 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xfa, 0xc3, + 0xf2, 0x35, 0xd0, 0x6d, 0x32, 0x78, 0x6a, 0xd6, + 0xe6, 0x70, 0x5e, 0x00, 0x4c, 0x35, 0xf1, 0xe0, + 0x21, 0xcf, 0xc3, 0x78, 0xcd, 0xe0, 0x2b, 0x0b, + 0xf4, 0xeb, 0xf9, 0xc0, 0x38, 0xf2, 0x9a, 0x31, + 0x55, 0x07, 0x2b, 0x8d, 0x68, 0x40, 0x31, 0x08, + 0xaa, 0xe3, 0x16, 0xcf, 0x4b, 0xd4, + }, + { + 0x16, 0x03, 0x01, 0x02, 0x76, 0x04, 0x00, 0x02, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xe8, 0x8b, 0xde, 0xef, 0xba, 0xf9, 0xdb, 0x95, + 0x24, 0xa5, 0x49, 0xb3, 0x23, 0xd8, 0x73, 0x88, + 0x50, 0x42, 0xed, 0xeb, 0xa3, 0xd8, 0xab, 0x31, + 0x9c, 0xd0, 0x00, 0x01, 0xef, 0xc0, 0xbf, 0xab, + 0x59, 0x55, 0xb5, 0xb9, 0xef, 0xa5, 0xa6, 0xec, + 0x69, 0xed, 0x00, 0x2f, 0x47, 0xdb, 0x75, 0x52, + 0x0c, 0xe5, 0x86, 0xb7, 0x02, 0x59, 0x22, 0xf7, + 0xfd, 0x8b, 0xff, 0xa4, 0x09, 0xc0, 0x1c, 0x10, + 0x80, 0x10, 0x7f, 0x4c, 0x7a, 0x94, 0x40, 0x10, + 0x0d, 0xda, 0x8a, 0xe5, 0x4a, 0xbc, 0xd0, 0xc0, + 0x4b, 0xa5, 0x33, 0x97, 0xc6, 0xe7, 0x40, 0x7f, + 0x7f, 0x8c, 0xf9, 0xf8, 0xc8, 0xb8, 0xfb, 0x8c, + 0xdd, 0x28, 0x81, 0xae, 0xfd, 0x37, 0x20, 0x3a, + 0x40, 0x37, 0x99, 0xc4, 0x21, 0x01, 0xc4, 0x91, + 0xb0, 0x5e, 0x11, 0xc5, 0xa9, 0xfd, 0x9a, 0x02, + 0x7e, 0x97, 0x6a, 0x86, 0x89, 0xb8, 0xc1, 0x32, + 0x4c, 0x7e, 0x6d, 0x47, 0x61, 0x0e, 0xe3, 0xc2, + 0xf0, 0x62, 0x3c, 0xc6, 0x71, 0x4f, 0xbb, 0x47, + 0x65, 0xb1, 0xd9, 0x22, 0x79, 0x15, 0xea, 0x1f, + 0x4b, 0x2a, 0x8a, 0xa4, 0xc8, 0x73, 0x34, 0xba, + 0x83, 0xe4, 0x70, 0x99, 0xc9, 0xcf, 0xbe, 0x64, + 0x99, 0xb9, 0xfa, 0xe9, 0xaf, 0x5d, 0xc7, 0x20, + 0x26, 0xde, 0xc5, 0x06, 0x12, 0x36, 0x4f, 0x4d, + 0xc0, 0xbb, 0x81, 0x5b, 0x5e, 0x38, 0xc3, 0x07, + 0x21, 0x04, 0x1a, 0x53, 0x9c, 0x59, 0xac, 0x2d, + 0xe6, 0xa5, 0x93, 0xa5, 0x19, 0xc6, 0xb0, 0xf7, + 0x56, 0x5d, 0xdf, 0xd1, 0xf4, 0xfd, 0x44, 0x6d, + 0xc6, 0xa2, 0x31, 0xa7, 0x35, 0x42, 0x18, 0x50, + 0x0c, 0x4f, 0x6e, 0xe3, 0x3b, 0xa3, 0xaa, 0x1c, + 0xbe, 0x41, 0x0d, 0xce, 0x6c, 0x62, 0xe1, 0x96, + 0x2d, 0xbd, 0x14, 0x31, 0xe3, 0xc4, 0x5b, 0xbf, + 0xf6, 0xde, 0xec, 0x42, 0xe8, 0xc7, 0x2a, 0x0b, + 0xdb, 0x2d, 0x7c, 0xf0, 0x3f, 0x45, 0x32, 0x45, + 0x09, 0x47, 0x09, 0x0f, 0x21, 0x22, 0x45, 0x06, + 0x11, 0xb8, 0xf9, 0xe6, 0x67, 0x90, 0x4b, 0x4a, + 0xde, 0x81, 0xfb, 0xeb, 0xe7, 0x9a, 0x08, 0x30, + 0xcf, 0x51, 0xe1, 0xd9, 0xfa, 0x79, 0xa3, 0xcc, + 0x65, 0x1a, 0x83, 0x86, 0xc9, 0x7a, 0x41, 0xf5, + 0xdf, 0xa0, 0x7c, 0x44, 0x23, 0x17, 0xf3, 0x62, + 0xe8, 0xa9, 0x31, 0x1e, 0x6b, 0x05, 0x4b, 0x4f, + 0x9d, 0x91, 0x46, 0x92, 0xa6, 0x25, 0x32, 0xca, + 0xa1, 0x75, 0xda, 0xe6, 0x80, 0x3e, 0x7f, 0xd1, + 0x26, 0x57, 0x07, 0x42, 0xe4, 0x91, 0xff, 0xbd, + 0x44, 0xae, 0x98, 0x5c, 0x1d, 0xdf, 0x11, 0xe3, + 0xae, 0x87, 0x5e, 0xb7, 0x69, 0xad, 0x34, 0x7f, + 0x3a, 0x07, 0x7c, 0xdf, 0xfc, 0x76, 0x17, 0x8b, + 0x62, 0xc8, 0xe1, 0x78, 0x2a, 0xc8, 0xb9, 0x8a, + 0xbb, 0x5c, 0xfb, 0x38, 0x74, 0x91, 0x6e, 0x12, + 0x0c, 0x1f, 0x8e, 0xe1, 0xc2, 0x01, 0xd8, 0x9d, + 0x23, 0x0f, 0xc4, 0x67, 0x5d, 0xe5, 0x67, 0x4b, + 0x94, 0x6e, 0x69, 0x72, 0x90, 0x2d, 0x52, 0x78, + 0x8e, 0x61, 0xba, 0xdf, 0x4e, 0xf5, 0xdc, 0xfb, + 0x73, 0xbe, 0x03, 0x70, 0xd9, 0x01, 0x30, 0xf3, + 0xa1, 0xbb, 0x9a, 0x5f, 0xec, 0x9e, 0xed, 0x8d, + 0xdd, 0x53, 0xfd, 0x60, 0xc3, 0x2b, 0x7a, 0x00, + 0x2c, 0xf9, 0x0a, 0x57, 0x47, 0x45, 0x43, 0xb3, + 0x23, 0x01, 0x9c, 0xee, 0x54, 0x4d, 0x58, 0xd3, + 0x71, 0x1c, 0xc9, 0xd3, 0x30, 0x9e, 0x14, 0xa5, + 0xf3, 0xbf, 0x4d, 0x9b, 0xb7, 0x13, 0x21, 0xae, + 0xd2, 0x8d, 0x6e, 0x6f, 0x1c, 0xcc, 0xb2, 0x41, + 0xb2, 0x64, 0x56, 0x83, 0xce, 0xd1, 0x0c, 0x79, + 0x32, 0x78, 0xef, 0xc5, 0x21, 0xb1, 0xe8, 0xc4, + 0x42, 0xa7, 0x8d, 0xc1, 0xfa, 0xa1, 0x9c, 0x3c, + 0x21, 0xd8, 0xe9, 0x90, 0xe2, 0x7c, 0x14, 0x26, + 0xfe, 0x61, 0x3e, 0xf9, 0x71, 0x1d, 0x5d, 0x49, + 0x3b, 0xb1, 0xb8, 0x42, 0xa1, 0xb8, 0x1c, 0x75, + 0x7d, 0xee, 0xed, 0xfc, 0xe6, 0x20, 0x2b, 0x9e, + 0x10, 0x52, 0xda, 0x56, 0x4d, 0x64, 0x6c, 0x41, + 0xc1, 0xf7, 0x60, 0x0c, 0x10, 0x65, 0x6f, 0xd4, + 0xe9, 0x9b, 0x0d, 0x83, 0x13, 0xc8, 0x5a, 0xa3, + 0x56, 0x2a, 0x42, 0xc6, 0x1c, 0xfe, 0xdb, 0xba, + 0x3d, 0x04, 0x12, 0xfd, 0x28, 0xeb, 0x78, 0xdd, + 0xbc, 0xc8, 0x0d, 0xa1, 0xce, 0xd4, 0x54, 0xbf, + 0xaf, 0xe1, 0x60, 0x0c, 0xa3, 0xc3, 0xc3, 0x62, + 0x58, 0xc1, 0x79, 0xa7, 0x95, 0x41, 0x09, 0x24, + 0xc6, 0x9a, 0x50, 0x14, 0x03, 0x01, 0x00, 0x01, + 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x4d, 0x7b, + 0x5f, 0x28, 0x5e, 0x68, 0x6c, 0xa3, 0x65, 0xc7, + 0x7e, 0x49, 0x6c, 0xb3, 0x67, 0xbb, 0xd0, 0x75, + 0xa2, 0x9e, 0x8c, 0x92, 0x4f, 0x8c, 0x33, 0x14, + 0x7c, 0x6c, 0xf1, 0x74, 0x97, 0xc3, 0xe0, 0x10, + 0xe9, 0x0d, 0xc2, 0x30, 0x5c, 0x23, 0xee, 0x1d, + 0x16, 0x2e, 0xb9, 0x96, 0x2b, 0x2d, 0x17, 0x03, + 0x01, 0x00, 0x20, 0xf2, 0xc8, 0xa7, 0x1b, 0x60, + 0x46, 0xee, 0xe5, 0x7e, 0xc9, 0x35, 0xb3, 0xf1, + 0x7c, 0x32, 0x0c, 0x85, 0x94, 0x59, 0x57, 0x27, + 0xb0, 0xbd, 0x52, 0x86, 0x90, 0xf1, 0xb7, 0x4d, + 0x1e, 0xc1, 0x16, 0x17, 0x03, 0x01, 0x00, 0x30, + 0xff, 0x85, 0x50, 0xdf, 0x3f, 0xfc, 0xa2, 0x61, + 0x1a, 0x12, 0xc0, 0x1e, 0x10, 0x32, 0x88, 0x50, + 0xa0, 0x2c, 0x80, 0xda, 0x77, 0xea, 0x09, 0x47, + 0xe0, 0x85, 0x07, 0x29, 0x45, 0x65, 0x19, 0xa3, + 0x8d, 0x99, 0xb8, 0xbf, 0xb6, 0xbc, 0x76, 0xe2, + 0x50, 0x24, 0x82, 0x0a, 0xfd, 0xdd, 0x35, 0x09, + 0x15, 0x03, 0x01, 0x00, 0x20, 0xe7, 0x36, 0xf6, + 0x61, 0xd2, 0x95, 0x3c, 0xb6, 0x65, 0x7b, 0xb2, + 0xb8, 0xdf, 0x03, 0x53, 0xeb, 0xf7, 0x16, 0xe0, + 0xe0, 0x15, 0x22, 0x71, 0x70, 0x62, 0x73, 0xad, + 0xb5, 0x1a, 0x77, 0x44, 0x57, + }, + }}, +} + +var aesGCMServerScript = [][]byte{ + { + 0x16, 0x03, 0x01, 0x01, 0x1c, 0x01, 0x00, 0x01, + 0x18, 0x03, 0x03, 0x52, 0x1e, 0x74, 0xf0, 0xb0, + 0xc1, 0x8b, 0x16, 0xf9, 0x74, 0xfc, 0x16, 0xc4, + 0x11, 0x18, 0x96, 0x08, 0x25, 0x38, 0x4f, 0x98, + 0x98, 0xbe, 0xb5, 0x61, 0xdf, 0x94, 0x15, 0xcc, + 0x9b, 0x61, 0xef, 0x00, 0x00, 0x80, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x32, + 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26, 0xc0, 0x0f, + 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, + 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, + 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, + 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, + 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, + 0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x31, + 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, + 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, + 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, + 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, 0x00, 0x12, + 0x00, 0x09, 0x00, 0x14, 0x00, 0x11, 0x00, 0x08, + 0x00, 0x06, 0x00, 0x03, 0x00, 0xff, 0x01, 0x00, + 0x00, 0x6f, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, + 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, + 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, + 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, + 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, + 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, + 0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x22, 0x00, 0x20, 0x06, 0x01, 0x06, 0x02, + 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, + 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x03, 0x01, + 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x02, 0x03, 0x01, 0x01, 0x00, 0x0f, 0x00, 0x01, + 0x01, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, + 0x2c, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x2f, 0x00, 0x00, + 0x04, 0x00, 0x23, 0x00, 0x00, 0x16, 0x03, 0x03, + 0x02, 0xbe, 0x0b, 0x00, 0x02, 0xba, 0x00, 0x02, + 0xb7, 0x00, 0x02, 0xb4, 0x30, 0x82, 0x02, 0xb0, + 0x30, 0x82, 0x02, 0x19, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0x85, 0xb0, 0xbb, 0xa4, + 0x8a, 0x7f, 0xb8, 0xca, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, + 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, + 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, + 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, + 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, + 0x30, 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, + 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, + 0x34, 0x32, 0x34, 0x30, 0x39, 0x30, 0x39, 0x33, + 0x38, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, + 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, + 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, + 0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, + 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbb, 0x79, + 0xd6, 0xf5, 0x17, 0xb5, 0xe5, 0xbf, 0x46, 0x10, + 0xd0, 0xdc, 0x69, 0xbe, 0xe6, 0x2b, 0x07, 0x43, + 0x5a, 0xd0, 0x03, 0x2d, 0x8a, 0x7a, 0x43, 0x85, + 0xb7, 0x14, 0x52, 0xe7, 0xa5, 0x65, 0x4c, 0x2c, + 0x78, 0xb8, 0x23, 0x8c, 0xb5, 0xb4, 0x82, 0xe5, + 0xde, 0x1f, 0x95, 0x3b, 0x7e, 0x62, 0xa5, 0x2c, + 0xa5, 0x33, 0xd6, 0xfe, 0x12, 0x5c, 0x7a, 0x56, + 0xfc, 0xf5, 0x06, 0xbf, 0xfa, 0x58, 0x7b, 0x26, + 0x3f, 0xb5, 0xcd, 0x04, 0xd3, 0xd0, 0xc9, 0x21, + 0x96, 0x4a, 0xc7, 0xf4, 0x54, 0x9f, 0x5a, 0xbf, + 0xef, 0x42, 0x71, 0x00, 0xfe, 0x18, 0x99, 0x07, + 0x7f, 0x7e, 0x88, 0x7d, 0x7d, 0xf1, 0x04, 0x39, + 0xc4, 0xa2, 0x2e, 0xdb, 0x51, 0xc9, 0x7c, 0xe3, + 0xc0, 0x4c, 0x3b, 0x32, 0x66, 0x01, 0xcf, 0xaf, + 0xb1, 0x1d, 0xb8, 0x71, 0x9a, 0x1d, 0xdb, 0xdb, + 0x89, 0x6b, 0xae, 0xda, 0x2d, 0x79, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, + 0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xb1, 0xad, 0xe2, 0x85, + 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, 0x23, + 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, 0x39, + 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xb1, 0xad, 0xe2, + 0x85, 0x5a, 0xcf, 0xcb, 0x28, 0xdb, 0x69, 0xce, + 0x23, 0x69, 0xde, 0xd3, 0x26, 0x8e, 0x18, 0x88, + 0x39, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, + 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, + 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0x85, + 0xb0, 0xbb, 0xa4, 0x8a, 0x7f, 0xb8, 0xca, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, + 0x08, 0x6c, 0x45, 0x24, 0xc7, 0x6b, 0xb1, 0x59, + 0xab, 0x0c, 0x52, 0xcc, 0xf2, 0xb0, 0x14, 0xd7, + 0x87, 0x9d, 0x7a, 0x64, 0x75, 0xb5, 0x5a, 0x95, + 0x66, 0xe4, 0xc5, 0x2b, 0x8e, 0xae, 0x12, 0x66, + 0x1f, 0xeb, 0x4f, 0x38, 0xb3, 0x6e, 0x60, 0xd3, + 0x92, 0xfd, 0xf7, 0x41, 0x08, 0xb5, 0x25, 0x13, + 0xb1, 0x18, 0x7a, 0x24, 0xfb, 0x30, 0x1d, 0xba, + 0xed, 0x98, 0xb9, 0x17, 0xec, 0xe7, 0xd7, 0x31, + 0x59, 0xdb, 0x95, 0xd3, 0x1d, 0x78, 0xea, 0x50, + 0x56, 0x5c, 0xd5, 0x82, 0x5a, 0x2d, 0x5a, 0x5f, + 0x33, 0xc4, 0xb6, 0xd8, 0xc9, 0x75, 0x90, 0x96, + 0x8c, 0x0f, 0x52, 0x98, 0xb5, 0xcd, 0x98, 0x1f, + 0x89, 0x20, 0x5f, 0xf2, 0xa0, 0x1c, 0xa3, 0x1b, + 0x96, 0x94, 0xdd, 0xa9, 0xfd, 0x57, 0xe9, 0x70, + 0xe8, 0x26, 0x6d, 0x71, 0x99, 0x9b, 0x26, 0x6e, + 0x38, 0x50, 0x29, 0x6c, 0x90, 0xa7, 0xbd, 0xd9, + 0x16, 0x03, 0x03, 0x01, 0x11, 0x0c, 0x00, 0x01, + 0x0d, 0x03, 0x00, 0x19, 0x85, 0x04, 0x01, 0x39, + 0xdc, 0xee, 0x44, 0x17, 0x5e, 0xdb, 0xd7, 0x27, + 0xaf, 0xb6, 0x56, 0xd9, 0xb4, 0x43, 0x5a, 0x99, + 0xcf, 0xaa, 0x31, 0x37, 0x0c, 0x6f, 0x3a, 0xa0, + 0xf8, 0x53, 0xc4, 0x74, 0xd1, 0x91, 0x0a, 0x46, + 0xf5, 0x38, 0x3b, 0x5c, 0x09, 0xd8, 0x97, 0xdc, + 0x4b, 0xaa, 0x70, 0x26, 0x48, 0xf2, 0xd6, 0x0b, + 0x31, 0xc9, 0xf8, 0xd4, 0x98, 0x43, 0xe1, 0x6c, + 0xd5, 0xc7, 0xb2, 0x8e, 0x0b, 0x01, 0xe6, 0xb6, + 0x00, 0x28, 0x80, 0x7b, 0xfc, 0x96, 0x8f, 0x0d, + 0xa2, 0x4f, 0xb0, 0x79, 0xaf, 0xdc, 0x61, 0x28, + 0x63, 0x33, 0x78, 0xf6, 0x31, 0x39, 0xfd, 0x8a, + 0xf4, 0x15, 0x18, 0x11, 0xfe, 0xdb, 0xd5, 0x07, + 0xda, 0x2c, 0xed, 0x49, 0xa0, 0x23, 0xbf, 0xd0, + 0x3a, 0x38, 0x1d, 0x54, 0xae, 0x1c, 0x7b, 0xea, + 0x29, 0xee, 0xd0, 0x38, 0xc1, 0x76, 0xa7, 0x7f, + 0x2a, 0xf4, 0xce, 0x1e, 0xac, 0xcc, 0x94, 0x79, + 0x90, 0x33, 0x04, 0x01, 0x00, 0x80, 0x0d, 0x8e, + 0x79, 0xe6, 0x86, 0xf6, 0xb6, 0xfb, 0x6b, 0x6a, + 0xcc, 0x55, 0xe4, 0x80, 0x4d, 0xc5, 0x0c, 0xc6, + 0xa3, 0x9f, 0x1d, 0x39, 0xd2, 0x98, 0x57, 0x31, + 0xa2, 0x90, 0x73, 0xe8, 0xd2, 0xcd, 0xb0, 0x93, + 0x1a, 0x60, 0x0f, 0x38, 0x02, 0x3b, 0x1b, 0x25, + 0x56, 0xec, 0x44, 0xab, 0xbe, 0x2e, 0x0c, 0xc0, + 0x6e, 0x54, 0x91, 0x50, 0xd6, 0xb1, 0xa2, 0x98, + 0x14, 0xa8, 0x35, 0x62, 0x9d, 0xca, 0xfb, 0x0f, + 0x64, 0x2b, 0x05, 0xa0, 0xa0, 0x57, 0xef, 0xcd, + 0x95, 0x45, 0x13, 0x5a, 0x9b, 0x3d, 0xdb, 0x42, + 0x54, 0x7f, 0xb9, 0x17, 0x08, 0x7f, 0xb2, 0xf0, + 0xb1, 0xc3, 0xdf, 0x67, 0x95, 0xe2, 0x73, 0xf2, + 0x76, 0xa3, 0x97, 0xfd, 0x9c, 0x92, 0x4a, 0xdb, + 0x95, 0x1e, 0x91, 0x95, 0xae, 0x3d, 0xae, 0x58, + 0xb5, 0x03, 0x6f, 0x5c, 0x3a, 0x19, 0xab, 0x92, + 0xa5, 0x09, 0x6b, 0x40, 0x61, 0xb0, 0x16, 0x03, + 0x03, 0x00, 0x04, 0x0e, 0x00, 0x00, 0x00, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x8a, 0x10, 0x00, 0x00, + 0x86, 0x85, 0x04, 0x01, 0xba, 0xb8, 0xad, 0x69, + 0x20, 0x5e, 0xc1, 0x61, 0xc3, 0x0f, 0xb4, 0x30, + 0x64, 0x66, 0x70, 0x96, 0x33, 0x3c, 0x8e, 0x12, + 0x56, 0xbf, 0x6d, 0xb8, 0x6d, 0xc6, 0xba, 0xea, + 0xfc, 0x38, 0xc0, 0x8b, 0x87, 0xa8, 0xf3, 0x87, + 0xa1, 0xd5, 0xb6, 0xb0, 0x72, 0xc7, 0xd4, 0x19, + 0x56, 0xa0, 0x91, 0xe1, 0x45, 0xc7, 0xf1, 0x7d, + 0xb0, 0x1d, 0x78, 0x18, 0xf6, 0x3d, 0xbf, 0x1a, + 0x23, 0x93, 0x0b, 0x19, 0xb1, 0x00, 0x56, 0xc9, + 0x5e, 0x89, 0xd4, 0x9d, 0xd9, 0x5b, 0xe0, 0xb8, + 0xff, 0x2f, 0x7d, 0x93, 0xae, 0x5b, 0xa5, 0x1f, + 0x1f, 0x2b, 0x09, 0xe5, 0xf6, 0x07, 0x26, 0xa3, + 0xed, 0xcb, 0x6a, 0x1a, 0xd6, 0x14, 0x83, 0x9b, + 0xd3, 0x9d, 0x47, 0x1b, 0xf3, 0x72, 0x5f, 0x69, + 0x21, 0x8f, 0xfa, 0x09, 0x38, 0x1a, 0x6b, 0x91, + 0xcf, 0x19, 0x32, 0x54, 0x58, 0x8e, 0xee, 0xaf, + 0xeb, 0x06, 0x9b, 0x3a, 0x34, 0x16, 0x66, 0x14, + 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, 0x03, + 0x00, 0x28, 0xc6, 0x96, 0x67, 0x62, 0xcc, 0x47, + 0x01, 0xb5, 0xbd, 0xb7, 0x24, 0xd3, 0xb6, 0xfd, + 0xb8, 0x46, 0xce, 0x82, 0x6d, 0x31, 0x1f, 0x15, + 0x11, 0x8f, 0xed, 0x62, 0x71, 0x5f, 0xae, 0xb6, + 0xa9, 0x0c, 0x24, 0x1d, 0xe8, 0x26, 0x51, 0xca, + 0x7c, 0x42, + }, + { + 0x16, 0x03, 0x03, 0x00, 0x72, 0x04, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xea, 0x8b, 0xfb, 0xef, 0xba, 0xc8, 0x88, 0x94, + 0x44, 0x99, 0x5f, 0x02, 0x68, 0x3a, 0x12, 0x67, + 0x7f, 0xb9, 0x39, 0x71, 0x84, 0xe0, 0x30, 0xe6, + 0x90, 0x6c, 0xcf, 0x32, 0x29, 0x29, 0x5c, 0x5a, + 0x8b, 0x7d, 0xaa, 0x11, 0x28, 0x26, 0xb5, 0xce, + 0xd2, 0x88, 0xd5, 0xb0, 0x5f, 0x94, 0x37, 0xa2, + 0x48, 0xd9, 0x53, 0xb2, 0xab, 0x59, 0x23, 0x3d, + 0x81, 0x6e, 0x64, 0x89, 0xca, 0x1a, 0x84, 0x16, + 0xdf, 0x31, 0x10, 0xde, 0x52, 0x7f, 0x50, 0xf3, + 0xd9, 0x27, 0xa0, 0xe8, 0x34, 0x15, 0x9e, 0x11, + 0xdd, 0xba, 0xce, 0x40, 0x17, 0xf3, 0x67, 0x14, + 0x03, 0x03, 0x00, 0x01, 0x01, 0x16, 0x03, 0x03, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x35, 0xcb, 0x17, 0x66, 0xee, 0xfd, + 0x27, 0xdb, 0xb8, 0xa8, 0x8a, 0xf1, 0x56, 0x67, + 0x89, 0x0d, 0x13, 0xac, 0xe2, 0x31, 0xb9, 0xa2, + 0x26, 0xbb, 0x1c, 0xcf, 0xd1, 0xb2, 0x48, 0x1d, + 0x0d, 0xb1, 0x17, 0x03, 0x03, 0x00, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, + 0x89, 0x7c, 0x58, 0x6a, 0x9b, 0x00, 0x05, 0x8c, + 0x7f, 0x28, 0x54, 0x61, 0x44, 0x10, 0xee, 0x85, + 0x26, 0xa8, 0x04, 0xcd, 0xca, 0x85, 0x60, 0xf2, + 0xeb, 0x22, 0xbd, 0x9e, 0x15, 0x03, 0x03, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x10, 0xe4, 0xe5, 0xf9, 0x85, 0xe3, 0xb0, + 0xec, 0x84, 0x29, 0x91, 0x05, 0x7d, 0x86, 0xe3, + 0x97, 0xeb, 0xb2, + }, +} diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go index b6e73fe293b..7e820c1e7e9 100644 --- a/libgo/go/crypto/tls/key_agreement.go +++ b/libgo/go/crypto/tls/key_agreement.go @@ -6,11 +6,14 @@ package tls import ( "crypto" + "crypto/ecdsa" "crypto/elliptic" "crypto/md5" "crypto/rsa" "crypto/sha1" + "crypto/sha256" "crypto/x509" + "encoding/asn1" "errors" "io" "math/big" @@ -36,7 +39,7 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi } ciphertext := ckx.ciphertext - if version != versionSSL30 { + if version != VersionSSL30 { ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) if ciphertextLen != len(ckx.ciphertext)-2 { return nil, errors.New("bad ClientKeyExchange") @@ -82,34 +85,94 @@ func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello return preMasterSecret, ckx, nil } +// sha1Hash calculates a SHA1 hash over the given byte slices. +func sha1Hash(slices [][]byte) []byte { + hsha1 := sha1.New() + for _, slice := range slices { + hsha1.Write(slice) + } + return hsha1.Sum(nil) +} + // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the // concatenation of an MD5 and SHA1 hash. -func md5SHA1Hash(slices ...[]byte) []byte { +func md5SHA1Hash(slices [][]byte) []byte { md5sha1 := make([]byte, md5.Size+sha1.Size) hmd5 := md5.New() for _, slice := range slices { hmd5.Write(slice) } copy(md5sha1, hmd5.Sum(nil)) + copy(md5sha1[md5.Size:], sha1Hash(slices)) + return md5sha1 +} - hsha1 := sha1.New() +// sha256Hash implements TLS 1.2's hash function. +func sha256Hash(slices [][]byte) []byte { + h := sha256.New() for _, slice := range slices { - hsha1.Write(slice) + h.Write(slice) } - copy(md5sha1[md5.Size:], hsha1.Sum(nil)) - return md5sha1 + return h.Sum(nil) +} + +// hashForServerKeyExchange hashes the given slices and returns their digest +// and the identifier of the hash function used. The hashFunc argument is only +// used for >= TLS 1.2 and precisely identifies the hash function to use. +func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) { + if version >= VersionTLS12 { + switch hashFunc { + case hashSHA256: + return sha256Hash(slices), crypto.SHA256, nil + case hashSHA1: + return sha1Hash(slices), crypto.SHA1, nil + default: + return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer") + } + } + 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 +// advertized list of supported signature and hash combinations. +func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) { + if len(clientSignatureAndHashes) == 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 + return hashSHA1, nil + } + + for _, sigAndHash := range clientSignatureAndHashes { + if sigAndHash.signature != sigType { + continue + } + switch sigAndHash.hash { + case hashSHA1, hashSHA256: + return sigAndHash.hash, nil + } + } + + return 0, errors.New("tls: client doesn't support any common hash functions") } // ecdheRSAKeyAgreement implements a TLS key agreement where the server // generates a ephemeral EC public/private key pair and signs it. The -// pre-master secret is then calculated using ECDH. -type ecdheRSAKeyAgreement struct { +// pre-master secret is then calculated using ECDH. The signature may +// either be ECDSA or RSA. +type ecdheKeyAgreement struct { + version uint16 + sigType uint8 privateKey []byte curve elliptic.Curve x, y *big.Int } -func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { +func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { var curveid uint16 Curve: @@ -150,16 +213,55 @@ Curve: serverECDHParams[3] = byte(len(ecdhePublic)) copy(serverECDHParams[4:], ecdhePublic) - md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams) - sig, err := rsa.SignPKCS1v15(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1) + var tls12HashId uint8 + if ka.version >= VersionTLS12 { + if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil { + return nil, err + } + } + + digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams) if err != nil { - return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) + return nil, err + } + var sig []byte + switch ka.sigType { + case signatureECDSA: + privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey) + if !ok { + return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key") + } + r, s, err := ecdsa.Sign(config.rand(), privKey, digest) + if err != nil { + return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) + } + sig, err = asn1.Marshal(ecdsaSignature{r, s}) + case signatureRSA: + privKey, ok := cert.PrivateKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("ECDHE RSA requires a RSA server private key") + } + sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest) + if err != nil { + return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) + } + default: + return nil, errors.New("unknown ECDHE signature algorithm") } skx := new(serverKeyExchangeMsg) - skx.key = make([]byte, len(serverECDHParams)+2+len(sig)) + sigAndHashLen := 0 + if ka.version >= VersionTLS12 { + sigAndHashLen = 2 + } + skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig)) copy(skx.key, serverECDHParams) k := skx.key[len(serverECDHParams):] + if ka.version >= VersionTLS12 { + k[0] = tls12HashId + k[1] = ka.sigType + k = k[2:] + } k[0] = byte(len(sig) >> 8) k[1] = byte(len(sig)) copy(k[2:], sig) @@ -167,7 +269,7 @@ Curve: return skx, nil } -func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { +func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { return nil, errors.New("bad ClientKeyExchange") } @@ -185,7 +287,7 @@ func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, cert *C var errServerKeyExchange = errors.New("invalid ServerKeyExchange") -func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { +func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { if len(skx.key) < 4 { return errServerKeyExchange } @@ -219,17 +321,62 @@ func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientH if len(sig) < 2 { return errServerKeyExchange } + + var tls12HashId uint8 + if ka.version >= VersionTLS12 { + // handle SignatureAndHashAlgorithm + var sigAndHash []uint8 + sigAndHash, sig = sig[:2], sig[2:] + if sigAndHash[1] != ka.sigType { + return errServerKeyExchange + } + tls12HashId = sigAndHash[0] + if len(sig) < 2 { + return errServerKeyExchange + } + } sigLen := int(sig[0])<<8 | int(sig[1]) if sigLen+2 != len(sig) { return errServerKeyExchange } sig = sig[2:] - md5sha1 := md5SHA1Hash(clientHello.random, serverHello.random, serverECDHParams) - return rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), crypto.MD5SHA1, md5sha1, sig) + digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, 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("ECDHE ECDSA requires a ECDSA server public key") + } + ecdsaSig := new(ecdsaSignature) + if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { + return err + } + if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { + return errors.New("ECDSA signature contained zero or negative values") + } + if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { + return errors.New("ECDSA verification failure") + } + case signatureRSA: + pubKey, ok := cert.PublicKey.(*rsa.PublicKey) + if !ok { + return errors.New("ECDHE RSA requires a RSA server public key") + } + if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { + return err + } + default: + return errors.New("unknown ECDHE signature algorithm") + } + + return nil } -func (ka *ecdheRSAKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { +func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { if ka.curve == nil { return nil, nil, errors.New("missing ServerKeyExchange message") } diff --git a/libgo/go/crypto/tls/prf.go b/libgo/go/crypto/tls/prf.go index df1eaad0586..fb8b3ab4d1e 100644 --- a/libgo/go/crypto/tls/prf.go +++ b/libgo/go/crypto/tls/prf.go @@ -5,9 +5,11 @@ package tls import ( + "crypto" "crypto/hmac" "crypto/md5" "crypto/sha1" + "crypto/sha256" "hash" ) @@ -43,8 +45,8 @@ func pHash(result, secret, seed []byte, hash func() hash.Hash) { } } -// pRF10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5. -func pRF10(result, secret, label, seed []byte) { +// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5. +func prf10(result, secret, label, seed []byte) { hashSHA1 := sha1.New hashMD5 := md5.New @@ -62,9 +64,18 @@ func pRF10(result, secret, label, seed []byte) { } } -// pRF30 implements the SSL 3.0 pseudo-random function, as defined in +// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5. +func prf12(result, secret, label, seed []byte) { + labelAndSeed := make([]byte, len(label)+len(seed)) + copy(labelAndSeed, label) + copy(labelAndSeed[len(label):], seed) + + pHash(result, secret, labelAndSeed, sha256.New) +} + +// prf30 implements the SSL 3.0 pseudo-random function, as defined in // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6. -func pRF30(result, secret, label, seed []byte) { +func prf30(result, secret, label, seed []byte) { hashSHA1 := sha1.New() hashMD5 := md5.New() @@ -106,19 +117,27 @@ var keyExpansionLabel = []byte("key expansion") var clientFinishedLabel = []byte("client finished") var serverFinishedLabel = []byte("server finished") +func prfForVersion(version uint16) func(result, secret, label, seed []byte) { + switch version { + case VersionSSL30: + return prf30 + case VersionTLS10, VersionTLS11: + return prf10 + case VersionTLS12: + return prf12 + default: + panic("unknown version") + } +} + // masterFromPreMasterSecret generates the master secret from the pre-master // secret. See http://tools.ietf.org/html/rfc5246#section-8.1 func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte) []byte { - prf := pRF10 - if version == versionSSL30 { - prf = pRF30 - } - var seed [tlsRandomLength * 2]byte copy(seed[0:len(clientRandom)], clientRandom) copy(seed[len(clientRandom):], serverRandom) masterSecret := make([]byte, masterSecretLength) - prf(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) + prfForVersion(version)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) return masterSecret } @@ -126,18 +145,13 @@ func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, se // secret, given the lengths of the MAC key, cipher key and IV, as defined in // RFC 2246, section 6.3. func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { - prf := pRF10 - if version == versionSSL30 { - prf = pRF30 - } - var seed [tlsRandomLength * 2]byte copy(seed[0:len(clientRandom)], serverRandom) copy(seed[len(serverRandom):], clientRandom) n := 2*macLen + 2*keyLen + 2*ivLen keyMaterial := make([]byte, n) - prf(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) + prfForVersion(version)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) clientMAC = keyMaterial[:macLen] keyMaterial = keyMaterial[macLen:] serverMAC = keyMaterial[:macLen] @@ -153,37 +167,34 @@ func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRand } func newFinishedHash(version uint16) finishedHash { - return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New(), version} + if version >= VersionTLS12 { + return finishedHash{sha256.New(), sha256.New(), nil, nil, version} + } + return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version} } // A finishedHash calculates the hash of a set of handshake messages suitable // for including in a Finished message. type finishedHash struct { - clientMD5 hash.Hash - clientSHA1 hash.Hash - serverMD5 hash.Hash - serverSHA1 hash.Hash - version uint16 + client hash.Hash + server hash.Hash + + // Prior to TLS 1.2, an additional MD5 hash is required. + clientMD5 hash.Hash + serverMD5 hash.Hash + + version uint16 } func (h finishedHash) Write(msg []byte) (n int, err error) { - h.clientMD5.Write(msg) - h.clientSHA1.Write(msg) - h.serverMD5.Write(msg) - h.serverSHA1.Write(msg) - return len(msg), nil -} + h.client.Write(msg) + h.server.Write(msg) -// finishedSum10 calculates the contents of the verify_data member of a TLSv1 -// Finished message given the MD5 and SHA1 hashes of a set of handshake -// messages. -func finishedSum10(md5, sha1, label, masterSecret []byte) []byte { - seed := make([]byte, len(md5)+len(sha1)) - copy(seed, md5) - copy(seed[len(md5):], sha1) - out := make([]byte, finishedVerifyLength) - pRF10(out, masterSecret, label, seed) - return out + if h.version < VersionTLS12 { + h.clientMD5.Write(msg) + h.serverMD5.Write(msg) + } + return len(msg), nil } // finishedSum30 calculates the contents of the verify_data member of a SSLv3 @@ -224,23 +235,57 @@ var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52} // clientSum returns the contents of the verify_data member of a client's // Finished message. func (h finishedHash) clientSum(masterSecret []byte) []byte { - if h.version == versionSSL30 { - return finishedSum30(h.clientMD5, h.clientSHA1, masterSecret, ssl3ClientFinishedMagic) + if h.version == VersionSSL30 { + return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic) } - md5 := h.clientMD5.Sum(nil) - sha1 := h.clientSHA1.Sum(nil) - return finishedSum10(md5, sha1, clientFinishedLabel, masterSecret) + out := make([]byte, finishedVerifyLength) + if h.version >= VersionTLS12 { + seed := h.client.Sum(nil) + prf12(out, masterSecret, clientFinishedLabel, seed) + } else { + seed := make([]byte, 0, md5.Size+sha1.Size) + seed = h.clientMD5.Sum(seed) + seed = h.client.Sum(seed) + prf10(out, masterSecret, clientFinishedLabel, seed) + } + return out } // serverSum returns the contents of the verify_data member of a server's // Finished message. func (h finishedHash) serverSum(masterSecret []byte) []byte { - if h.version == versionSSL30 { - return finishedSum30(h.serverMD5, h.serverSHA1, masterSecret, ssl3ServerFinishedMagic) + if h.version == VersionSSL30 { + return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic) + } + + out := make([]byte, finishedVerifyLength) + if h.version >= VersionTLS12 { + seed := h.server.Sum(nil) + prf12(out, masterSecret, serverFinishedLabel, seed) + } else { + seed := make([]byte, 0, md5.Size+sha1.Size) + seed = h.serverMD5.Sum(seed) + seed = h.server.Sum(seed) + prf10(out, masterSecret, serverFinishedLabel, seed) + } + return out +} + +// 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) ([]byte, crypto.Hash, uint8) { + if h.version >= VersionTLS12 { + digest := h.server.Sum(nil) + return digest, crypto.SHA256, hashSHA256 + } + if sigType == signatureECDSA { + digest := h.server.Sum(nil) + return digest, crypto.SHA1, hashSHA1 } - md5 := h.serverMD5.Sum(nil) - sha1 := h.serverSHA1.Sum(nil) - return finishedSum10(md5, sha1, serverFinishedLabel, masterSecret) + digest := make([]byte, 0, 36) + digest = h.serverMD5.Sum(digest) + digest = h.server.Sum(digest) + return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */ } diff --git a/libgo/go/crypto/tls/prf_test.go b/libgo/go/crypto/tls/prf_test.go index 773a2b2ffc8..a9b6c9e4c79 100644 --- a/libgo/go/crypto/tls/prf_test.go +++ b/libgo/go/crypto/tls/prf_test.go @@ -72,7 +72,7 @@ func TestKeysFromPreMasterSecret(t *testing.T) { // These test vectors were generated from GnuTLS using `gnutls-cli --insecure -d 9 ` var testKeysFromTests = []testKeysFromTest{ { - versionTLS10, + VersionTLS10, "0302cac83ad4b1db3b9ab49ad05957de2a504a634a386fc600889321e1a971f57479466830ac3e6f468e87f5385fa0c5", "4ae66303755184a3917fcb44880605fcc53baa01912b22ed94473fc69cebd558", "4ae663020ec16e6bb5130be918cfcafd4d765979a3136a5d50c593446e4e44db", @@ -85,7 +85,7 @@ var testKeysFromTests = []testKeysFromTest{ 16, }, { - versionTLS10, + VersionTLS10, "03023f7527316bc12cbcd69e4b9e8275d62c028f27e65c745cfcddc7ce01bd3570a111378b63848127f1c36e5f9e4890", "4ae66364b5ea56b20ce4e25555aed2d7e67f42788dd03f3fee4adae0459ab106", "4ae66363ab815cbf6a248b87d6b556184e945e9b97fbdf247858b0bdafacfa1c", @@ -98,7 +98,7 @@ var testKeysFromTests = []testKeysFromTest{ 16, }, { - versionTLS10, + VersionTLS10, "832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1", "4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e", "4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e", @@ -111,7 +111,7 @@ var testKeysFromTests = []testKeysFromTest{ 16, }, { - versionSSL30, + VersionSSL30, "832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1", "4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e", "4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e", diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go index 9230656d6a4..6c67506fc36 100644 --- a/libgo/go/crypto/tls/tls.go +++ b/libgo/go/crypto/tls/tls.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. -// Package tls partially implements TLS 1.0, as specified in RFC 2246. +// Package tls partially implements TLS 1.2, as specified in RFC 5246. package tls import ( diff --git a/libgo/go/crypto/x509/cert_pool.go b/libgo/go/crypto/x509/cert_pool.go index 505f4d4f776..babe94d41c5 100644 --- a/libgo/go/crypto/x509/cert_pool.go +++ b/libgo/go/crypto/x509/cert_pool.go @@ -25,9 +25,10 @@ func NewCertPool() *CertPool { } // findVerifiedParents attempts to find certificates in s which have signed the -// given certificate. If no such certificate can be found or the signature -// doesn't match, it returns nil. -func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int) { +// given certificate. If any candidates were rejected then errCert will be set +// to one of them, arbitrarily, and err will contain the reason that it was +// rejected. +func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int, errCert *Certificate, err error) { if s == nil { return } @@ -41,8 +42,10 @@ func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int) { } for _, c := range candidates { - if cert.CheckSignatureFrom(s.certs[c]) == nil { + if err = cert.CheckSignatureFrom(s.certs[c]); err == nil { parents = append(parents, c) + } else { + errCert = s.certs[c] } } diff --git a/libgo/go/crypto/x509/pkcs1.go b/libgo/go/crypto/x509/pkcs1.go index 873d3966eb5..acebe351398 100644 --- a/libgo/go/crypto/x509/pkcs1.go +++ b/libgo/go/crypto/x509/pkcs1.go @@ -52,7 +52,7 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) { } if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 { - return nil, errors.New("private key contains zero or negative value") + return nil, errors.New("x509: private key contains zero or negative value") } key = new(rsa.PrivateKey) @@ -67,7 +67,7 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) { key.Primes[1] = priv.Q for i, a := range priv.AdditionalPrimes { if a.Prime.Sign() <= 0 { - return nil, errors.New("private key contains zero or negative prime") + return nil, errors.New("x509: private key contains zero or negative prime") } key.Primes[i+2] = a.Prime // We ignore the other two values because rsa will calculate diff --git a/libgo/go/crypto/x509/pkcs8.go b/libgo/go/crypto/x509/pkcs8.go index 8e1585e15cc..ba19989cba1 100644 --- a/libgo/go/crypto/x509/pkcs8.go +++ b/libgo/go/crypto/x509/pkcs8.go @@ -32,7 +32,7 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) if err != nil { - return nil, errors.New("crypto/x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) + return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) } return key, nil @@ -44,11 +44,11 @@ func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { } key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) if err != nil { - return nil, errors.New("crypto/x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) + return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) } return key, nil default: - return nil, fmt.Errorf("crypto/x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) + return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) } } diff --git a/libgo/go/crypto/x509/pkix/pkix.go b/libgo/go/crypto/x509/pkix/pkix.go index 738659011fa..5034946f710 100644 --- a/libgo/go/crypto/x509/pkix/pkix.go +++ b/libgo/go/crypto/x509/pkix/pkix.go @@ -144,7 +144,7 @@ type CertificateList struct { SignatureValue asn1.BitString } -// HasExpired returns true iff now is past the expiry time of certList. +// HasExpired reports whether now is past the expiry time of certList. func (certList *CertificateList) HasExpired(now time.Time) bool { return now.After(certList.TBSCertList.NextUpdate) } diff --git a/libgo/go/crypto/x509/root_unix.go b/libgo/go/crypto/x509/root_unix.go index 1b25a94d08d..324f855b135 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 freebsd linux openbsd netbsd +// +build dragonfly freebsd linux openbsd netbsd package x509 @@ -10,11 +10,11 @@ import "io/ioutil" // Possible certificate files; stop after finding one. var certFiles = []string{ - "/etc/ssl/certs/ca-certificates.crt", // Linux etc + "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL "/etc/ssl/ca-bundle.pem", // OpenSUSE "/etc/ssl/cert.pem", // OpenBSD - "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD + "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly } func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go index e8f70a49da8..81018b78fe6 100644 --- a/libgo/go/crypto/x509/root_windows.go +++ b/libgo/go/crypto/x509/root_windows.go @@ -89,7 +89,7 @@ func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) e case syscall.CERT_TRUST_IS_NOT_TIME_VALID: return CertificateInvalidError{c, Expired} default: - return UnknownAuthorityError{c} + return UnknownAuthorityError{c, nil, nil} } } return nil @@ -129,9 +129,9 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex case syscall.CERT_E_CN_NO_MATCH: return HostnameError{c, opts.DNSName} case syscall.CERT_E_UNTRUSTEDROOT: - return UnknownAuthorityError{c} + return UnknownAuthorityError{c, nil, nil} default: - return UnknownAuthorityError{c} + return UnknownAuthorityError{c, nil, nil} } } diff --git a/libgo/go/crypto/x509/sec1.go b/libgo/go/crypto/x509/sec1.go index 8a2840fbef5..7de66754eeb 100644 --- a/libgo/go/crypto/x509/sec1.go +++ b/libgo/go/crypto/x509/sec1.go @@ -33,6 +33,20 @@ func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) { return parseECPrivateKey(nil, der) } +// MarshalECPrivateKey marshals an EC private key into ASN.1, DER format. +func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { + oid, ok := oidFromNamedCurve(key.Curve) + if !ok { + return nil, errors.New("x509: unknown elliptic curve") + } + return asn1.Marshal(ecPrivateKey{ + Version: 1, + PrivateKey: key.D.Bytes(), + NamedCurveOID: oid, + PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, + }) +} + // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. // The OID for the named curve may be provided from another source (such as // the PKCS8 container) - if it is provided then use this instead of the OID @@ -40,10 +54,10 @@ func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) { func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { var privKey ecPrivateKey if _, err := asn1.Unmarshal(der, &privKey); err != nil { - return nil, errors.New("crypto/x509: failed to parse EC private key: " + err.Error()) + return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) } if privKey.Version != ecPrivKeyVersion { - return nil, fmt.Errorf("crypto/x509: unknown EC private key version %d", privKey.Version) + return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) } var curve elliptic.Curve @@ -53,12 +67,12 @@ func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *e curve = namedCurveFromOID(privKey.NamedCurveOID) } if curve == nil { - return nil, errors.New("crypto/x509: unknown elliptic curve") + return nil, errors.New("x509: unknown elliptic curve") } k := new(big.Int).SetBytes(privKey.PrivateKey) if k.Cmp(curve.Params().N) >= 0 { - return nil, errors.New("crypto/x509: invalid elliptic curve private key value") + return nil, errors.New("x509: invalid elliptic curve private key value") } priv := new(ecdsa.PrivateKey) priv.Curve = curve diff --git a/libgo/go/crypto/x509/sec1_test.go b/libgo/go/crypto/x509/sec1_test.go index 7135699d283..95f18e77de0 100644 --- a/libgo/go/crypto/x509/sec1_test.go +++ b/libgo/go/crypto/x509/sec1_test.go @@ -5,6 +5,7 @@ package x509 import ( + "bytes" "encoding/hex" "testing" ) @@ -15,8 +16,15 @@ var ecPrivateKeyHex = `3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4d func TestParseECPrivateKey(t *testing.T) { derBytes, _ := hex.DecodeString(ecPrivateKeyHex) - _, err := ParseECPrivateKey(derBytes) + key, err := ParseECPrivateKey(derBytes) if err != nil { t.Errorf("failed to decode EC private key: %s", err) } + serialized, err := MarshalECPrivateKey(key) + if err != nil { + t.Fatalf("failed to encode EC private key: %s", err) + } + if !bytes.Equal(serialized, derBytes) { + t.Fatalf("serialized key differs: got %x, want %x", serialized, derBytes) + } } diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index b29ddbc80f0..8327463ca86 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -5,6 +5,7 @@ package x509 import ( + "fmt" "net" "runtime" "strings" @@ -91,10 +92,27 @@ func (h HostnameError) Error() string { // UnknownAuthorityError results when the certificate issuer is unknown type UnknownAuthorityError struct { cert *Certificate + // hintErr contains an error that may be helpful in determining why an + // authority wasn't found. + hintErr error + // hintCert contains a possible authority certificate that was rejected + // because of the error in hintErr. + hintCert *Certificate } func (e UnknownAuthorityError) Error() string { - return "x509: certificate signed by unknown authority" + s := "x509: certificate signed by unknown authority" + if e.hintErr != nil { + certName := e.hintCert.Subject.CommonName + if len(certName) == 0 { + if len(e.hintCert.Subject.Organization) > 0 { + certName = e.hintCert.Subject.Organization[0] + } + certName = "serial:" + e.hintCert.SerialNumber.String() + } + s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName) + } + return s } // SystemRootsError results when we fail to load the system root certificates. @@ -136,14 +154,18 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V } if len(c.PermittedDNSDomains) > 0 { + ok := false for _, domain := range c.PermittedDNSDomains { if opts.DNSName == domain || (strings.HasSuffix(opts.DNSName, domain) && len(opts.DNSName) >= 1+len(domain) && opts.DNSName[len(opts.DNSName)-len(domain)-1] == '.') { - continue + ok = true + break } + } + if !ok { return CertificateInvalidError{c, CANotAuthorizedForThisName} } } @@ -249,7 +271,8 @@ func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate } func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) { - for _, rootNum := range opts.Roots.findVerifiedParents(c) { + possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c) + for _, rootNum := range possibleRoots { root := opts.Roots.certs[rootNum] err = root.isValid(rootCertificate, currentChain, opts) if err != nil { @@ -258,8 +281,9 @@ func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain [ chains = append(chains, appendToFreshChain(currentChain, root)) } + possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c) nextIntermediate: - for _, intermediateNum := range opts.Intermediates.findVerifiedParents(c) { + for _, intermediateNum := range possibleIntermediates { intermediate := opts.Intermediates.certs[intermediateNum] for _, cert := range currentChain { if cert == intermediate { @@ -284,7 +308,13 @@ nextIntermediate: } if len(chains) == 0 && err == nil { - err = UnknownAuthorityError{c} + hintErr := rootErr + hintCert := failedRoot + if hintErr == nil { + hintErr = intermediateErr + hintCert = failedIntermediate + } + err = UnknownAuthorityError{c, hintErr, hintCert} } return diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go index 5103ed814aa..ba6c13d4510 100644 --- a/libgo/go/crypto/x509/verify_test.go +++ b/libgo/go/crypto/x509/verify_test.go @@ -127,6 +127,18 @@ var verifyTests = []verifyTest{ }, }, { + leaf: googleLeafWithInvalidHash, + intermediates: []string{thawteIntermediate}, + roots: []string{verisignRoot}, + currentTime: 1302726541, + dnsName: "www.google.com", + + // The specific error message may not occur when using system + // verification. + systemSkip: true, + errorCallback: expectHashError, + }, + { // The default configuration should reject an S/MIME chain. leaf: smimeLeaf, roots: []string{smimeIntermediate}, @@ -171,6 +183,24 @@ var verifyTests = []verifyTest{ {"mega.co.nz", "EssentialSSL CA", "COMODO Certification Authority"}, }, }, + { + // Check that a name constrained intermediate works even when + // it lists multiple constraints. + leaf: nameConstraintsLeaf, + intermediates: []string{nameConstraintsIntermediate1, nameConstraintsIntermediate2}, + roots: []string{globalSignRoot}, + currentTime: 1382387896, + dnsName: "secure.iddl.vt.edu", + + expectedChains: [][]string{ + { + "Technology-enhanced Learning and Online Strategies", + "Virginia Tech Global Qualified Server CA", + "Trusted Root CA G2", + "GlobalSign Root CA", + }, + }, + }, } func expectHostnameError(t *testing.T, i int, err error) (ok bool) { @@ -213,6 +243,18 @@ func expectSystemRootsError(t *testing.T, i int, err error) bool { return true } +func expectHashError(t *testing.T, i int, err error) bool { + if err == nil { + t.Errorf("#%d: no error resulted from invalid hash", i) + 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) + return false + } + return true +} + func certificateFromPEM(pemBytes string) (*Certificate, error) { block, _ := pem.Decode([]byte(pemBytes)) if block == nil { @@ -400,6 +442,28 @@ u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6 z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw== -----END CERTIFICATE-----` +// googleLeafWithInvalidHash is the same as googleLeaf, but the signature +// algorithm in the certificate contains a nonsense OID. +const googleLeafWithInvalidHash = `-----BEGIN CERTIFICATE----- +MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BATIFADBM +MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg +THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x +MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh +MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw +FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN +gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L +05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM +BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl +LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF +BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw +Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0 +ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAVAF +AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5 +u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6 +z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw== +-----END CERTIFICATE-----` + const dnssecExpLeaf = `-----BEGIN CERTIFICATE----- MIIGzTCCBbWgAwIBAgIDAdD6MA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0 @@ -522,6 +586,50 @@ um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= -----END CERTIFICATE-----` +const startComRootSHA256 = `-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul +F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC +ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w +ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk +aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 +YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg +c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 +d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG +CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF +wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS +Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst +0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc +pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl +CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF +P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK +1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm +KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ +8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm +fyWl8kgAwKQB2j8= +-----END CERTIFICATE-----` + const smimeLeaf = `-----BEGIN CERTIFICATE----- MIIFBjCCA+6gAwIBAgISESFvrjT8XcJTEe6rBlPptILlMA0GCSqGSIb3DQEBBQUA MFQxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSowKAYD @@ -663,3 +771,168 @@ zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB ZQ== -----END CERTIFICATE-----` + +var nameConstraintsLeaf = `-----BEGIN CERTIFICATE----- +MIIHMTCCBRmgAwIBAgIIIZaV/3ezOJkwDQYJKoZIhvcNAQEFBQAwgcsxCzAJBgNV +BAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEj +MCEGA1UECxMaR2xvYmFsIFF1YWxpZmllZCBTZXJ2ZXIgQ0ExPDA6BgNVBAoTM1Zp +cmdpbmlhIFBvbHl0ZWNobmljIEluc3RpdHV0ZSBhbmQgU3RhdGUgVW5pdmVyc2l0 +eTExMC8GA1UEAxMoVmlyZ2luaWEgVGVjaCBHbG9iYWwgUXVhbGlmaWVkIFNlcnZl +ciBDQTAeFw0xMzA5MTkxNDM2NTVaFw0xNTA5MTkxNDM2NTVaMIHNMQswCQYDVQQG +EwJVUzERMA8GA1UECAwIVmlyZ2luaWExEzARBgNVBAcMCkJsYWNrc2J1cmcxPDA6 +BgNVBAoMM1ZpcmdpbmlhIFBvbHl0ZWNobmljIEluc3RpdHV0ZSBhbmQgU3RhdGUg +VW5pdmVyc2l0eTE7MDkGA1UECwwyVGVjaG5vbG9neS1lbmhhbmNlZCBMZWFybmlu +ZyBhbmQgT25saW5lIFN0cmF0ZWdpZXMxGzAZBgNVBAMMEnNlY3VyZS5pZGRsLnZ0 +LmVkdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkOyPpsOK/6IuPG +WnIBlVwlHzeYf+cUlggqkLq0b0+vZbiTXgio9/VCuNQ8opSoss7J7o3ygV9to+9Y +YwJKVC5WDT/y5JWpQey0CWILymViJnpNSwnxBc8A+Q8w5NUGDd/UhtPx/U8/hqbd +WPDYj2hbOqyq8UlRhfS5pwtnv6BbCTaY11I6FhCLK7zttISyTuWCf9p9o/ggiipP +ii/5oh4dkl+r5SfuSp5GPNHlYO8lWqys5NAPoDD4fc/kuflcK7Exx7XJ+Oqu0W0/ +psjEY/tES1ZgDWU/ParcxxFpFmKHbD5DXsfPOObzkVWXIY6tGMutSlE1Froy/Nn0 +OZsAOrcCAwEAAaOCAhMwggIPMIG4BggrBgEFBQcBAQSBqzCBqDBYBggrBgEFBQcw +AoZMaHR0cDovL3d3dy5wa2kudnQuZWR1L2dsb2JhbHF1YWxpZmllZHNlcnZlci9j +YWNlcnQvZ2xvYmFscXVhbGlmaWVkc2VydmVyLmNydDBMBggrBgEFBQcwAYZAaHR0 +cDovL3Z0Y2EtcC5lcHJvdi5zZXRpLnZ0LmVkdTo4MDgwL2VqYmNhL3B1YmxpY3dl +Yi9zdGF0dXMvb2NzcDAdBgNVHQ4EFgQUp7xbO6iHkvtZbPE4jmndmnAbSEcwDAYD +VR0TAQH/BAIwADAfBgNVHSMEGDAWgBS8YmAn1eM1SBfpS6tFatDIqHdxjDBqBgNV +HSAEYzBhMA4GDCsGAQQBtGgFAgICATAOBgwrBgEEAbRoBQICAQEwPwYMKwYBBAG0 +aAUCAgMBMC8wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucGtpLnZ0LmVkdS9nbG9i +YWwvY3BzLzBKBgNVHR8EQzBBMD+gPaA7hjlodHRwOi8vd3d3LnBraS52dC5lZHUv +Z2xvYmFscXVhbGlmaWVkc2VydmVyL2NybC9jYWNybC5jcmwwDgYDVR0PAQH/BAQD +AgTwMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHREEFjAUghJz +ZWN1cmUuaWRkbC52dC5lZHUwDQYJKoZIhvcNAQEFBQADggIBAEgoYo4aUtatY3gI +OyyKp7QlIOaLbTJZywESHqy+L5EGDdJW2DJV+mcE0LDGvqa2/1Lo+AR1ntsZwfOi +Y718JwgVVaX/RCd5+QKP25c5/x72xI8hb/L1bgS0ED9b0YAhd7Qm1K1ot82+6mqX +DW6WiGeDr8Z07MQ3143qQe2rBlq+QI69DYzm2GOqAIAnUIWv7tCyLUm31b4DwmrJ +TeudVreTKUbBNB1TWRFHEPkWhjjXKZnNGRO11wHXcyBu6YekIvVZ+vmx8ePee4jJ +3GFOi7lMuWOeq57jTVL7KOKaKLVXBb6gqo5aq+Wwt8RUD5MakrCAEeQZj7DKaFmZ +oQCO0Pxrsl3InCGvxnGzT+bFVO9nJ/BAMj7hknFdm9Jr6Bg5q33Z+gnf909AD9QF +ESqUSykaHu2LVdJx2MaCH1CyKnRgMw5tEwE15EXpUjCm24m8FMOYC+rNtf18pgrz +5D8Jhh+oxK9PjcBYqXNtnioIxiMCYcV0q5d4w4BYFEh71tk7/bYB0R55CsBUVPmp +timWNOdRd57Tfpk3USaVsumWZAf9MP3wPiC7gb4d5tYEEAG5BuDT8ruFw838wU8G +1VvAVutSiYBg7k3NYO7AUqZ+Ax4klQX3aM9lgonmJ78Qt94UPtbptrfZ4/lSqEf8 +GBUwDrQNTb+gsXsDkjd5lcYxNx6l +-----END CERTIFICATE-----` + +var nameConstraintsIntermediate1 = `-----BEGIN CERTIFICATE----- +MIINLjCCDBagAwIBAgIRIqpyf/YoGgvHc8HiDAxAI8owDQYJKoZIhvcNAQEFBQAw +XDELMAkGA1UEBhMCQkUxFTATBgNVBAsTDFRydXN0ZWQgUm9vdDEZMBcGA1UEChMQ +R2xvYmFsU2lnbiBudi1zYTEbMBkGA1UEAxMSVHJ1c3RlZCBSb290IENBIEcyMB4X +DTEyMTIxMzAwMDAwMFoXDTE3MTIxMzAwMDAwMFowgcsxCzAJBgNVBAYTAlVTMREw +DwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEjMCEGA1UECxMa +R2xvYmFsIFF1YWxpZmllZCBTZXJ2ZXIgQ0ExPDA6BgNVBAoTM1ZpcmdpbmlhIFBv +bHl0ZWNobmljIEluc3RpdHV0ZSBhbmQgU3RhdGUgVW5pdmVyc2l0eTExMC8GA1UE +AxMoVmlyZ2luaWEgVGVjaCBHbG9iYWwgUXVhbGlmaWVkIFNlcnZlciBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALgIZhEaptBWADBqdJ45ueFGzMXa +GHnzNxoxR1fQIaaRQNdCg4cw3A4dWKMeEgYLtsp65ai3Xfw62Qaus0+KJ3RhgV+r +ihqK81NUzkls78fJlADVDI4fCTlothsrE1CTOMiy97jKHai5mVTiWxmcxpmjv7fm +5Nhc+uHgh2hIz6npryq495mD51ZrUTIaqAQN6Pw/VHfAmR524vgriTOjtp1t4lA9 +pXGWjF/vkhAKFFheOQSQ00rngo2wHgCqMla64UTN0oz70AsCYNZ3jDLx0kOP0YmM +R3Ih91VA63kLqPXA0R6yxmmhhxLZ5bcyAy1SLjr1N302MIxLM/pSy6aquEnbELhz +qyp9yGgRyGJay96QH7c4RJY6gtcoPDbldDcHI9nXngdAL4DrZkJ9OkDkJLyqG66W +ZTF5q4EIs6yMdrywz0x7QP+OXPJrjYpbeFs6tGZCFnWPFfmHCRJF8/unofYrheq+ +9J7Jx3U55S/k57NXbAM1RAJOuMTlfn9Etf9Dpoac9poI4Liav6rBoUQk3N3JWqnV +HNx/NdCyJ1/6UbKMJUZsStAVglsi6lVPo289HHOE4f7iwl3SyekizVOp01wUin3y +cnbZB/rXmZbwapSxTTSBf0EIOr9i4EGfnnhCAVA9U5uLrI5OEB69IY8PNX0071s3 +Z2a2fio5c8m3JkdrAgMBAAGjggh5MIIIdTAOBgNVHQ8BAf8EBAMCAQYwTAYDVR0g +BEUwQzBBBgkrBgEEAaAyATwwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xv +YmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wEgYDVR0TAQH/BAgwBgEB/wIBADCCBtAG +A1UdHgSCBscwggbDoIIGvzASghAzZGJsYWNrc2J1cmcub3JnMBiCFmFjY2VsZXJh +dGV2aXJnaW5pYS5jb20wGIIWYWNjZWxlcmF0ZXZpcmdpbmlhLm9yZzALgglhY3Zj +cC5vcmcwCYIHYmV2Lm5ldDAJggdiZXYub3JnMAuCCWNsaWdzLm9yZzAMggpjbWl3 +ZWIub3JnMBeCFWVhc3Rlcm5icm9va3Ryb3V0Lm5ldDAXghVlYXN0ZXJuYnJvb2t0 +cm91dC5vcmcwEYIPZWNvcnJpZG9ycy5pbmZvMBOCEWVkZ2FycmVzZWFyY2gub3Jn +MBKCEGdldC1lZHVjYXRlZC5jb20wE4IRZ2V0LWVkdWNhdGVkLmluZm8wEYIPZ2V0 +ZWR1Y2F0ZWQubmV0MBKCEGdldC1lZHVjYXRlZC5uZXQwEYIPZ2V0ZWR1Y2F0ZWQu +b3JnMBKCEGdldC1lZHVjYXRlZC5vcmcwD4INaG9raWVjbHViLmNvbTAQgg5ob2tp +ZXBob3RvLmNvbTAPgg1ob2tpZXNob3AuY29tMBGCD2hva2llc3BvcnRzLmNvbTAS +ghBob2tpZXRpY2tldHMuY29tMBKCEGhvdGVscm9hbm9rZS5jb20wE4IRaHVtYW53 +aWxkbGlmZS5vcmcwF4IVaW5uYXR2aXJnaW5pYXRlY2guY29tMA+CDWlzY2hwMjAx +MS5vcmcwD4INbGFuZHJlaGFiLm9yZzAggh5uYXRpb25hbHRpcmVyZXNlYXJjaGNl +bnRlci5jb20wFYITbmV0d29ya3ZpcmdpbmlhLm5ldDAMggpwZHJjdnQuY29tMBiC +FnBldGVkeWVyaXZlcmNvdXJzZS5jb20wDYILcmFkaW9pcS5vcmcwFYITcml2ZXJj +b3Vyc2Vnb2xmLmNvbTALgglzZGltaS5vcmcwEIIOc292YW1vdGlvbi5jb20wHoIc +c3VzdGFpbmFibGUtYmlvbWF0ZXJpYWxzLmNvbTAeghxzdXN0YWluYWJsZS1iaW9t +YXRlcmlhbHMub3JnMBWCE3RoaXNpc3RoZWZ1dHVyZS5jb20wGIIWdGhpcy1pcy10 +aGUtZnV0dXJlLmNvbTAVghN0aGlzaXN0aGVmdXR1cmUubmV0MBiCFnRoaXMtaXMt +dGhlLWZ1dHVyZS5uZXQwCoIIdmFkcy5vcmcwDIIKdmFsZWFmLm9yZzANggt2YXRl +Y2guaW5mbzANggt2YXRlY2gubW9iaTAcghp2YXRlY2hsaWZlbG9uZ2xlYXJuaW5n +LmNvbTAcghp2YXRlY2hsaWZlbG9uZ2xlYXJuaW5nLm5ldDAcghp2YXRlY2hsaWZl +bG9uZ2xlYXJuaW5nLm9yZzAKggh2Y29tLmVkdTASghB2aXJnaW5pYXZpZXcubmV0 +MDSCMnZpcmdpbmlhcG9seXRlY2huaWNpbnN0aXR1dGVhbmRzdGF0ZXVuaXZlcnNp +dHkuY29tMDWCM3ZpcmdpbmlhcG9seXRlY2huaWNpbnN0aXR1dGVhbmRzdGF0ZXVu +aXZlcnNpdHkuaW5mbzA0gjJ2aXJnaW5pYXBvbHl0ZWNobmljaW5zdGl0dXRlYW5k +c3RhdGV1bml2ZXJzaXR5Lm5ldDA0gjJ2aXJnaW5pYXBvbHl0ZWNobmljaW5zdGl0 +dXRlYW5kc3RhdGV1bml2ZXJzaXR5Lm9yZzAZghd2aXJnaW5pYXB1YmxpY3JhZGlv +Lm9yZzASghB2aXJnaW5pYXRlY2guZWR1MBOCEXZpcmdpbmlhdGVjaC5tb2JpMByC +GnZpcmdpbmlhdGVjaGZvdW5kYXRpb24ub3JnMAiCBnZ0LmVkdTALggl2dGFyYy5v +cmcwDIIKdnQtYXJjLm9yZzALggl2dGNyYy5jb20wCoIIdnRpcC5vcmcwDIIKdnRs +ZWFuLm9yZzAWghR2dGtub3dsZWRnZXdvcmtzLmNvbTAYghZ2dGxpZmVsb25nbGVh +cm5pbmcuY29tMBiCFnZ0bGlmZWxvbmdsZWFybmluZy5uZXQwGIIWdnRsaWZlbG9u +Z2xlYXJuaW5nLm9yZzATghF2dHNwb3J0c21lZGlhLmNvbTALggl2dHdlaS5jb20w +D4INd2l3YXR3ZXJjLmNvbTAKggh3dnRmLm9yZzAIgQZ2dC5lZHUwd6R1MHMxCzAJ +BgNVBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVy +ZzE8MDoGA1UEChMzVmlyZ2luaWEgUG9seXRlY2huaWMgSW5zdGl0dXRlIGFuZCBT +dGF0ZSBVbml2ZXJzaXR5MCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDAQYI +KwYBBQUHAwkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2NybC5nbG9iYWxzaWdu +LmNvbS9ncy90cnVzdHJvb3RnMi5jcmwwgYQGCCsGAQUFBwEBBHgwdjAzBggrBgEF +BQcwAYYnaHR0cDovL29jc3AyLmdsb2JhbHNpZ24uY29tL3RydXN0cm9vdGcyMD8G +CCsGAQUFBzAChjNodHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC90 +cnVzdHJvb3RnMi5jcnQwHQYDVR0OBBYEFLxiYCfV4zVIF+lLq0Vq0Miod3GMMB8G +A1UdIwQYMBaAFBT25YsxtkWASkxt/MKHico2w5BiMA0GCSqGSIb3DQEBBQUAA4IB +AQAyJm/lOB2Er4tHXhc/+fSufSzgjohJgYfMkvG4LknkvnZ1BjliefR8tTXX49d2 +SCDFWfGjqyJZwavavkl/4p3oXPG/nAMDMvxh4YAT+CfEK9HH+6ICV087kD4BLegi ++aFJMj8MMdReWCzn5sLnSR1rdse2mo2arX3Uod14SW+PGrbUmTuWNyvRbz3fVmxp +UdbGmj3laknO9YPsBGgHfv73pVVsTJkW4ZfY/7KdD/yaVv6ophpOB3coXfjl2+kd +Z4ypn2zK+cx9IL/LSewqd/7W9cD55PCUy4X9OTbEmAccwiz3LB66mQoUGfdHdkoB +jUY+v9vLQXmaVwI0AYL7g9LN +-----END CERTIFICATE-----` + +var nameConstraintsIntermediate2 = `-----BEGIN CERTIFICATE----- +MIIEXTCCA0WgAwIBAgILBAAAAAABNuk6OrMwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMjA0MjUxMTAw +MDBaFw0yNzA0MjUxMTAwMDBaMFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVz +dGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRy +dXN0ZWQgUm9vdCBDQSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKyuvqrtcMr7g7EuNbu4sKwxM127UsCmx1RxbxxgcArGS7rjiefpBH/w4LYrymjf +vcw1ueyMNoqLo9nJMz/ORXupb35NNfE667prQYHa+tTjl1IiKpB7QUwt3wXPuTMF +Ja1tXtjKzkqJyuJlNuPKT76HcjgNqgV1s9qG44MD5I2JvI12du8zI1bgdQ+l/KsX +kTfbGjUvhOLOlVNWVQDpL+YMIrGqgBYxy5TUNgrAcRtwpNdS2KkF5otSmMweVb5k +hoUVv3u8UxQH/WWbNhHq1RrIlg/0rBUfi/ziShYFSB7U+aLx5DxPphTFBiDquQGp +tB+FC4JvnukDStFihZCZ1R8CAwEAAaOCASMwggEfMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MEcGA1UdIARAMD4wPAYEVR0gADA0MDIGCCsGAQUFBwIB +FiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAdBgNVHQ4E +FgQUFPblizG2RYBKTG38woeJyjbDkGIwMwYDVR0fBCwwKjAooCagJIYiaHR0cDov +L2NybC5nbG9iYWxzaWduLm5ldC9yb290LmNybDA+BggrBgEFBQcBAQQyMDAwLgYI +KwYBBQUHMAGGImh0dHA6Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9yb290cjEwHwYD +VR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEFBQADggEB +AL7IG0l+k4LkcpI+a/kvZsSRwSM4uA6zGX34e78A2oytr8RG8bJwVb8+AHMUD+Xe +2kYdh/Uj/waQXfqR0OgxQXL9Ct4ZM+JlR1avsNKXWL5AwYXAXCOB3J5PW2XOck7H +Zw0vRbGQhjWjQx+B4KOUFg1b3ov/z6Xkr3yaCfRQhXh7KC0Bc0RXPPG5Nv5lCW+z +tbbg0zMm3kyfQITRusMSg6IBsDJqOnjaiaKQRcXiD0Sk43ZXb2bUKMxC7+Td3QL4 +RyHcWJbQ7YylLTS/x+jxWIcOQ0oO5/54t5PTQ14neYhOz9x4gUk2AYAW6d1vePwb +hcC8roQwkHT7HvfYBoc74FM= +-----END CERTIFICATE-----` + +var globalSignRoot = `-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE-----` diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 4dfea2c9499..57f68ba7edc 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -40,38 +40,60 @@ func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) { } algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm) if algo == UnknownPublicKeyAlgorithm { - return nil, errors.New("ParsePKIXPublicKey: unknown public key algorithm") + return nil, errors.New("x509: unknown public key algorithm") } return parsePublicKey(algo, &pki) } -// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format. -func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { - var pubBytes []byte - +func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) { switch pub := pub.(type) { case *rsa.PublicKey: - pubBytes, _ = asn1.Marshal(rsaPublicKey{ + publicKeyBytes, err = asn1.Marshal(rsaPublicKey{ N: pub.N, E: pub.E, }) + publicKeyAlgorithm.Algorithm = oidPublicKeyRSA + // This is a NULL parameters value which is technically + // superfluous, but most other code includes it and, by + // doing this, we match their public key hashes. + publicKeyAlgorithm.Parameters = asn1.RawValue{ + Tag: 5, + } + case *ecdsa.PublicKey: + publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) + oid, ok := oidFromNamedCurve(pub.Curve) + if !ok { + return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve") + } + publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA + var paramBytes []byte + paramBytes, err = asn1.Marshal(oid) + if err != nil { + return + } + publicKeyAlgorithm.Parameters.FullBytes = paramBytes default: - return nil, errors.New("MarshalPKIXPublicKey: unknown public key type") + return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported") + } + + return publicKeyBytes, publicKeyAlgorithm, nil +} + +// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format. +func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { + var publicKeyBytes []byte + var publicKeyAlgorithm pkix.AlgorithmIdentifier + var err error + + if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil { + return nil, err } pkix := pkixPublicKey{ - Algo: pkix.AlgorithmIdentifier{ - Algorithm: []int{1, 2, 840, 113549, 1, 1, 1}, - // This is a NULL parameters value which is technically - // superfluous, but most other code includes it and, by - // doing this, we match their public key hashes. - Parameters: asn1.RawValue{ - Tag: 5, - }, - }, + Algo: publicKeyAlgorithm, BitString: asn1.BitString{ - Bytes: pubBytes, - BitLength: 8 * len(pubBytes), + Bytes: publicKeyBytes, + BitLength: 8 * len(publicKeyBytes), }, } @@ -453,6 +475,18 @@ type Certificate struct { NotBefore, NotAfter time.Time // Validity bounds. KeyUsage KeyUsage + // Extensions contains raw X.509 extensions. When parsing certificates, + // this can be used to extract non-critical extensions that are not + // parsed by this package. When marshaling certificates, the Extensions + // field is ignored, see ExtraExtensions. + Extensions []pkix.Extension + + // ExtraExtensions contains extensions to be copied, raw, into any + // marshaled certificates. Values override any extensions that would + // otherwise be produced based on the other fields. The ExtraExtensions + // field is not populated when parsing certificates, see Extensions. + ExtraExtensions []pkix.Extension + ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages. UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. @@ -463,6 +497,10 @@ type Certificate struct { SubjectKeyId []byte AuthorityKeyId []byte + // RFC 5280, 4.2.2.1 (Authority Information Access) + OCSPServer []string + IssuingCertificateURL []string + // Subject Alternate Name values DNSNames []string EmailAddresses []string @@ -472,12 +510,15 @@ type Certificate struct { PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical. PermittedDNSDomains []string + // CRL Distribution Points + CRLDistributionPoints []string + PolicyIdentifiers []asn1.ObjectIdentifier } // ErrUnsupportedAlgorithm results from attempting to perform an operation that // involves algorithms that are not currently implemented. -var ErrUnsupportedAlgorithm = errors.New("crypto/x509: cannot verify signature: algorithm unimplemented") +var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented") // ConstraintViolationError results when a requested usage is not permitted by // a certificate. For example: checking a signature when the public key isn't a @@ -485,7 +526,7 @@ var ErrUnsupportedAlgorithm = errors.New("crypto/x509: cannot verify signature: type ConstraintViolationError struct{} func (ConstraintViolationError) Error() string { - return "crypto/x509: invalid signature: parent certificate cannot sign this kind of certificate" + return "x509: invalid signature: parent certificate cannot sign this kind of certificate" } func (c *Certificate) Equal(other *Certificate) bool { @@ -604,10 +645,10 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature return err } if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { - return errors.New("DSA signature contained zero or negative values") + return errors.New("x509: DSA signature contained zero or negative values") } if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) { - return errors.New("DSA verification failure") + return errors.New("x509: DSA verification failure") } return case *ecdsa.PublicKey: @@ -616,10 +657,10 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature return err } if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("crypto/x509: ECDSA signature contained zero or negative values") + return errors.New("x509: ECDSA signature contained zero or negative values") } if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) { - return errors.New("crypto/x509: ECDSA verification failure") + return errors.New("x509: ECDSA verification failure") } return } @@ -635,7 +676,7 @@ func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) (err error) { type UnhandledCriticalExtension struct{} func (h UnhandledCriticalExtension) Error() string { - return "unhandled critical extension" + return "x509: unhandled critical extension" } type basicConstraints struct { @@ -659,6 +700,24 @@ type generalSubtree struct { Name string `asn1:"tag:2,optional,ia5"` } +// RFC 5280, 4.2.2.1 +type authorityInfoAccess struct { + Method asn1.ObjectIdentifier + Location asn1.RawValue +} + +// RFC 5280, 4.2.1.14 +type distributionPoint struct { + DistributionPoint distributionPointName `asn1:"optional,tag:0"` + Reason asn1.BitString `asn1:"optional,tag:1"` + CRLIssuer asn1.RawValue `asn1:"optional,tag:2"` +} + +type distributionPointName struct { + FullName asn1.RawValue `asn1:"optional,tag:0"` + RelativeName pkix.RDNSequence `asn1:"optional,tag:1"` +} + func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) { asn1Data := keyData.PublicKey.RightAlign() switch algo { @@ -694,7 +753,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{ return nil, err } if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 { - return nil, errors.New("zero or negative DSA parameter") + return nil, errors.New("x509: zero or negative DSA parameter") } pub := &dsa.PublicKey{ Parameters: dsa.Parameters{ @@ -714,11 +773,11 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{ } namedCurve := namedCurveFromOID(*namedCurveOID) if namedCurve == nil { - return nil, errors.New("crypto/x509: unsupported elliptic curve") + return nil, errors.New("x509: unsupported elliptic curve") } x, y := elliptic.Unmarshal(namedCurve, asn1Data) if x == nil { - return nil, errors.New("crypto/x509: failed to unmarshal elliptic curve point") + return nil, errors.New("x509: failed to unmarshal elliptic curve point") } pub := &ecdsa.PublicKey{ Curve: namedCurve, @@ -752,7 +811,7 @@ func parseCertificate(in *certificate) (*Certificate, error) { } if in.TBSCertificate.SerialNumber.Sign() < 0 { - return nil, errors.New("negative serial number") + return nil, errors.New("x509: negative serial number") } out.Version = in.TBSCertificate.Version + 1 @@ -773,6 +832,8 @@ func parseCertificate(in *certificate) (*Certificate, error) { out.NotAfter = in.TBSCertificate.Validity.NotAfter for _, e := range in.TBSCertificate.Extensions { + out.Extensions = append(out.Extensions, e) + if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 { switch e.Id[3] { case 15: @@ -896,6 +957,39 @@ func parseCertificate(in *certificate) (*Certificate, error) { } continue + case 31: + // RFC 5280, 4.2.1.14 + + // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint + // + // DistributionPoint ::= SEQUENCE { + // distributionPoint [0] DistributionPointName OPTIONAL, + // reasons [1] ReasonFlags OPTIONAL, + // cRLIssuer [2] GeneralNames OPTIONAL } + // + // DistributionPointName ::= CHOICE { + // fullName [0] GeneralNames, + // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } + + var cdp []distributionPoint + _, err := asn1.Unmarshal(e.Value, &cdp) + if err != nil { + return nil, err + } + + for _, dp := range cdp { + var n asn1.RawValue + _, err = asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n) + if err != nil { + return nil, err + } + + if n.Tag == 6 { + out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes)) + } + } + continue + case 35: // RFC 5280, 4.2.1.1 var a authKeyId @@ -952,6 +1046,24 @@ func parseCertificate(in *certificate) (*Certificate, error) { out.PolicyIdentifiers[i] = policy.Policy } } + } else if e.Id.Equal(oidExtensionAuthorityInfoAccess) { + // RFC 5280 4.2.2.1: Authority Information Access + var aia []authorityInfoAccess + if _, err = asn1.Unmarshal(e.Value, &aia); err != nil { + return nil, err + } + + for _, v := range aia { + // GeneralName: uniformResourceIdentifier [6] IA5String + if v.Location.Tag != 6 { + continue + } + if v.Method.Equal(oidAuthorityInfoAccessOcsp) { + out.OCSPServer = append(out.OCSPServer, string(v.Location.Bytes)) + } else if v.Method.Equal(oidAuthorityInfoAccessIssuers) { + out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes)) + } + } } if e.Critical { @@ -1011,21 +1123,40 @@ func reverseBitsInAByte(in byte) byte { } var ( - oidExtensionSubjectKeyId = []int{2, 5, 29, 14} - oidExtensionKeyUsage = []int{2, 5, 29, 15} - oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37} - oidExtensionAuthorityKeyId = []int{2, 5, 29, 35} - oidExtensionBasicConstraints = []int{2, 5, 29, 19} - oidExtensionSubjectAltName = []int{2, 5, 29, 17} - oidExtensionCertificatePolicies = []int{2, 5, 29, 32} - oidExtensionNameConstraints = []int{2, 5, 29, 30} + oidExtensionSubjectKeyId = []int{2, 5, 29, 14} + oidExtensionKeyUsage = []int{2, 5, 29, 15} + oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37} + oidExtensionAuthorityKeyId = []int{2, 5, 29, 35} + oidExtensionBasicConstraints = []int{2, 5, 29, 19} + oidExtensionSubjectAltName = []int{2, 5, 29, 17} + oidExtensionCertificatePolicies = []int{2, 5, 29, 32} + oidExtensionNameConstraints = []int{2, 5, 29, 30} + oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31} + oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1} +) + +var ( + oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1} + oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2} ) +// oidNotInExtensions returns whether an extension with the given oid exists in +// extensions. +func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool { + for _, e := range extensions { + if e.Id.Equal(oid) { + return true + } + } + return false +} + func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { - ret = make([]pkix.Extension, 8 /* maximum number of elements. */) + ret = make([]pkix.Extension, 10 /* maximum number of elements. */) n := 0 - if template.KeyUsage != 0 { + if template.KeyUsage != 0 && + !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) { ret[n].Id = oidExtensionKeyUsage ret[n].Critical = true @@ -1045,7 +1176,8 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0 { + if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) && + !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) { ret[n].Id = oidExtensionExtendedKeyUsage var oids []asn1.ObjectIdentifier @@ -1066,7 +1198,7 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if template.BasicConstraintsValid { + if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) { ret[n].Id = oidExtensionBasicConstraints ret[n].Value, err = asn1.Marshal(basicConstraints{template.IsCA, template.MaxPathLen}) ret[n].Critical = true @@ -1076,7 +1208,7 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.SubjectKeyId) > 0 { + if len(template.SubjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) { ret[n].Id = oidExtensionSubjectKeyId ret[n].Value, err = asn1.Marshal(template.SubjectKeyId) if err != nil { @@ -1085,7 +1217,7 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.AuthorityKeyId) > 0 { + if len(template.AuthorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) { ret[n].Id = oidExtensionAuthorityKeyId ret[n].Value, err = asn1.Marshal(authKeyId{template.AuthorityKeyId}) if err != nil { @@ -1094,7 +1226,31 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 { + if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) && + !oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) { + ret[n].Id = oidExtensionAuthorityInfoAccess + var aiaValues []authorityInfoAccess + for _, name := range template.OCSPServer { + aiaValues = append(aiaValues, authorityInfoAccess{ + Method: oidAuthorityInfoAccessOcsp, + Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}, + }) + } + for _, name := range template.IssuingCertificateURL { + aiaValues = append(aiaValues, authorityInfoAccess{ + Method: oidAuthorityInfoAccessIssuers, + Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}, + }) + } + ret[n].Value, err = asn1.Marshal(aiaValues) + if err != nil { + return + } + n++ + } + + if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) && + !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) { ret[n].Id = oidExtensionSubjectAltName var rawValues []asn1.RawValue for _, name := range template.DNSNames { @@ -1118,7 +1274,8 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.PolicyIdentifiers) > 0 { + if len(template.PolicyIdentifiers) > 0 && + !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) { ret[n].Id = oidExtensionCertificatePolicies policies := make([]policyInformation, len(template.PolicyIdentifiers)) for i, policy := range template.PolicyIdentifiers { @@ -1131,7 +1288,8 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.PermittedDNSDomains) > 0 { + if len(template.PermittedDNSDomains) > 0 && + !oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) { ret[n].Id = oidExtensionNameConstraints ret[n].Critical = template.PermittedDNSDomainsCritical @@ -1147,10 +1305,33 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } + if len(template.CRLDistributionPoints) > 0 && + !oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) { + ret[n].Id = oidExtensionCRLDistributionPoints + + var crlDp []distributionPoint + for _, name := range template.CRLDistributionPoints { + rawFullName, _ := asn1.Marshal(asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}) + + dp := distributionPoint{ + DistributionPoint: distributionPointName{ + FullName: asn1.RawValue{Tag: 0, Class: 2, Bytes: rawFullName}, + }, + } + crlDp = append(crlDp, dp) + } + + ret[n].Value, err = asn1.Marshal(crlDp) + if err != nil { + return + } + n++ + } + // Adding another extension here? Remember to update the maximum number // of elements in the make() at the top of the function. - return ret[0:n], nil + return append(ret[:n], template.ExtraExtensions...), nil } func subjectBytes(cert *Certificate) ([]byte, error) { @@ -1179,28 +1360,8 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf var publicKeyBytes []byte var publicKeyAlgorithm pkix.AlgorithmIdentifier - switch pub := pub.(type) { - case *rsa.PublicKey: - publicKeyBytes, err = asn1.Marshal(rsaPublicKey{ - N: pub.N, - E: pub.E, - }) - publicKeyAlgorithm.Algorithm = oidPublicKeyRSA - case *ecdsa.PublicKey: - oid, ok := oidFromNamedCurve(pub.Curve) - if !ok { - return nil, errors.New("x509: unknown elliptic curve") - } - publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA - var paramBytes []byte - paramBytes, err = asn1.Marshal(oid) - if err != nil { - return - } - publicKeyAlgorithm.Parameters.FullBytes = paramBytes - publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) - default: - return nil, errors.New("x509: only RSA and ECDSA public keys supported") + if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil { + return nil, err } var signatureAlgorithm pkix.AlgorithmIdentifier diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go index abd4fe84d7e..f1097e992e7 100644 --- a/libgo/go/crypto/x509/x509_test.go +++ b/libgo/go/crypto/x509/x509_test.go @@ -237,6 +237,11 @@ func TestCertificateParse(t *testing.T) { if err := certs[0].VerifyHostname("mail.google.com"); err != nil { t.Error(err) } + + const expectedExtensions = 4 + if n := len(certs[0].Extensions); n != expectedExtensions { + t.Errorf("want %d extensions, got %d", expectedExtensions, n) + } } var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" + @@ -308,7 +313,8 @@ func TestCreateSelfSignedCertificate(t *testing.T) { } testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth} - testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{3, 2, 1}} + testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} + extraExtensionData := []byte("extra extension") for _, test := range tests { commonName := "test.example.com" @@ -330,12 +336,30 @@ func TestCreateSelfSignedCertificate(t *testing.T) { BasicConstraintsValid: true, IsCA: true, + OCSPServer: []string{"http://ocsp.example.com"}, + IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"}, + DNSNames: []string{"test.example.com"}, EmailAddresses: []string{"gopher@golang.org"}, IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, PermittedDNSDomains: []string{".example.com", "example.com"}, + + CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"}, + + ExtraExtensions: []pkix.Extension{ + { + Id: []int{1, 2, 3, 4}, + Value: extraExtensionData, + }, + // This extension should override the SubjectKeyId, above. + { + Id: oidExtensionSubjectKeyId, + Critical: false, + Value: []byte{0x04, 0x04, 4, 3, 2, 1}, + }, + }, } derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv) @@ -374,6 +398,14 @@ func TestCreateSelfSignedCertificate(t *testing.T) { t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) } + if !reflect.DeepEqual(cert.OCSPServer, template.OCSPServer) { + t.Errorf("%s: OCSP servers differ from template. Got %v, want %v", test.name, cert.OCSPServer, template.OCSPServer) + } + + if !reflect.DeepEqual(cert.IssuingCertificateURL, template.IssuingCertificateURL) { + t.Errorf("%s: Issuing certificate URLs differ from template. Got %v, want %v", test.name, cert.IssuingCertificateURL, template.IssuingCertificateURL) + } + if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) { t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames) } @@ -386,6 +418,18 @@ func TestCreateSelfSignedCertificate(t *testing.T) { t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses) } + if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) { + t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints) + } + + if !bytes.Equal(cert.SubjectKeyId, []byte{4, 3, 2, 1}) { + t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name) + } + + if bytes.Index(derBytes, extraExtensionData) == -1 { + t.Errorf("%s: didn't find extra extension in DER output", test.name) + } + if test.checkSig { err = cert.CheckSignatureFrom(cert) if err != nil { |