crypto/tls: allow the server to enforce its ciphersuite preferences.

Previously, Go TLS servers always took the client's preferences into
account when selecting a ciphersuite. This change adds the option of
using the server's preferences, which can be expressed by setting
tls.Config.CipherSuites.

This mirrors Apache's SSLHonorCipherOrder directive.

R=golang-dev, nightlyone, bradfitz, ality
CC=golang-dev
https://golang.org/cl/7163043
This commit is contained in:
Adam Langley 2013-01-22 10:10:38 -05:00
parent fd32ac4bae
commit 793cbd5b81
3 changed files with 64 additions and 5 deletions

View file

@ -180,8 +180,17 @@ Curves:
return true, nil
}
for _, id := range hs.clientHello.cipherSuites {
if hs.suite = c.tryCipherSuite(id, hs.ellipticOk); hs.suite != nil {
var preferenceList, supportedList []uint16
if c.config.PreferServerCipherSuites {
preferenceList = c.config.cipherSuites()
supportedList = hs.clientHello.cipherSuites
} else {
preferenceList = hs.clientHello.cipherSuites
supportedList = c.config.cipherSuites()
}
for _, id := range preferenceList {
if hs.suite = c.tryCipherSuite(id, supportedList, hs.ellipticOk); hs.suite != nil {
break
}
}
@ -222,7 +231,7 @@ func (hs *serverHandshakeState) checkForResumption() bool {
}
// Check that we also support the ciphersuite from the session.
hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, hs.ellipticOk)
hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.ellipticOk)
if hs.suite == nil {
return false
}
@ -568,8 +577,8 @@ 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, ellipticOk bool) *cipherSuite {
for _, supported := range c.config.cipherSuites() {
func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, ellipticOk bool) *cipherSuite {
for _, supported := range supportedCipherSuites {
if id == supported {
var candidate *cipherSuite