cmd/*, lib/tlsutil: Refactor TLS stuff (fixes #5256) (#5276)

This changes the TLS and certificate handling in a few ways:

- We always use TLS 1.2, both for sync connections (as previously) and
  the GUI/REST/discovery stuff. This is a tightening of the requirements
  on the GUI. AS far as I can tell from caniusethis.com every browser from
  2013 and forward supports TLS 1.2, so I think we should be fine.

- We always greate ECDSA certificates. Previously we'd create
  ECDSA-with-RSA certificates for sync connections and pure RSA
  certificates for the web stuff. The new default is more modern and the
  same everywhere. These certificates are OK in TLS 1.2.

- We use the Go CPU detection stuff to choose the cipher suites to use,
  indirectly. The TLS package uses CPU capabilities probing to select
  either AES-GCM (fast if we have AES-NI) or ChaCha20 (faster if we
  don't). These CPU detection things aren't exported though, so the tlsutil
  package now does a quick TLS handshake with itself as part of init().
  If the chosen cipher suite was AES-GCM we prioritize that, otherwise we
  prefer ChaCha20. Some might call this ugly. I think it's awesome.
This commit is contained in:
Jakob Borg
2018-10-21 14:17:50 +09:00
committed by GitHub
parent c0be9987d0
commit 8519a24ba6
8 changed files with 217 additions and 69 deletions

View File

@@ -11,6 +11,7 @@ package tlsutil
import (
"bytes"
"crypto/tls"
"io"
"net"
"testing"
@@ -74,6 +75,53 @@ func TestUnionedConnection(t *testing.T) {
}
}
func TestCheckCipherSuites(t *testing.T) {
// This is the set of cipher suites we expect - only the order should
// differ.
allSuites := []uint16{
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,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
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,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
}
suites := buildCipherSuites()
if len(suites) != len(allSuites) {
t.Fatal("should get a list representing all suites")
}
// Check that the returned list of suites doesn't contain anything
// unexpecteds and is free from duplicates.
seen := make(map[uint16]struct{})
nextSuite:
for _, s0 := range suites {
if _, ok := seen[s0]; ok {
t.Fatal("duplicate suite", s0)
}
for _, s1 := range allSuites {
if s0 == s1 {
seen[s0] = struct{}{}
continue nextSuite
}
}
t.Fatal("got unknown suite", s0)
}
}
type fakeAccepter struct {
data []byte
}