From 6babc473e6aa81a06bd00104ccfc577050f0f6bc Mon Sep 17 00:00:00 2001 From: Daniele Sluijters Date: Sat, 8 Feb 2020 14:59:32 +0100 Subject: [PATCH] Add CipherSuites and InsecureCipherSuites As part of Go 1.14 the CipherSuites and InsecureCipherSuites functions got added to the TLS package, returning a slice of *tls.CipherSuite. Relates to #148 --- cipher_suite.go | 18 ++++++++++++++ cipher_suite_go114.go | 36 +++++++++++++++++++++++++++ cipher_suite_go114_test.go | 51 ++++++++++++++++++++++++++++++++++++++ cipher_suite_test.go | 7 ++++++ record_layer_header.go | 4 +++ 5 files changed, 116 insertions(+) create mode 100644 cipher_suite_go114.go create mode 100644 cipher_suite_go114_test.go diff --git a/cipher_suite.go b/cipher_suite.go index d2a4442fb..bf314876b 100644 --- a/cipher_suite.go +++ b/cipher_suite.go @@ -28,6 +28,10 @@ const ( TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuiteID = 0x00a8 ) +var ( + _ = allCipherSuites() // Necessary until this function isn't only used by Go 1.14 +) + func (c CipherSuiteID) String() string { switch c { case TLS_ECDHE_ECDSA_WITH_AES_128_CCM: @@ -120,6 +124,20 @@ func defaultCipherSuites() []cipherSuite { } } +func allCipherSuites() []cipherSuite { + return []cipherSuite{ + newCipherSuiteTLSEcdheEcdsaWithAes128Ccm(), + newCipherSuiteTLSEcdheEcdsaWithAes128Ccm8(), + &cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{}, + &cipherSuiteTLSEcdheRsaWithAes128GcmSha256{}, + &cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{}, + &cipherSuiteTLSEcdheRsaWithAes256CbcSha{}, + newCipherSuiteTLSPskWithAes128Ccm(), + newCipherSuiteTLSPskWithAes128Ccm8(), + &cipherSuiteTLSPskWithAes128GcmSha256{}, + } +} + func decodeCipherSuites(buf []byte) ([]cipherSuite, error) { if len(buf) < 2 { return nil, errDTLSPacketInvalidLength diff --git a/cipher_suite_go114.go b/cipher_suite_go114.go new file mode 100644 index 000000000..54824db01 --- /dev/null +++ b/cipher_suite_go114.go @@ -0,0 +1,36 @@ +// +build go1.14 + +package dtls + +import ( + "crypto/tls" +) + +// Convert from our cipherSuite interface to a tls.CipherSuite struct +func toTLSCipherSuite(c cipherSuite) *tls.CipherSuite { + return &tls.CipherSuite{ + ID: uint16(c.ID()), + Name: c.String(), + SupportedVersions: []uint16{VersionDTLS12}, + Insecure: false, + } +} + +// CipherSuites returns a list of cipher suites currently implemented by this +// package, excluding those with security issues, which are returned by +// InsecureCipherSuites. +func CipherSuites() []*tls.CipherSuite { + suites := allCipherSuites() + res := make([]*tls.CipherSuite, len(suites)) + for i, c := range suites { + res[i] = toTLSCipherSuite(c) + } + return res +} + +// InsecureCipherSuites returns a list of cipher suites currently implemented by +// this package and which have security issues. +func InsecureCipherSuites() []*tls.CipherSuite { + var res []*tls.CipherSuite + return res +} diff --git a/cipher_suite_go114_test.go b/cipher_suite_go114_test.go new file mode 100644 index 000000000..57c64d48a --- /dev/null +++ b/cipher_suite_go114_test.go @@ -0,0 +1,51 @@ +// +build go1.14 + +package dtls + +import ( + "testing" +) + +func TestInsecureCipherSuites(t *testing.T) { + r := InsecureCipherSuites() + + if len(r) != 0 { + t.Fatalf("Expected no insecure ciphersuites, got %d", len(r)) + } +} + +func TestCipherSuites(t *testing.T) { + ours := allCipherSuites() + theirs := CipherSuites() + + if len(ours) != len(theirs) { + t.Fatalf("Expected %d CipherSuites, got %d", len(ours), len(theirs)) + } + + for i, s := range ours { + i := i + s := s + t.Run(s.String(), func(t *testing.T) { + c := theirs[i] + if c.ID != uint16(s.ID()) { + t.Fatalf("Expected ID: 0x%04X, got 0x%04X", s.ID(), c.ID) + } + + if c.Name != s.String() { + t.Fatalf("Expected Name: %s, got %s", s.String(), c.Name) + } + + if len(c.SupportedVersions) != 1 { + t.Fatalf("Expected %d SupportedVersion, got %d", 1, len(c.SupportedVersions)) + } + + if c.SupportedVersions[0] != VersionDTLS12 { + t.Fatalf("Expected SupportedVersions 0x%04X, got 0x%04X", VersionDTLS12, c.SupportedVersions[0]) + } + + if c.Insecure { + t.Fatalf("Expected Insecure %t, got %t", false, c.Insecure) + } + }) + } +} diff --git a/cipher_suite_test.go b/cipher_suite_test.go index 587fec501..ade677211 100644 --- a/cipher_suite_test.go +++ b/cipher_suite_test.go @@ -38,3 +38,10 @@ func TestCipherSuiteName(t *testing.T) { } } } + +func TestAllCipherSuites(t *testing.T) { + actual := len(allCipherSuites()) + if actual == 0 { + t.Fatal() + } +} diff --git a/record_layer_header.go b/record_layer_header.go index 07e4b3c84..954cd4a7a 100644 --- a/record_layer_header.go +++ b/record_layer_header.go @@ -17,6 +17,10 @@ const ( dtls1_2Major = 0xfe dtls1_2Minor = 0xfd + + // VersionDTLS12 is the DTLS version in the same style as + // VersionTLSXX from crypto/tls + VersionDTLS12 = 0xfefd ) var protocolVersion1_2 = protocolVersion{dtls1_2Major, dtls1_2Minor}