From 91ff734327554f027caeaa5a7341b8f82a813b99 Mon Sep 17 00:00:00 2001 From: elcore Date: Fri, 17 Feb 2017 01:19:58 +0100 Subject: [PATCH] Implement curve X25519 (Golang 1.8) (#1376) * Implement curve X25519 * caddytls: Added a default curves list * caddytls: Improve tests --- caddytls/config.go | 27 ++++++++++++++++++++++++--- caddytls/setup_test.go | 20 ++++++++++++++++---- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/caddytls/config.go b/caddytls/config.go index 6632aed28..06afc7cde 100644 --- a/caddytls/config.go +++ b/caddytls/config.go @@ -311,6 +311,11 @@ func MakeTLSConfig(configs []*Config) (*tls.Config, error) { config.CipherSuites = append([]uint16{tls.TLS_FALLBACK_SCSV}, config.CipherSuites...) } + // Default curves + if len(config.CurvePreferences) == 0 { + config.CurvePreferences = defaultCurves + } + // Set up client authentication if enabled if config.ClientAuth != tls.NoClientCert { pool := x509.NewCertPool() @@ -367,6 +372,11 @@ func SetDefaultTLSParams(config *Config) { // (prepend since having it at end breaks http2 due to non-h2-approved suites before it) config.Ciphers = append([]uint16{tls.TLS_FALLBACK_SCSV}, config.Ciphers...) + // If no curves provided, use default list + if len(config.CurvePreferences) == 0 { + config.CurvePreferences = defaultCurves + } + // Set default protocol min and max versions - must balance compatibility and security if config.ProtocolMinVersion == 0 { config.ProtocolMinVersion = tls.VersionTLS11 @@ -438,9 +448,20 @@ var defaultCiphers = []uint16{ // Map of supported curves // https://golang.org/pkg/crypto/tls/#CurveID var supportedCurvesMap = map[string]tls.CurveID{ - "P256": tls.CurveP256, - "P384": tls.CurveP384, - "P521": tls.CurveP521, + "X25519": tls.X25519, + "P256": tls.CurveP256, + "P384": tls.CurveP384, + "P521": tls.CurveP521, +} + +// List of all the curves we want to use by default +// +// This list should only include curves which are fast by design (e.g. X25519) +// and those for which an optimized assembly implementation exists (e.g. P256). +// The latter ones can be found here: https://github.com/golang/go/tree/master/src/crypto/elliptic +var defaultCurves = []tls.CurveID{ + tls.X25519, + tls.CurveP256, } const ( diff --git a/caddytls/setup_test.go b/caddytls/setup_test.go index a008bcd2b..749090b0c 100644 --- a/caddytls/setup_test.go +++ b/caddytls/setup_test.go @@ -88,6 +88,18 @@ func TestSetupParseBasic(t *testing.T) { if !cfg.PreferServerCipherSuites { t.Error("Expected PreferServerCipherSuites = true, but was false") } + + // Ensure curve count is correct + if len(cfg.CurvePreferences) != len(defaultCurves) { + t.Errorf("Expected %v Curves, got %v", len(defaultCurves), len(cfg.CurvePreferences)) + } + + // Ensure curve ordering is correct + for i, actual := range cfg.CurvePreferences { + if actual != defaultCurves[i] { + t.Errorf("Expected curve in position %d to be %0x, got %0x", i, defaultCurves[i], actual) + } + } } func TestSetupParseIncompleteParams(t *testing.T) { @@ -288,7 +300,7 @@ func TestSetupParseWithKeyType(t *testing.T) { func TestSetupParseWithCurves(t *testing.T) { params := `tls { - curves p256 p384 p521 + curves x25519 p256 p384 p521 }` cfg := new(Config) RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg }) @@ -299,11 +311,11 @@ func TestSetupParseWithCurves(t *testing.T) { t.Errorf("Expected no errors, got: %v", err) } - if len(cfg.CurvePreferences) != 3 { - t.Errorf("Expected 3 curves, got %v", len(cfg.CurvePreferences)) + if len(cfg.CurvePreferences) != 4 { + t.Errorf("Expected 4 curves, got %v", len(cfg.CurvePreferences)) } - expectedCurves := []tls.CurveID{tls.CurveP256, tls.CurveP384, tls.CurveP521} + expectedCurves := []tls.CurveID{tls.X25519, tls.CurveP256, tls.CurveP384, tls.CurveP521} // Ensure ordering is correct for i, actual := range cfg.CurvePreferences {