mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
crypto/tls: disable RC4 by default.
RC4 is frowned upon[1] at this point and major providers are disabling it by default[2]. Those who still need RC4 support in crypto/tls can enable it by specifying the CipherSuites slice in crypto/tls.Config explicitly. Fixes #10094. [1] https://tools.ietf.org/html/rfc7465 [2] https://blog.cloudflare.com/killing-rc4-the-long-goodbye/ Change-Id: Ia03a456f7e7a4362b706392b0e3c4cc93ce06f9f Reviewed-on: https://go-review.googlesource.com/7647 Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
parent
a432568300
commit
d26fdf295e
3 changed files with 41 additions and 12 deletions
|
|
@ -49,6 +49,9 @@ const (
|
||||||
// suiteTLS12 indicates that the cipher suite should only be advertised
|
// suiteTLS12 indicates that the cipher suite should only be advertised
|
||||||
// and accepted when using TLS 1.2.
|
// and accepted when using TLS 1.2.
|
||||||
suiteTLS12
|
suiteTLS12
|
||||||
|
// suiteDefaultOff indicates that this cipher suite is not included by
|
||||||
|
// default.
|
||||||
|
suiteDefaultOff
|
||||||
)
|
)
|
||||||
|
|
||||||
// A cipherSuite is a specific combination of key agreement, cipher and MAC
|
// A cipherSuite is a specific combination of key agreement, cipher and MAC
|
||||||
|
|
@ -75,13 +78,13 @@ var cipherSuites = []*cipherSuite{
|
||||||
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM, crypto.SHA256},
|
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM, crypto.SHA256},
|
||||||
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM, crypto.SHA384},
|
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM, crypto.SHA384},
|
||||||
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM, crypto.SHA384},
|
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM, crypto.SHA384},
|
||||||
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteDefaultOff, cipherRC4, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil, crypto.SHA256},
|
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil, crypto.SHA256},
|
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil, crypto.SHA256},
|
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil, crypto.SHA256},
|
||||||
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil, crypto.SHA256},
|
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil, crypto.SHA256},
|
||||||
|
|
|
||||||
|
|
@ -611,9 +611,12 @@ func defaultCipherSuites() []uint16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initDefaultCipherSuites() {
|
func initDefaultCipherSuites() {
|
||||||
varDefaultCipherSuites = make([]uint16, len(cipherSuites))
|
varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites))
|
||||||
for i, suite := range cipherSuites {
|
for _, suite := range cipherSuites {
|
||||||
varDefaultCipherSuites[i] = suite.id
|
if suite.flags&suiteDefaultOff != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,15 @@ func (zeroSource) Read(b []byte) (n int, err error) {
|
||||||
|
|
||||||
var testConfig *Config
|
var testConfig *Config
|
||||||
|
|
||||||
|
func allCipherSuites() []uint16 {
|
||||||
|
ids := make([]uint16, len(cipherSuites))
|
||||||
|
for i, suite := range cipherSuites {
|
||||||
|
ids[i] = suite.id
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
testConfig = &Config{
|
testConfig = &Config{
|
||||||
Time: func() time.Time { return time.Unix(0, 0) },
|
Time: func() time.Time { return time.Unix(0, 0) },
|
||||||
|
|
@ -45,6 +54,7 @@ func init() {
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
MinVersion: VersionSSL30,
|
MinVersion: VersionSSL30,
|
||||||
MaxVersion: VersionTLS12,
|
MaxVersion: VersionTLS12,
|
||||||
|
CipherSuites: allCipherSuites(),
|
||||||
}
|
}
|
||||||
testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
|
testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
|
||||||
testConfig.Certificates[0].PrivateKey = testRSAPrivateKey
|
testConfig.Certificates[0].PrivateKey = testRSAPrivateKey
|
||||||
|
|
@ -53,7 +63,7 @@ func init() {
|
||||||
testConfig.BuildNameToCertificate()
|
testConfig.BuildNameToCertificate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr string) {
|
func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) {
|
||||||
// Create in-memory network connection,
|
// Create in-memory network connection,
|
||||||
// send message to server. Should return
|
// send message to server. Should return
|
||||||
// expected error.
|
// expected error.
|
||||||
|
|
@ -66,7 +76,7 @@ func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr str
|
||||||
cli.writeRecord(recordTypeHandshake, m.marshal())
|
cli.writeRecord(recordTypeHandshake, m.marshal())
|
||||||
c.Close()
|
c.Close()
|
||||||
}()
|
}()
|
||||||
err := Server(s, testConfig).Handshake()
|
err := Server(s, serverConfig).Handshake()
|
||||||
s.Close()
|
s.Close()
|
||||||
if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
|
if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
|
||||||
t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr)
|
t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr)
|
||||||
|
|
@ -74,14 +84,14 @@ func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr str
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimpleError(t *testing.T) {
|
func TestSimpleError(t *testing.T) {
|
||||||
testClientHelloFailure(t, &serverHelloDoneMsg{}, "unexpected handshake message")
|
testClientHelloFailure(t, testConfig, &serverHelloDoneMsg{}, "unexpected handshake message")
|
||||||
}
|
}
|
||||||
|
|
||||||
var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
|
var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
|
||||||
|
|
||||||
func TestRejectBadProtocolVersion(t *testing.T) {
|
func TestRejectBadProtocolVersion(t *testing.T) {
|
||||||
for _, v := range badProtocolVersions {
|
for _, v := range badProtocolVersions {
|
||||||
testClientHelloFailure(t, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
|
testClientHelloFailure(t, testConfig, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +101,7 @@ func TestNoSuiteOverlap(t *testing.T) {
|
||||||
cipherSuites: []uint16{0xff00},
|
cipherSuites: []uint16{0xff00},
|
||||||
compressionMethods: []uint8{0},
|
compressionMethods: []uint8{0},
|
||||||
}
|
}
|
||||||
testClientHelloFailure(t, clientHello, "no cipher suite supported by both client and server")
|
testClientHelloFailure(t, testConfig, clientHello, "no cipher suite supported by both client and server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNoCompressionOverlap(t *testing.T) {
|
func TestNoCompressionOverlap(t *testing.T) {
|
||||||
|
|
@ -100,7 +110,20 @@ func TestNoCompressionOverlap(t *testing.T) {
|
||||||
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
|
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
|
||||||
compressionMethods: []uint8{0xff},
|
compressionMethods: []uint8{0xff},
|
||||||
}
|
}
|
||||||
testClientHelloFailure(t, clientHello, "client does not support uncompressed connections")
|
testClientHelloFailure(t, testConfig, clientHello, "client does not support uncompressed connections")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoRC4ByDefault(t *testing.T) {
|
||||||
|
clientHello := &clientHelloMsg{
|
||||||
|
vers: 0x0301,
|
||||||
|
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
|
||||||
|
compressionMethods: []uint8{0},
|
||||||
|
}
|
||||||
|
serverConfig := *testConfig
|
||||||
|
// Reset the enabled cipher suites to nil in order to test the
|
||||||
|
// defaults.
|
||||||
|
serverConfig.CipherSuites = nil
|
||||||
|
testClientHelloFailure(t, &serverConfig, clientHello, "no cipher suite supported by both client and server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenegotiationExtension(t *testing.T) {
|
func TestRenegotiationExtension(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue