This makes us use TLS 1.3+ on sync connections by default. A new option `insecureAllowOldTLSVersions` exists to allow communication with TLS 1.2-only clients (roughly Syncthing 1.2.2 and older). Even with that option set you get a slightly simplified setup, with the cipher suite order fixed instead of auto detected.
This commit is contained in:
+20
-99
@@ -29,30 +29,22 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
// The list of cipher suites we will use / suggest for TLS connections.
|
||||
// This is built based on the component slices below, depending on what
|
||||
// the hardware prefers.
|
||||
cipherSuites []uint16
|
||||
// The list of cipher suites we will use / suggest for TLS 1.2 connections.
|
||||
cipherSuites = []uint16{
|
||||
// Suites that are good and fast on hardware *without* AES-NI.
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
|
||||
// Suites that are good and fast on hardware with AES-NI. These are
|
||||
// reordered from the Go default to put the 256 bit ciphers above the
|
||||
// 128 bit ones - because that looks cooler, even though there is
|
||||
// probably no relevant difference in strength yet.
|
||||
gcmSuites = []uint16{
|
||||
// Suites that are good and fast on hardware with AES-NI. These are
|
||||
// reordered from the Go default to put the 256 bit ciphers above the
|
||||
// 128 bit ones - because that looks cooler, even though there is
|
||||
// probably no relevant difference in strength yet.
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}
|
||||
|
||||
// Suites that are good and fast on hardware *without* AES-NI.
|
||||
chaChaSuites = []uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
}
|
||||
|
||||
// The rest of the suites, minus DES stuff.
|
||||
otherSuites = []uint16{
|
||||
// The rest of the suites, minus DES stuff.
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
@@ -67,13 +59,18 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Creates the list of ciper suites that SecureDefault uses.
|
||||
cipherSuites = buildCipherSuites()
|
||||
// SecureDefault returns a tls.Config with reasonable, secure defaults set.
|
||||
// This variant allows only TLS 1.3.
|
||||
func SecureDefaultTLS13() *tls.Config {
|
||||
return &tls.Config{
|
||||
// TLS 1.3 is the minimum we accept
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
}
|
||||
|
||||
// SecureDefault returns a tls.Config with reasonable, secure defaults set.
|
||||
func SecureDefault() *tls.Config {
|
||||
// SecureDefaultWithTLS12 returns a tls.Config with reasonable, secure
|
||||
// defaults set. This variant allows TLS 1.2.
|
||||
func SecureDefaultWithTLS12() *tls.Config {
|
||||
// paranoia
|
||||
cs := make([]uint16, len(cipherSuites))
|
||||
copy(cs, cipherSuites)
|
||||
@@ -245,79 +242,3 @@ func pemBlockForKey(priv interface{}) (*pem.Block, error) {
|
||||
return nil, errors.New("unknown key type")
|
||||
}
|
||||
}
|
||||
|
||||
// buildCipherSuites returns a list of cipher suites with either AES-GCM or
|
||||
// ChaCha20 at the top. This takes advantage of the CPU detection that the
|
||||
// TLS package does to create an optimal cipher suite list for the current
|
||||
// hardware.
|
||||
func buildCipherSuites() []uint16 {
|
||||
pref := preferredCipherSuite()
|
||||
for _, suite := range gcmSuites {
|
||||
if suite == pref {
|
||||
// Go preferred an AES-GCM suite. Use those first.
|
||||
return append(gcmSuites, append(chaChaSuites, otherSuites...)...)
|
||||
}
|
||||
}
|
||||
// Use ChaCha20 at the top, then AES-GCM etc.
|
||||
return append(chaChaSuites, append(gcmSuites, otherSuites...)...)
|
||||
}
|
||||
|
||||
// preferredCipherSuite returns the cipher suite that is selected for a TLS
|
||||
// connection made with the Go defaults to ourselves. This is (currently,
|
||||
// probably) either a ChaCha20 suite or an AES-GCM suite, depending on what
|
||||
// the CPU detection has decided is fastest on this hardware.
|
||||
//
|
||||
// The function will return zero if something odd happens, and there's no
|
||||
// guarantee what cipher suite would be chosen anyway, so the return value
|
||||
// should be taken with a grain of salt.
|
||||
func preferredCipherSuite() uint16 {
|
||||
// This is one of our certs from NewCertificate above, to avoid having
|
||||
// to generate one at init time just for this function.
|
||||
crtBs := []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIBXDCCAQOgAwIBAgIIQUODl2/bE4owCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ
|
||||
c3luY3RoaW5nMB4XDTE4MTAxNDA2MjU0M1oXDTQ5MTIzMTIzNTk1OVowFDESMBAG
|
||||
A1UEAxMJc3luY3RoaW5nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMqP+1lL4
|
||||
0s/xtI3ygExzYc/GvLHr0qetpBrUVHaDwS/cR1yXDsYaJpJcUNtrf1XK49IlpWW1
|
||||
Ds8seQsSg7/9BaM/MD0wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
|
||||
BwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMAoGCCqGSM49BAMCA0cAMEQCIFxY
|
||||
MDBA92FKqZYSZjmfdIbT1OI6S9CnAFvL/pJZJwNuAiAV7osre2NiCHtXABOvsGrH
|
||||
vKWqDvXcHr6Tlo+LmTAdyg==
|
||||
-----END CERTIFICATE-----
|
||||
`)
|
||||
keyBs := []byte(`-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIHtPxVHlj6Bhi9RgSR2/lAtIQ7APM9wmpaJAcds6TD2CoAoGCCqGSM49
|
||||
AwEHoUQDQgAEMqP+1lL40s/xtI3ygExzYc/GvLHr0qetpBrUVHaDwS/cR1yXDsYa
|
||||
JpJcUNtrf1XK49IlpWW1Ds8seQsSg7/9BQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
`)
|
||||
|
||||
cert, err := tls.X509KeyPair(crtBs, keyBs)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
serverCfg := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
PreferServerCipherSuites: true,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
clientCfg := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
c0, c1 := net.Pipe()
|
||||
|
||||
c := tls.Client(c0, clientCfg)
|
||||
go func() {
|
||||
c.Handshake()
|
||||
}()
|
||||
|
||||
s := tls.Server(c1, serverCfg)
|
||||
if err := s.Handshake(); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return c.ConnectionState().CipherSuite
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ func TestCheckCipherSuites(t *testing.T) {
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
}
|
||||
|
||||
suites := buildCipherSuites()
|
||||
suites := SecureDefaultWithTLS12().CipherSuites
|
||||
|
||||
if len(suites) != len(allSuites) {
|
||||
t.Fatal("should get a list representing all suites")
|
||||
|
||||
Reference in New Issue
Block a user