]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: don't rely on map iteration order.
authorAdam Langley <agl@golang.org>
Mon, 28 Nov 2011 20:34:16 +0000 (15:34 -0500)
committerAdam Langley <agl@golang.org>
Mon, 28 Nov 2011 20:34:16 +0000 (15:34 -0500)
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

src/pkg/crypto/tls/cipher_suites.go
src/pkg/crypto/tls/common.go
src/pkg/crypto/tls/handshake_client.go
src/pkg/crypto/tls/handshake_server.go

index 1134f36258374b24a642e8fe87b56c7229da34b4..ff0ff2b09a14821467993876b9b281f680b17190 100644 (file)
@@ -37,6 +37,7 @@ type keyAgreement interface {
 // A cipherSuite is a specific combination of key agreement, cipher and MAC
 // function. All cipher suites currently assume RSA key agreement.
 type cipherSuite struct {
+       id uint16
        // the lengths, in bytes, of the key material needed for each component.
        keyLen int
        macLen int
@@ -50,13 +51,13 @@ type cipherSuite struct {
        mac      func(version uint16, macKey []byte) macFunction
 }
 
-var cipherSuites = map[uint16]*cipherSuite{
-       TLS_RSA_WITH_RC4_128_SHA:            &cipherSuite{16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
-       TLS_RSA_WITH_3DES_EDE_CBC_SHA:       &cipherSuite{24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
-       TLS_RSA_WITH_AES_128_CBC_SHA:        &cipherSuite{16, 20, 16, rsaKA, false, cipherAES, macSHA1},
-       TLS_ECDHE_RSA_WITH_RC4_128_SHA:      &cipherSuite{16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
-       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: &cipherSuite{24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
-       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:  &cipherSuite{16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
+var cipherSuites = []*cipherSuite{
+       &cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
+       &cipherSuite{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
+       &cipherSuite{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
+       &cipherSuite{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
+       &cipherSuite{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, 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{} {
@@ -159,15 +160,20 @@ func ecdheRSAKA() keyAgreement {
        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.
-func mutualCipherSuite(have []uint16, want uint16) (suite *cipherSuite, id uint16) {
+func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
        for _, id := range have {
                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
index ea520859b827c9267a85fd283525cdeeef76c179..e90424868283da38821eb22b37e7f034592a26a8 100644 (file)
@@ -315,9 +315,7 @@ var (
 
 func initDefaultCipherSuites() {
        varDefaultCipherSuites = make([]uint16, len(cipherSuites))
-       i := 0
-       for id := range cipherSuites {
-               varDefaultCipherSuites[i] = id
-               i++
+       for i, suite := range cipherSuites {
+               varDefaultCipherSuites[i] = suite.id
        }
 }
index aed991ccd1bfb00229a382557dd00d1cba0eb8d8..0f41008bf433c9a59ac5ae1cbfcb7501ce7d3eb3 100644 (file)
@@ -72,7 +72,7 @@ func (c *Conn) clientHandshake() error {
                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 {
                return c.sendAlert(alertHandshakeFailure)
        }
@@ -292,7 +292,7 @@ func (c *Conn) clientHandshake() error {
        }
 
        c.handshakeComplete = true
-       c.cipherSuite = suiteId
+       c.cipherSuite = suite.id
        return nil
 }
 
index d5af084eda5b094c0d157e6893dae6abb31c3cd7..1fa4585189aa32242cd5ddd22b6dd251a3ff1467 100644 (file)
@@ -56,18 +56,25 @@ Curves:
        ellipticOk := supportedCurve && supportedPointFormat
 
        var suite *cipherSuite
-       var suiteId uint16
 FindCipherSuite:
        for _, id := range clientHello.cipherSuites {
                for _, supported := range config.cipherSuites() {
                        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
                                // support for this client.
                                if suite.elliptic && !ellipticOk {
                                        continue
                                }
-                               suiteId = id
                                break FindCipherSuite
                        }
                }
@@ -87,7 +94,7 @@ FindCipherSuite:
        }
 
        hello.vers = vers
-       hello.cipherSuite = suiteId
+       hello.cipherSuite = suite.id
        t := uint32(config.time())
        hello.random = make([]byte, 32)
        hello.random[0] = byte(t >> 24)
@@ -296,7 +303,7 @@ FindCipherSuite:
        c.writeRecord(recordTypeHandshake, finished.marshal())
 
        c.handshakeComplete = true
-       c.cipherSuite = suiteId
+       c.cipherSuite = suite.id
 
        return nil
 }