Commit 1eb7ca92 authored by Adam Langley's avatar Adam Langley

crypto/tls: don't rely on map iteration order.

Previously we were using the map iteration order to set the order of
the cipher suites in the ClientHello.

R=bradfitz
CC=golang-dev
https://golang.org/cl/5440048
parent 5f6027e9
...@@ -37,6 +37,7 @@ type keyAgreement interface { ...@@ -37,6 +37,7 @@ type keyAgreement interface {
// A cipherSuite is a specific combination of key agreement, cipher and MAC // A cipherSuite is a specific combination of key agreement, cipher and MAC
// function. All cipher suites currently assume RSA key agreement. // function. All cipher suites currently assume RSA key agreement.
type cipherSuite struct { type cipherSuite struct {
id uint16
// the lengths, in bytes, of the key material needed for each component. // the lengths, in bytes, of the key material needed for each component.
keyLen int keyLen int
macLen int macLen int
...@@ -50,13 +51,13 @@ type cipherSuite struct { ...@@ -50,13 +51,13 @@ type cipherSuite struct {
mac func(version uint16, macKey []byte) macFunction mac func(version uint16, macKey []byte) macFunction
} }
var cipherSuites = map[uint16]*cipherSuite{ var cipherSuites = []*cipherSuite{
TLS_RSA_WITH_RC4_128_SHA: &cipherSuite{16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, &cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
TLS_RSA_WITH_3DES_EDE_CBC_SHA: &cipherSuite{24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, &cipherSuite{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
TLS_RSA_WITH_AES_128_CBC_SHA: &cipherSuite{16, 20, 16, rsaKA, false, cipherAES, macSHA1}, &cipherSuite{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
TLS_ECDHE_RSA_WITH_RC4_128_SHA: &cipherSuite{16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, &cipherSuite{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: &cipherSuite{24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, &cipherSuite{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: &cipherSuite{16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, &cipherSuite{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
} }
func cipherRC4(key, iv []byte, isRead bool) interface{} { func cipherRC4(key, iv []byte, isRead bool) interface{} {
...@@ -159,15 +160,20 @@ func ecdheRSAKA() keyAgreement { ...@@ -159,15 +160,20 @@ func ecdheRSAKA() keyAgreement {
return new(ecdheRSAKeyAgreement) return new(ecdheRSAKeyAgreement)
} }
// mutualCipherSuite returns a cipherSuite and its id given a list of supported // mutualCipherSuite returns a cipherSuite given a list of supported
// ciphersuites and the id requested by the peer. // ciphersuites and the id requested by the peer.
func mutualCipherSuite(have []uint16, want uint16) (suite *cipherSuite, id uint16) { func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
for _, id := range have { for _, id := range have {
if id == want { if id == want {
return cipherSuites[id], id for _, suite := range cipherSuites {
if suite.id == want {
return suite
}
}
return nil
} }
} }
return return nil
} }
// A list of the possible cipher suite ids. Taken from // A list of the possible cipher suite ids. Taken from
......
...@@ -315,9 +315,7 @@ var ( ...@@ -315,9 +315,7 @@ var (
func initDefaultCipherSuites() { func initDefaultCipherSuites() {
varDefaultCipherSuites = make([]uint16, len(cipherSuites)) varDefaultCipherSuites = make([]uint16, len(cipherSuites))
i := 0 for i, suite := range cipherSuites {
for id := range cipherSuites { varDefaultCipherSuites[i] = suite.id
varDefaultCipherSuites[i] = id
i++
} }
} }
...@@ -72,7 +72,7 @@ func (c *Conn) clientHandshake() error { ...@@ -72,7 +72,7 @@ func (c *Conn) clientHandshake() error {
return errors.New("server advertised unrequested NPN") return errors.New("server advertised unrequested NPN")
} }
suite, suiteId := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite) suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
if suite == nil { if suite == nil {
return c.sendAlert(alertHandshakeFailure) return c.sendAlert(alertHandshakeFailure)
} }
...@@ -292,7 +292,7 @@ func (c *Conn) clientHandshake() error { ...@@ -292,7 +292,7 @@ func (c *Conn) clientHandshake() error {
} }
c.handshakeComplete = true c.handshakeComplete = true
c.cipherSuite = suiteId c.cipherSuite = suite.id
return nil return nil
} }
......
...@@ -56,18 +56,25 @@ Curves: ...@@ -56,18 +56,25 @@ Curves:
ellipticOk := supportedCurve && supportedPointFormat ellipticOk := supportedCurve && supportedPointFormat
var suite *cipherSuite var suite *cipherSuite
var suiteId uint16
FindCipherSuite: FindCipherSuite:
for _, id := range clientHello.cipherSuites { for _, id := range clientHello.cipherSuites {
for _, supported := range config.cipherSuites() { for _, supported := range config.cipherSuites() {
if id == supported { if id == supported {
suite = cipherSuites[id] suite = nil
for _, s := range cipherSuites {
if s.id == id {
suite = s
break
}
}
if suite == nil {
continue
}
// Don't select a ciphersuite which we can't // Don't select a ciphersuite which we can't
// support for this client. // support for this client.
if suite.elliptic && !ellipticOk { if suite.elliptic && !ellipticOk {
continue continue
} }
suiteId = id
break FindCipherSuite break FindCipherSuite
} }
} }
...@@ -87,7 +94,7 @@ FindCipherSuite: ...@@ -87,7 +94,7 @@ FindCipherSuite:
} }
hello.vers = vers hello.vers = vers
hello.cipherSuite = suiteId hello.cipherSuite = suite.id
t := uint32(config.time()) t := uint32(config.time())
hello.random = make([]byte, 32) hello.random = make([]byte, 32)
hello.random[0] = byte(t >> 24) hello.random[0] = byte(t >> 24)
...@@ -296,7 +303,7 @@ FindCipherSuite: ...@@ -296,7 +303,7 @@ FindCipherSuite:
c.writeRecord(recordTypeHandshake, finished.marshal()) c.writeRecord(recordTypeHandshake, finished.marshal())
c.handshakeComplete = true c.handshakeComplete = true
c.cipherSuite = suiteId c.cipherSuite = suite.id
return nil return nil
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment