aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2010-12-15 11:49:55 -0500
committerAdam Langley <agl@golang.org>2010-12-15 11:49:55 -0500
commiteedf5c452974fc518bd6ec385730b61f016ddadf (patch)
tree220e91f1939993a3424ad71931f7bf688b22ac66
parent2f8ff0b81d38d2039c1827fd8b0744ff70c09497 (diff)
downloadgo-eedf5c452974fc518bd6ec385730b61f016ddadf.tar.gz
go-eedf5c452974fc518bd6ec385730b61f016ddadf.zip
crypto/tls: support CBC ciphers
This is largely based on ality's CL 2747042. crypto/rc4: API break in order to conform to crypto/cipher's Stream interface cipher/cipher: promote to the default build Since CBC differs between TLS 1.0 and 1.1, we downgrade and support only 1.0 at the current time. 1.0 is what most of the world uses. Given this CL, it would be trival to add support for AES 256, SHA 256 etc, but I haven't in order to keep the change smaller. R=rsc CC=ality, golang-dev https://golang.org/cl/3659041
-rw-r--r--src/pkg/Makefile1
-rw-r--r--src/pkg/crypto/rc4/rc4.go10
-rw-r--r--src/pkg/crypto/rc4/rc4_test.go2
-rw-r--r--src/pkg/crypto/tls/Makefile1
-rw-r--r--src/pkg/crypto/tls/cipher_suites.go62
-rw-r--r--src/pkg/crypto/tls/common.go47
-rw-r--r--src/pkg/crypto/tls/conn.go157
-rw-r--r--src/pkg/crypto/tls/conn_test.go52
-rw-r--r--src/pkg/crypto/tls/handshake_client.go30
-rw-r--r--src/pkg/crypto/tls/handshake_server.go51
-rw-r--r--src/pkg/crypto/tls/handshake_server_test.go416
-rw-r--r--src/pkg/crypto/tls/prf.go33
-rw-r--r--src/pkg/crypto/tls/prf_test.go2
13 files changed, 659 insertions, 205 deletions
diff --git a/src/pkg/Makefile b/src/pkg/Makefile
index aa94cb2dda..9f449d1258 100644
--- a/src/pkg/Makefile
+++ b/src/pkg/Makefile
@@ -32,6 +32,7 @@ DIRS=\
crypto/block\
crypto/blowfish\
crypto/cast5\
+ crypto/cipher\
crypto/elliptic\
crypto/hmac\
crypto/md4\
diff --git a/src/pkg/crypto/rc4/rc4.go b/src/pkg/crypto/rc4/rc4.go
index e47a015138..65fd195f3d 100644
--- a/src/pkg/crypto/rc4/rc4.go
+++ b/src/pkg/crypto/rc4/rc4.go
@@ -45,14 +45,14 @@ func NewCipher(key []byte) (*Cipher, os.Error) {
return &c, nil
}
-// XORKeyStream will XOR each byte of the given buffer with a byte of the
-// generated keystream.
-func (c *Cipher) XORKeyStream(buf []byte) {
- for i := range buf {
+// XORKeyStream sets dst to the result of XORing src with the key stream.
+// Dst and src may be the same slice but otherwise should not overlap.
+func (c *Cipher) XORKeyStream(dst, src []byte) {
+ for i := range src {
c.i += 1
c.j += c.s[c.i]
c.s[c.i], c.s[c.j] = c.s[c.j], c.s[c.i]
- buf[i] ^= c.s[c.s[c.i]+c.s[c.j]]
+ dst[i] = src[i] ^ c.s[c.s[c.i]+c.s[c.j]]
}
}
diff --git a/src/pkg/crypto/rc4/rc4_test.go b/src/pkg/crypto/rc4/rc4_test.go
index 73a52e721b..6265d9408f 100644
--- a/src/pkg/crypto/rc4/rc4_test.go
+++ b/src/pkg/crypto/rc4/rc4_test.go
@@ -48,7 +48,7 @@ func TestGolden(t *testing.T) {
return
}
keystream := make([]byte, len(g.keystream))
- c.XORKeyStream(keystream)
+ c.XORKeyStream(keystream, keystream)
for j, v := range keystream {
if g.keystream[j] != v {
t.Errorf("Failed at golden index %d", i)
diff --git a/src/pkg/crypto/tls/Makefile b/src/pkg/crypto/tls/Makefile
index 86f9695c07..1995a8a827 100644
--- a/src/pkg/crypto/tls/Makefile
+++ b/src/pkg/crypto/tls/Makefile
@@ -8,6 +8,7 @@ TARG=crypto/tls
GOFILES=\
alert.go\
ca_set.go\
+ cipher_suites.go\
common.go\
conn.go\
handshake_client.go\
diff --git a/src/pkg/crypto/tls/cipher_suites.go b/src/pkg/crypto/tls/cipher_suites.go
new file mode 100644
index 0000000000..c376c58898
--- /dev/null
+++ b/src/pkg/crypto/tls/cipher_suites.go
@@ -0,0 +1,62 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/rc4"
+ "hash"
+)
+
+// A cipherSuite is a specific combination of key agreement, cipher and MAC
+// function. All cipher suites currently assume RSA key agreement.
+type cipherSuite struct {
+ // the lengths, in bytes, of the key material needed for each component.
+ keyLen, macLen, ivLen int
+ cipher func(key, iv []byte, isRead bool) interface{}
+ mac func(macKey []byte) hash.Hash
+}
+
+var cipherSuites = map[uint16]*cipherSuite{
+ TLS_RSA_WITH_RC4_128_SHA: &cipherSuite{16, 20, 0, cipherRC4, hmacSHA1},
+ TLS_RSA_WITH_AES_128_CBC_SHA: &cipherSuite{16, 20, 16, cipherAES, hmacSHA1},
+}
+
+func cipherRC4(key, iv []byte, isRead bool) interface{} {
+ cipher, _ := rc4.NewCipher(key)
+ return cipher
+}
+
+func cipherAES(key, iv []byte, isRead bool) interface{} {
+ block, _ := aes.NewCipher(key)
+ if isRead {
+ return cipher.NewCBCDecrypter(block, iv)
+ }
+ return cipher.NewCBCEncrypter(block, iv)
+}
+
+func hmacSHA1(key []byte) hash.Hash {
+ return hmac.NewSHA1(key)
+}
+
+// mutualCipherSuite returns a cipherSuite and its id given a list of supported
+// ciphersuites and the id requested by the peer.
+func mutualCipherSuite(have []uint16, want uint16) (suite *cipherSuite, id uint16) {
+ for _, id := range have {
+ if want == id {
+ return cipherSuites[id], id
+ }
+ }
+ return
+}
+
+// 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_AES_128_CBC_SHA uint16 = 0x002f
+)
diff --git a/src/pkg/crypto/tls/common.go b/src/pkg/crypto/tls/common.go
index 4fb17ad3a8..1cb2d850cc 100644
--- a/src/pkg/crypto/tls/common.go
+++ b/src/pkg/crypto/tls/common.go
@@ -20,7 +20,7 @@ const (
maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
minVersion = 0x0301 // minimum supported version - TLS 1.0
- maxVersion = 0x0302 // maximum supported version - TLS 1.1
+ maxVersion = 0x0301 // maximum supported version - TLS 1.0
)
// TLS record types.
@@ -47,11 +47,6 @@ const (
typeNextProtocol uint8 = 67 // Not IANA assigned
)
-// TLS cipher suites.
-const (
- TLS_RSA_WITH_RC4_128_SHA uint16 = 5
-)
-
// TLS compression types.
const (
compressionNone uint8 = 0
@@ -120,6 +115,10 @@ type Config struct {
// certificate nor does it require that the certificate sent be
// anything more than self-signed.
AuthenticateClient bool
+
+ // CipherSuites is a list of supported cipher suites. If CipherSuites
+ // is nil, TLS uses a list of suites supported by the implementation.
+ CipherSuites []uint16
}
func (c *Config) rand() io.Reader {
@@ -146,6 +145,14 @@ func (c *Config) rootCAs() *CASet {
return s
}
+func (c *Config) cipherSuites() []uint16 {
+ s := c.CipherSuites
+ if len(s) == 0 {
+ s = defaultCipherSuites()
+ }
+ return s
+}
+
// A Certificate is a chain of one or more certificates, leaf first.
type Certificate struct {
Certificate [][]byte
@@ -164,11 +171,6 @@ type handshakeMessage interface {
unmarshal([]byte) bool
}
-type encryptor interface {
- // XORKeyStream xors the contents of the slice with bytes from the key stream.
- XORKeyStream(buf []byte)
-}
-
// mutualVersion returns the protocol version to use given the advertised
// version of the peer.
func mutualVersion(vers uint16) (uint16, bool) {
@@ -199,10 +201,20 @@ var certFiles = []string{
var once sync.Once
func defaultRoots() *CASet {
- once.Do(initDefaultRoots)
+ once.Do(initDefaults)
return varDefaultRoots
}
+func defaultCipherSuites() []uint16 {
+ once.Do(initDefaults)
+ return varDefaultCipherSuites
+}
+
+func initDefaults() {
+ initDefaultRoots()
+ initDefaultCipherSuites()
+}
+
var varDefaultRoots *CASet
func initDefaultRoots() {
@@ -216,3 +228,14 @@ func initDefaultRoots() {
}
varDefaultRoots = roots
}
+
+var varDefaultCipherSuites []uint16
+
+func initDefaultCipherSuites() {
+ varDefaultCipherSuites = make([]uint16, len(cipherSuites))
+ i := 0
+ for id, _ := range cipherSuites {
+ varDefaultCipherSuites[i] = id
+ i++
+ }
+}
diff --git a/src/pkg/crypto/tls/conn.go b/src/pkg/crypto/tls/conn.go
index 125d0a9086..8b1cd86af9 100644
--- a/src/pkg/crypto/tls/conn.go
+++ b/src/pkg/crypto/tls/conn.go
@@ -1,9 +1,14 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
// TLS low level connection and record layer
package tls
import (
"bytes"
+ "crypto/cipher"
"crypto/subtle"
"crypto/x509"
"hash"
@@ -99,31 +104,31 @@ func (c *Conn) SetWriteTimeout(nsec int64) os.Error {
// connection, either sending or receiving.
type halfConn struct {
sync.Mutex
- crypt encryptor // encryption state
- mac hash.Hash // MAC algorithm
- seq [8]byte // 64-bit sequence number
- bfree *block // list of free blocks
+ cipher interface{} // cipher algorithm
+ mac hash.Hash // MAC algorithm
+ seq [8]byte // 64-bit sequence number
+ bfree *block // list of free blocks
- nextCrypt encryptor // next encryption state
- nextMac hash.Hash // next MAC algorithm
+ nextCipher interface{} // next encryption state
+ nextMac hash.Hash // next MAC algorithm
}
// prepareCipherSpec sets the encryption and MAC states
// that a subsequent changeCipherSpec will use.
-func (hc *halfConn) prepareCipherSpec(crypt encryptor, mac hash.Hash) {
- hc.nextCrypt = crypt
+func (hc *halfConn) prepareCipherSpec(cipher interface{}, mac hash.Hash) {
+ hc.nextCipher = cipher
hc.nextMac = mac
}
// changeCipherSpec changes the encryption and MAC states
// to the ones previously passed to prepareCipherSpec.
func (hc *halfConn) changeCipherSpec() os.Error {
- if hc.nextCrypt == nil {
+ if hc.nextCipher == nil {
return alertInternalError
}
- hc.crypt = hc.nextCrypt
+ hc.cipher = hc.nextCipher
hc.mac = hc.nextMac
- hc.nextCrypt = nil
+ hc.nextCipher = nil
hc.nextMac = nil
return nil
}
@@ -150,27 +155,102 @@ func (hc *halfConn) resetSeq() {
}
}
+// removePadding returns an unpadded slice, in constant time, which is a prefix
+// of the input. It also returns a byte which is equal to 255 if the padding
+// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
+func removePadding(payload []byte) ([]byte, byte) {
+ if len(payload) < 1 {
+ return payload, 0
+ }
+
+ paddingLen := payload[len(payload)-1]
+ t := uint(len(payload)-1) - uint(paddingLen)
+ // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
+ good := byte(int32(^t) >> 31)
+
+ toCheck := 255 // the maximum possible padding length
+ // The length of the padded data is public, so we can use an if here
+ if toCheck+1 > len(payload) {
+ toCheck = len(payload) - 1
+ }
+
+ for i := 0; i < toCheck; i++ {
+ t := uint(paddingLen) - uint(i)
+ // if i <= paddingLen then the MSB of t is zero
+ mask := byte(int32(^t) >> 31)
+ b := payload[len(payload)-1-i]
+ good &^= mask&paddingLen ^ mask&b
+ }
+
+ // We AND together the bits of good and replicate the result across
+ // all the bits.
+ good &= good << 4
+ good &= good << 2
+ good &= good << 1
+ good = uint8(int8(good) >> 7)
+
+ toRemove := good&paddingLen + 1
+ return payload[:len(payload)-int(toRemove)], good
+}
+
+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) {
// pull out payload
payload := b.data[recordHeaderLen:]
+ macSize := 0
+ if hc.mac != nil {
+ macSize = hc.mac.Size()
+ }
+
+ paddingGood := byte(255)
+
// decrypt
- if hc.crypt != nil {
- hc.crypt.XORKeyStream(payload)
+ if hc.cipher != nil {
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ c.XORKeyStream(payload, payload)
+ case cipher.BlockMode:
+ blockSize := c.BlockSize()
+
+ if len(payload)%blockSize != 0 || len(payload) < roundUp(macSize+1, blockSize) {
+ return false, alertBadRecordMAC
+ }
+
+ c.CryptBlocks(payload, payload)
+ payload, paddingGood = removePadding(payload)
+ b.resize(recordHeaderLen + len(payload))
+
+ // note that we still have a timing side-channel in the
+ // MAC check, below. An attacker can align the record
+ // so that a correct padding will cause one less hash
+ // block to be calculated. Then they can iteratively
+ // decrypt a record by breaking each byte. See
+ // "Password Interception in a SSL/TLS Channel", Brice
+ // Canvel et al.
+ //
+ // However, our behaviour matches OpenSSL, so we leak
+ // only as much as they do.
+ default:
+ panic("unknown cipher type")
+ }
}
// check, strip mac
if hc.mac != nil {
- if len(payload) < hc.mac.Size() {
+ if len(payload) < macSize {
return false, alertBadRecordMAC
}
// strip mac off payload, b.data
- n := len(payload) - hc.mac.Size()
+ n := len(payload) - macSize
b.data[3] = byte(n >> 8)
b.data[4] = byte(n)
- b.data = b.data[0 : recordHeaderLen+n]
+ b.resize(recordHeaderLen + n)
remoteMAC := payload[n:]
hc.mac.Reset()
@@ -178,7 +258,7 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) {
hc.incSeq()
hc.mac.Write(b.data)
- if subtle.ConstantTimeCompare(hc.mac.Sum(), remoteMAC) != 1 {
+ if subtle.ConstantTimeCompare(hc.mac.Sum(), remoteMAC) != 1 || paddingGood != 255 {
return false, alertBadRecordMAC
}
}
@@ -186,6 +266,23 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) {
return true, 0
}
+// padToBlockSize calculates the needed padding block, if any, for a payload.
+// On exit, prefix aliases payload and extends to the end of the last full
+// block of payload. finalBlock is a fresh slice which contains the contents of
+// any suffix of payload as well as the needed padding to make finalBlock a
+// full block.
+func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
+ overrun := len(payload) % blockSize
+ paddingLen := blockSize - overrun
+ prefix = payload[:len(payload)-overrun]
+ finalBlock = make([]byte, blockSize)
+ copy(finalBlock, payload[len(payload)-overrun:])
+ for i := overrun; i < blockSize; i++ {
+ finalBlock[i] = byte(paddingLen - 1)
+ }
+ return
+}
+
// encrypt encrypts and macs the data in b.
func (hc *halfConn) encrypt(b *block) (bool, alert) {
// mac
@@ -198,18 +295,30 @@ func (hc *halfConn) encrypt(b *block) (bool, alert) {
n := len(b.data)
b.resize(n + len(mac))
copy(b.data[n:], mac)
-
- // update length to include mac
- n = len(b.data) - recordHeaderLen
- b.data[3] = byte(n >> 8)
- b.data[4] = byte(n)
}
+ payload := b.data[recordHeaderLen:]
+
// encrypt
- if hc.crypt != nil {
- hc.crypt.XORKeyStream(b.data[recordHeaderLen:])
+ if hc.cipher != nil {
+ 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)
+ default:
+ panic("unknown cipher type")
+ }
}
+ // update length to include MAC and any block padding needed.
+ n := len(b.data) - recordHeaderLen
+ b.data[3] = byte(n >> 8)
+ b.data[4] = byte(n)
+
return true, 0
}
diff --git a/src/pkg/crypto/tls/conn_test.go b/src/pkg/crypto/tls/conn_test.go
new file mode 100644
index 0000000000..ee654ca888
--- /dev/null
+++ b/src/pkg/crypto/tls/conn_test.go
@@ -0,0 +1,52 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "testing"
+)
+
+func TestRoundUp(t *testing.T) {
+ if roundUp(0, 16) != 0 ||
+ roundUp(1, 16) != 16 ||
+ roundUp(15, 16) != 16 ||
+ roundUp(16, 16) != 16 ||
+ roundUp(17, 16) != 32 {
+ t.Error("roundUp broken")
+ }
+}
+
+var paddingTests = []struct {
+ in []byte
+ good bool
+ expectedLen int
+}{
+ {[]byte{1, 2, 3, 4, 0}, true, 4},
+ {[]byte{1, 2, 3, 4, 0, 1}, false, 0},
+ {[]byte{1, 2, 3, 4, 99, 99}, false, 0},
+ {[]byte{1, 2, 3, 4, 1, 1}, true, 4},
+ {[]byte{1, 2, 3, 2, 2, 2}, true, 3},
+ {[]byte{1, 2, 3, 3, 3, 3}, true, 2},
+ {[]byte{1, 2, 3, 4, 3, 3}, false, 0},
+ {[]byte{1, 4, 4, 4, 4, 4}, true, 1},
+ {[]byte{5, 5, 5, 5, 5, 5}, true, 0},
+ {[]byte{6, 6, 6, 6, 6, 6}, false, 0},
+}
+
+func TestRemovePadding(t *testing.T) {
+ for i, test := range paddingTests {
+ payload, good := removePadding(test.in)
+ expectedGood := byte(255)
+ if !test.good {
+ expectedGood = 0
+ }
+ if good != expectedGood {
+ t.Errorf("#%d: wrong validity, want:%d got:%d", expectedGood, good)
+ }
+ if good == 255 && len(payload) != test.expectedLen {
+ t.Errorf("#%d: got %d, want %d", i, len(payload), test.expectedLen)
+ }
+ }
+}
diff --git a/src/pkg/crypto/tls/handshake_client.go b/src/pkg/crypto/tls/handshake_client.go
index 4cddba3303..e5e8a1f627 100644
--- a/src/pkg/crypto/tls/handshake_client.go
+++ b/src/pkg/crypto/tls/handshake_client.go
@@ -5,8 +5,6 @@
package tls
import (
- "crypto/hmac"
- "crypto/rc4"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
@@ -23,7 +21,7 @@ func (c *Conn) clientHandshake() os.Error {
hello := &clientHelloMsg{
vers: maxVersion,
- cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ cipherSuites: c.config.cipherSuites(),
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
ocspStapling: true,
@@ -61,11 +59,15 @@ func (c *Conn) clientHandshake() os.Error {
c.vers = vers
c.haveVers = true
- if serverHello.cipherSuite != TLS_RSA_WITH_RC4_128_SHA ||
- serverHello.compressionMethod != compressionNone {
+ if serverHello.compressionMethod != compressionNone {
return c.sendAlert(alertUnexpectedMessage)
}
+ suite, suiteId := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
+ if suite == nil {
+ return c.sendAlert(alertHandshakeFailure)
+ }
+
msg, err = c.readHandshake()
if err != nil {
return err
@@ -245,13 +247,12 @@ func (c *Conn) clientHandshake() os.Error {
c.writeRecord(recordTypeHandshake, certVerify.marshal())
}
- suite := cipherSuites[0]
- masterSecret, clientMAC, serverMAC, clientKey, serverKey :=
- keysFromPreMasterSecret11(preMasterSecret, hello.random, serverHello.random, suite.hashLength, suite.cipherKeyLength)
-
- cipher, _ := rc4.NewCipher(clientKey)
+ masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+ keysFromPreMasterSecret10(preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
- c.out.prepareCipherSpec(cipher, hmac.NewSHA1(clientMAC))
+ clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */ )
+ clientHash := suite.mac(clientMAC)
+ c.out.prepareCipherSpec(clientCipher, clientHash)
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
finished := new(finishedMsg)
@@ -259,8 +260,9 @@ func (c *Conn) clientHandshake() os.Error {
finishedHash.Write(finished.marshal())
c.writeRecord(recordTypeHandshake, finished.marshal())
- cipher2, _ := rc4.NewCipher(serverKey)
- c.in.prepareCipherSpec(cipher2, hmac.NewSHA1(serverMAC))
+ serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */ )
+ serverHash := suite.mac(serverMAC)
+ c.in.prepareCipherSpec(serverCipher, serverHash)
c.readRecord(recordTypeChangeCipherSpec)
if c.err != nil {
return c.err
@@ -282,6 +284,6 @@ func (c *Conn) clientHandshake() os.Error {
}
c.handshakeComplete = true
- c.cipherSuite = TLS_RSA_WITH_RC4_128_SHA
+ c.cipherSuite = suiteId
return nil
}
diff --git a/src/pkg/crypto/tls/handshake_server.go b/src/pkg/crypto/tls/handshake_server.go
index 6db2a6a1bf..29c8aadb40 100644
--- a/src/pkg/crypto/tls/handshake_server.go
+++ b/src/pkg/crypto/tls/handshake_server.go
@@ -4,17 +4,7 @@
package tls
-// The handshake goroutine reads handshake messages from the record processor
-// and outputs messages to be written on another channel. It updates the record
-// processor with the state of the connection via the control channel. In the
-// case of handshake messages that need synchronous processing (because they
-// affect the handling of the next record) the record processor knows about
-// them and either waits for a control message (Finished) or includes a reply
-// channel in the message (ChangeCipherSpec).
-
import (
- "crypto/hmac"
- "crypto/rc4"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
@@ -22,16 +12,6 @@ import (
"os"
)
-type cipherSuite struct {
- id uint16 // The number of this suite on the wire.
- hashLength, cipherKeyLength int
- // TODO(agl): need a method to create the cipher and hash interfaces.
-}
-
-var cipherSuites = []cipherSuite{
- {TLS_RSA_WITH_RC4_128_SHA, 20, 16},
-}
-
func (c *Conn) serverHandshake() os.Error {
config := c.config
msg, err := c.readHandshake()
@@ -54,16 +34,13 @@ func (c *Conn) serverHandshake() os.Error {
hello := new(serverHelloMsg)
- // We only support a single ciphersuite so we look for it in the list
- // of client supported suites.
- //
- // TODO(agl): Add additional cipher suites.
var suite *cipherSuite
-
+ var suiteId uint16
for _, id := range clientHello.cipherSuites {
- for _, supported := range cipherSuites {
- if supported.id == id {
- suite = &supported
+ for _, supported := range config.cipherSuites() {
+ if id == supported {
+ suite = cipherSuites[id]
+ suiteId = id
break
}
}
@@ -83,7 +60,7 @@ func (c *Conn) serverHandshake() os.Error {
}
hello.vers = vers
- hello.cipherSuite = suite.id
+ hello.cipherSuite = suiteId
t := uint32(config.time())
hello.random = make([]byte, 32)
hello.random[0] = byte(t >> 24)
@@ -225,11 +202,12 @@ func (c *Conn) serverHandshake() os.Error {
// wrong version anyway. See the discussion at the end of section
// 7.4.7.1 of RFC 4346.
- masterSecret, clientMAC, serverMAC, clientKey, serverKey :=
- keysFromPreMasterSecret11(preMasterSecret, clientHello.random, hello.random, suite.hashLength, suite.cipherKeyLength)
+ masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+ keysFromPreMasterSecret10(preMasterSecret, clientHello.random, hello.random, suite.macLen, suite.keyLen, suite.ivLen)
- cipher, _ := rc4.NewCipher(clientKey)
- c.in.prepareCipherSpec(cipher, hmac.NewSHA1(clientMAC))
+ clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */ )
+ clientHash := suite.mac(clientMAC)
+ c.in.prepareCipherSpec(clientCipher, clientHash)
c.readRecord(recordTypeChangeCipherSpec)
if err := c.error(); err != nil {
return err
@@ -265,8 +243,9 @@ func (c *Conn) serverHandshake() os.Error {
finishedHash.Write(clientFinished.marshal())
- cipher2, _ := rc4.NewCipher(serverKey)
- c.out.prepareCipherSpec(cipher2, hmac.NewSHA1(serverMAC))
+ serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */ )
+ serverHash := suite.mac(serverMAC)
+ c.out.prepareCipherSpec(serverCipher, serverHash)
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
finished := new(finishedMsg)
@@ -274,7 +253,7 @@ func (c *Conn) serverHandshake() os.Error {
c.writeRecord(recordTypeHandshake, finished.marshal())
c.handshakeComplete = true
- c.cipherSuite = TLS_RSA_WITH_RC4_128_SHA
+ c.cipherSuite = suiteId
return nil
}
diff --git a/src/pkg/crypto/tls/handshake_server_test.go b/src/pkg/crypto/tls/handshake_server_test.go
index efdbb66051..ad82e3945f 100644
--- a/src/pkg/crypto/tls/handshake_server_test.go
+++ b/src/pkg/crypto/tls/handshake_server_test.go
@@ -5,8 +5,8 @@
package tls
import (
- // "bytes"
"big"
+ "bytes"
"crypto/rsa"
"encoding/hex"
"flag"
@@ -14,7 +14,6 @@ import (
"net"
"os"
"testing"
- // "testing/script"
)
type zeroSource struct{}
@@ -36,6 +35,7 @@ func init() {
testConfig.Certificates = make([]Certificate, 1)
testConfig.Certificates[0].Certificate = [][]byte{testCertificate}
testConfig.Certificates[0].PrivateKey = testPrivateKey
+ testConfig.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
}
func testClientHelloFailure(t *testing.T, m handshakeMessage, expected os.Error) {
@@ -107,9 +107,9 @@ func TestClose(t *testing.T) {
}
-func TestHandshakeServer(t *testing.T) {
+func testServerScript(t *testing.T, name string, serverScript [][]byte, config *Config) {
c, s := net.Pipe()
- srv := Server(s, testConfig)
+ srv := Server(s, config)
go func() {
srv.Write([]byte("hello, world\n"))
srv.Close()
@@ -124,15 +124,23 @@ func TestHandshakeServer(t *testing.T) {
bb := make([]byte, len(b))
_, err := io.ReadFull(c, bb)
if err != nil {
- t.Fatalf("#%d: %s", i, err)
+ t.Fatalf("%s #%d: %s", name, i, err)
+ }
+ if !bytes.Equal(b, bb) {
+ t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b)
}
}
+}
- if !srv.haveVers || srv.vers != 0x0302 {
- t.Errorf("server version incorrect: %v %v", srv.haveVers, srv.vers)
- }
+func TestHandshakeServerRC4(t *testing.T) {
+ testServerScript(t, "RC4", rc4ServerScript, testConfig)
+}
- // TODO: check protocol
+func TestHandshakeServerAES(t *testing.T) {
+ aesConfig := new(Config)
+ *aesConfig = *testConfig
+ aesConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}
+ testServerScript(t, "AES", aesServerScript, aesConfig)
}
var serve = flag.Bool("serve", false, "run a TLS server on :10443")
@@ -185,109 +193,319 @@ var testPrivateKey = &rsa.PrivateKey{
// and then running 6.out -serve to start a server and then
// gnutls-cli --insecure --debug 100 -p 10443 localhost
// to dump a session.
-var serverScript = [][]byte{
- // Alternate write and read.
+var rc4ServerScript = [][]byte{
{
- 0x16, 0x03, 0x02, 0x00, 0x71, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x02, 0x4b, 0xd4, 0xee, 0x6e, 0xab,
- 0x0b, 0xc3, 0x01, 0xd6, 0x8d, 0xe0, 0x72, 0x7e, 0x6c, 0x04, 0xbe, 0x9a, 0x3c, 0xa3, 0xd8, 0x95,
- 0x28, 0x00, 0xb2, 0xe8, 0x1f, 0xdd, 0xb0, 0xec, 0xca, 0x46, 0x1f, 0x00, 0x00, 0x28, 0x00, 0x33,
- 0x00, 0x39, 0x00, 0x16, 0x00, 0x32, 0x00, 0x38, 0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
- 0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x00, 0x8c,
- 0x00, 0x8d, 0x00, 0x8b, 0x00, 0x8a, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x09, 0x00, 0x03, 0x02, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0f, 0x00, 0x00, 0x0c, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36,
- 0x38, 0x2e, 0x30, 0x2e, 0x31, 0x30,
+ 0x16, 0x03, 0x02, 0x00, 0x7f, 0x01, 0x00, 0x00,
+ 0x7b, 0x03, 0x02, 0x4d, 0x08, 0x1f, 0x5a, 0x7a,
+ 0x0a, 0x92, 0x2f, 0xf0, 0x73, 0x16, 0x3a, 0x88,
+ 0x14, 0x85, 0x4c, 0x98, 0x15, 0x7b, 0x65, 0xe0,
+ 0x78, 0xd0, 0xed, 0xd0, 0xf3, 0x65, 0x20, 0xeb,
+ 0x80, 0xd1, 0x0b, 0x00, 0x00, 0x34, 0x00, 0x33,
+ 0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
+ 0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
+ 0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
+ 0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
+ 0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
+ 0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
+ 0x00, 0x8a, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x09,
+ 0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
+ 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0xff,
+ 0x01, 0x00, 0x01, 0x00,
},
{
- 0x16, 0x03, 0x02, 0x00, 0x2a,
- 0x02, 0x00, 0x00, 0x26, 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, 0x05, 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, 0x00, 0x04,
- 0x0e, 0x00, 0x00, 0x00,
+ 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
+ 0x26, 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,
+ 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, 0x00, 0x04, 0x0e,
+ 0x00, 0x00, 0x00,
},
{
- 0x16, 0x03, 0x02, 0x00, 0x86, 0x10, 0x00, 0x00, 0x82, 0x00, 0x80, 0x3b, 0x7a, 0x9b, 0x05, 0xfd,
- 0x1b, 0x0d, 0x81, 0xf0, 0xac, 0x59, 0x57, 0x4e, 0xb6, 0xf5, 0x81, 0xed, 0x52, 0x78, 0xc5, 0xff,
- 0x36, 0x33, 0x9c, 0x94, 0x31, 0xc3, 0x14, 0x98, 0x5d, 0xa0, 0x49, 0x23, 0x11, 0x67, 0xdf, 0x73,
- 0x1b, 0x81, 0x0b, 0xdd, 0x10, 0xda, 0xee, 0xb5, 0x68, 0x61, 0xa9, 0xb6, 0x15, 0xae, 0x1a, 0x11,
- 0x31, 0x42, 0x2e, 0xde, 0x01, 0x4b, 0x81, 0x70, 0x03, 0xc8, 0x5b, 0xca, 0x21, 0x88, 0x25, 0xef,
- 0x89, 0xf0, 0xb7, 0xff, 0x24, 0x32, 0xd3, 0x14, 0x76, 0xe2, 0x50, 0x5c, 0x2e, 0x75, 0x9d, 0x5c,
- 0xa9, 0x80, 0x3d, 0x6f, 0xd5, 0x46, 0xd3, 0xdb, 0x42, 0x6e, 0x55, 0x81, 0x88, 0x42, 0x0e, 0x45,
- 0xfe, 0x9e, 0xe4, 0x41, 0x79, 0xcf, 0x71, 0x0e, 0xed, 0x27, 0xa8, 0x20, 0x05, 0xe9, 0x7a, 0x42,
- 0x4f, 0x05, 0x10, 0x2e, 0x52, 0x5d, 0x8c, 0x3c, 0x40, 0x49, 0x4c,
-
- 0x14, 0x03, 0x02, 0x00, 0x01, 0x01,
-
- 0x16, 0x03, 0x02, 0x00, 0x24, 0x8b, 0x12, 0x24, 0x06, 0xaa, 0x92, 0x74, 0xa1, 0x46, 0x6f, 0xc1,
- 0x4e, 0x4a, 0xf7, 0x16, 0xdd, 0xd6, 0xe1, 0x2d, 0x37, 0x0b, 0x44, 0xba, 0xeb, 0xc4, 0x6c, 0xc7,
- 0xa0, 0xb7, 0x8c, 0x9d, 0x24, 0xbd, 0x99, 0x33, 0x1e,
+ 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
+ 0x82, 0x00, 0x80, 0x3c, 0x13, 0xd7, 0x12, 0xc1,
+ 0x6a, 0xf0, 0x3f, 0x8c, 0xa1, 0x35, 0x5d, 0xc5,
+ 0x89, 0x1e, 0x9e, 0xcd, 0x32, 0xc7, 0x9e, 0xe6,
+ 0xae, 0xd5, 0xf1, 0xbf, 0x70, 0xd7, 0xa9, 0xef,
+ 0x2c, 0x4c, 0xf4, 0x22, 0xbc, 0x17, 0x17, 0xaa,
+ 0x05, 0xf3, 0x9f, 0x80, 0xf2, 0xe9, 0x82, 0x2f,
+ 0x2a, 0x15, 0x54, 0x0d, 0x16, 0x0e, 0x77, 0x4c,
+ 0x28, 0x3c, 0x03, 0x2d, 0x2d, 0xd7, 0xc8, 0x64,
+ 0xd9, 0x59, 0x4b, 0x1c, 0xf4, 0xde, 0xff, 0x2f,
+ 0xbc, 0x94, 0xaf, 0x18, 0x26, 0x37, 0xce, 0x4f,
+ 0x84, 0x74, 0x2e, 0x45, 0x66, 0x7c, 0x0c, 0x54,
+ 0x46, 0x36, 0x5f, 0x65, 0x21, 0x7b, 0x83, 0x8c,
+ 0x6d, 0x76, 0xcd, 0x0d, 0x9f, 0xda, 0x1c, 0xa4,
+ 0x6e, 0xfe, 0xb1, 0xf7, 0x09, 0x0d, 0xfb, 0x74,
+ 0x66, 0x34, 0x99, 0x89, 0x7f, 0x5f, 0x77, 0x87,
+ 0x4a, 0x66, 0x4b, 0xa9, 0x59, 0x57, 0xe3, 0x56,
+ 0x0d, 0xdd, 0xd8, 0x14, 0x03, 0x01, 0x00, 0x01,
+ 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xc0, 0x4e,
+ 0xd3, 0x0f, 0xb5, 0xc0, 0x57, 0xa6, 0x18, 0x80,
+ 0x80, 0x6b, 0x49, 0xfe, 0xbd, 0x3a, 0x7a, 0x2c,
+ 0xef, 0x70, 0xb5, 0x1c, 0xd2, 0xdf, 0x5f, 0x78,
+ 0x5a, 0xd8, 0x4f, 0xa0, 0x95, 0xb4, 0xb3, 0xb5,
+ 0xaa, 0x3b,
},
{
- 0x14, 0x03, 0x02, 0x00, 0x01,
- 0x01,
+ 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
+ 0x01, 0x00, 0x24, 0x9d, 0xc9, 0xda, 0xdf, 0xeb,
+ 0xc8, 0xdb, 0xf8, 0x94, 0xa5, 0xef, 0xd5, 0xfc,
+ 0x89, 0x01, 0x64, 0x30, 0x77, 0x5a, 0x18, 0x4b,
+ 0x16, 0x79, 0x9c, 0xf6, 0xf5, 0x09, 0x22, 0x12,
+ 0x4c, 0x3e, 0xa8, 0x8e, 0x91, 0xa5, 0x24,
+ },
+}
- 0x16, 0x03, 0x02, 0x00, 0x24,
- 0x6e, 0xd1, 0x3e, 0x49, 0x68, 0xc1, 0xa0, 0xa5, 0xb7, 0xaf, 0xb0, 0x7c, 0x52, 0x1f, 0xf7, 0x2d,
- 0x51, 0xf3, 0xa5, 0xb6, 0xf6, 0xd4, 0x18, 0x4b, 0x7a, 0xd5, 0x24, 0x1d, 0x09, 0xb6, 0x41, 0x1c,
- 0x1c, 0x98, 0xf6, 0x90,
+var aesServerScript = [][]byte{
+ {
+ 0x16, 0x03, 0x02, 0x00, 0x7f, 0x01, 0x00, 0x00,
+ 0x7b, 0x03, 0x02, 0x4d, 0x08, 0x2d, 0x0b, 0xb3,
+ 0x57, 0x85, 0x71, 0x4b, 0xfb, 0x34, 0xab, 0x16,
+ 0xd4, 0x92, 0x50, 0x81, 0x16, 0x95, 0x11, 0x28,
+ 0x1a, 0xcb, 0xff, 0x09, 0x4d, 0x23, 0xa6, 0xfe,
+ 0x2e, 0xbb, 0x78, 0x00, 0x00, 0x34, 0x00, 0x33,
+ 0x00, 0x45, 0x00, 0x39, 0x00, 0x88, 0x00, 0x16,
+ 0x00, 0x32, 0x00, 0x44, 0x00, 0x38, 0x00, 0x87,
+ 0x00, 0x13, 0x00, 0x66, 0x00, 0x90, 0x00, 0x91,
+ 0x00, 0x8f, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x41,
+ 0x00, 0x35, 0x00, 0x84, 0x00, 0x0a, 0x00, 0x05,
+ 0x00, 0x04, 0x00, 0x8c, 0x00, 0x8d, 0x00, 0x8b,
+ 0x00, 0x8a, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x09,
+ 0x00, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f,
+ 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0xff,
+ 0x01, 0x00, 0x01, 0x00,
+ },
- 0x17, 0x03, 0x02, 0x00, 0x21,
- 0x50, 0xb7, 0x92, 0x4f, 0xd8, 0x78, 0x29, 0xa2, 0xe7, 0xa5, 0xa6, 0xbd, 0x1a, 0x0c, 0xf1, 0x5a,
- 0x6e, 0x6c, 0xeb, 0x38, 0x99, 0x9b, 0x3c, 0xfd, 0xee, 0x53, 0xe8, 0x4d, 0x7b, 0xa5, 0x5b, 0x00,
+ {
+ 0x16, 0x03, 0x01, 0x00, 0x2a, 0x02, 0x00, 0x00,
+ 0x26, 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, 0x2f, 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, 0x00, 0x04, 0x0e,
+ 0x00, 0x00, 0x00,
+ },
- 0xb9,
+ {
+ 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
+ 0x82, 0x00, 0x80, 0x71, 0x9c, 0xe7, 0x23, 0xfc,
+ 0xb9, 0x19, 0x29, 0x82, 0xbf, 0xef, 0x08, 0xf7,
+ 0x99, 0x36, 0xc3, 0x4c, 0x6f, 0x05, 0xd2, 0x8b,
+ 0x62, 0x2b, 0x19, 0x9b, 0x7f, 0xc0, 0xcc, 0x48,
+ 0x30, 0x5f, 0xcd, 0xc3, 0x70, 0x55, 0x53, 0x73,
+ 0xfa, 0x79, 0x74, 0xf3, 0xa3, 0x76, 0x9f, 0xa1,
+ 0x7f, 0x98, 0xc2, 0xc0, 0xe3, 0xc5, 0xa0, 0x31,
+ 0x2f, 0xa6, 0xe8, 0x1e, 0x61, 0x46, 0xb3, 0x9b,
+ 0x4b, 0x16, 0xf1, 0x2d, 0xc7, 0x63, 0x7f, 0x79,
+ 0x22, 0x30, 0xd1, 0xf2, 0xfc, 0x77, 0x98, 0x0a,
+ 0x16, 0x11, 0x63, 0x71, 0x7f, 0x70, 0xef, 0x16,
+ 0xbb, 0x39, 0x87, 0x34, 0xac, 0x49, 0xbd, 0x07,
+ 0x67, 0xcb, 0x9c, 0xcc, 0xde, 0xef, 0xb1, 0xe0,
+ 0xdb, 0x01, 0xb5, 0x35, 0xa9, 0xb3, 0x10, 0x0c,
+ 0x4b, 0xee, 0xb3, 0x4e, 0xfd, 0xbe, 0x15, 0x27,
+ 0xf0, 0x46, 0xb2, 0x38, 0xba, 0x5f, 0xcc, 0x89,
+ 0xec, 0x29, 0x82, 0x14, 0x03, 0x01, 0x00, 0x01,
+ 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0x3c, 0xfb,
+ 0xa4, 0x12, 0xcb, 0x00, 0xf9, 0x57, 0x7e, 0x9b,
+ 0xc9, 0xdc, 0x0c, 0xba, 0x9a, 0x81, 0x62, 0xfb,
+ 0x26, 0x13, 0x53, 0xfe, 0xaa, 0xcc, 0x82, 0xbb,
+ 0xb6, 0x67, 0x7f, 0x39, 0xbe, 0x4d, 0xbb, 0xc0,
+ 0x6c, 0x24, 0x31, 0x83, 0xa5, 0x50, 0x3a, 0x75,
+ 0x32, 0x64, 0xb5, 0xdb, 0xbe, 0x0a,
+ },
- 0x15, 0x03, 0x02, 0x00, 0x16,
- 0xc7, 0xc9, 0x5a, 0x72, 0xfb, 0x02, 0xa5, 0x93, 0xdd, 0x69, 0xeb, 0x30, 0x68, 0x5e, 0xbc, 0xe0,
- 0x44, 0xb9, 0x59, 0x33, 0x68, 0xa9,
+ {
+ 0x14, 0x03, 0x01, 0x00, 0x01, 0x01, 0x16, 0x03,
+ 0x01, 0x00, 0x30, 0x43, 0x24, 0x42, 0x55, 0x08,
+ 0xe4, 0xc2, 0x15, 0xc9, 0xdb, 0x71, 0x69, 0xee,
+ 0x09, 0xc5, 0x1c, 0xfd, 0x46, 0x10, 0xa0, 0x68,
+ 0x21, 0xf2, 0x48, 0xac, 0x6c, 0xc0, 0x2b, 0x62,
+ 0x07, 0x8f, 0x48, 0x33, 0x0a, 0x6b, 0x62, 0x28,
+ 0x2e, 0x2c, 0xad, 0xcb, 0x34, 0x85, 0xca, 0x2e,
+ 0xcd, 0x84, 0xf0,
},
}
diff --git a/src/pkg/crypto/tls/prf.go b/src/pkg/crypto/tls/prf.go
index b206d26a4a..478cf65f91 100644
--- a/src/pkg/crypto/tls/prf.go
+++ b/src/pkg/crypto/tls/prf.go
@@ -44,8 +44,8 @@ func pHash(result, secret, seed []byte, hash func() hash.Hash) {
}
}
-// pRF11 implements the TLS 1.1 pseudo-random function, as defined in RFC 4346, section 5.
-func pRF11(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
@@ -75,25 +75,32 @@ var clientFinishedLabel = []byte("client finished")
var serverFinishedLabel = []byte("server finished")
// keysFromPreMasterSecret generates the connection keys from the pre master
-// secret, given the lengths of the MAC and cipher keys, as defined in RFC
-// 4346, section 6.3.
-func keysFromPreMasterSecret11(preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen int) (masterSecret, clientMAC, serverMAC, clientKey, serverKey []byte) {
+// secret, given the lengths of the MAC key, cipher key and IV, as defined in
+// RFC 2246, section 6.3.
+func keysFromPreMasterSecret10(preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
var seed [tlsRandomLength * 2]byte
copy(seed[0:len(clientRandom)], clientRandom)
copy(seed[len(clientRandom):], serverRandom)
masterSecret = make([]byte, masterSecretLength)
- pRF11(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
+ pRF10(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
copy(seed[0:len(clientRandom)], serverRandom)
copy(seed[len(serverRandom):], clientRandom)
- n := 2*macLen + 2*keyLen
+ n := 2*macLen + 2*keyLen + 2*ivLen
keyMaterial := make([]byte, n)
- pRF11(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
- clientMAC = keyMaterial[0:macLen]
- serverMAC = keyMaterial[macLen : macLen*2]
- clientKey = keyMaterial[macLen*2 : macLen*2+keyLen]
- serverKey = keyMaterial[macLen*2+keyLen:]
+ pRF10(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
+ clientMAC = keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+ serverMAC = keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+ clientKey = keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+ serverKey = keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+ clientIV = keyMaterial[:ivLen]
+ keyMaterial = keyMaterial[ivLen:]
+ serverIV = keyMaterial[:ivLen]
return
}
@@ -125,7 +132,7 @@ func finishedSum(md5, sha1, label, masterSecret []byte) []byte {
copy(seed, md5)
copy(seed[len(md5):], sha1)
out := make([]byte, finishedVerifyLength)
- pRF11(out, masterSecret, label, seed)
+ pRF10(out, masterSecret, label, seed)
return out
}
diff --git a/src/pkg/crypto/tls/prf_test.go b/src/pkg/crypto/tls/prf_test.go
index d99bab5b5e..f8c4acb9d2 100644
--- a/src/pkg/crypto/tls/prf_test.go
+++ b/src/pkg/crypto/tls/prf_test.go
@@ -47,7 +47,7 @@ func TestKeysFromPreMasterSecret(t *testing.T) {
in, _ := hex.DecodeString(test.preMasterSecret)
clientRandom, _ := hex.DecodeString(test.clientRandom)
serverRandom, _ := hex.DecodeString(test.serverRandom)
- master, clientMAC, serverMAC, clientKey, serverKey := keysFromPreMasterSecret11(in, clientRandom, serverRandom, test.macLen, test.keyLen)
+ master, clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromPreMasterSecret10(in, clientRandom, serverRandom, test.macLen, test.keyLen, 0)
masterString := hex.EncodeToString(master)
clientMACString := hex.EncodeToString(clientMAC)
serverMACString := hex.EncodeToString(serverMAC)