mirror of
https://github.com/caddyserver/caddy.git
synced 2026-06-08 07:44:30 -04:00
238 lines
5.1 KiB
Go
238 lines
5.1 KiB
Go
package caddytls
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"testing"
|
|
)
|
|
|
|
func TestCipherSuiteNameSupported(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
supported bool
|
|
}{
|
|
{
|
|
name: "valid TLS 1.2 cipher",
|
|
input: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
supported: true,
|
|
},
|
|
{
|
|
name: "valid TLS 1.2 cipher RSA",
|
|
input: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
supported: true,
|
|
},
|
|
{
|
|
name: "valid ChaCha20 cipher",
|
|
input: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
supported: true,
|
|
},
|
|
{
|
|
name: "unknown cipher name",
|
|
input: "TLS_UNKNOWN_CIPHER",
|
|
supported: false,
|
|
},
|
|
{
|
|
name: "empty string",
|
|
input: "",
|
|
supported: false,
|
|
},
|
|
{
|
|
name: "partial name",
|
|
input: "TLS_ECDHE",
|
|
supported: false,
|
|
},
|
|
{
|
|
name: "case sensitive mismatch",
|
|
input: "tls_ecdhe_ecdsa_with_aes_256_gcm_sha384",
|
|
supported: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := CipherSuiteNameSupported(tt.input)
|
|
if got != tt.supported {
|
|
t.Errorf("CipherSuiteNameSupported(%q) = %v, want %v", tt.input, got, tt.supported)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCipherSuiteID(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantID uint16
|
|
}{
|
|
{
|
|
name: "known cipher returns correct ID",
|
|
input: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
wantID: tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
},
|
|
{
|
|
name: "another known cipher",
|
|
input: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
wantID: tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
},
|
|
{
|
|
name: "unknown cipher returns 0",
|
|
input: "DOES_NOT_EXIST",
|
|
wantID: 0,
|
|
},
|
|
{
|
|
name: "empty string returns 0",
|
|
input: "",
|
|
wantID: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := CipherSuiteID(tt.input)
|
|
if got != tt.wantID {
|
|
t.Errorf("CipherSuiteID(%q) = 0x%04x, want 0x%04x", tt.input, got, tt.wantID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSupportedCipherSuites(t *testing.T) {
|
|
suites := SupportedCipherSuites()
|
|
if len(suites) == 0 {
|
|
t.Fatal("SupportedCipherSuites() returned empty list")
|
|
}
|
|
|
|
// Every suite should have a non-empty name and non-zero ID
|
|
for _, cs := range suites {
|
|
if cs.Name == "" {
|
|
t.Errorf("cipher suite with ID 0x%04x has empty name", cs.ID)
|
|
}
|
|
if cs.ID == 0 {
|
|
t.Errorf("cipher suite %q has zero ID", cs.Name)
|
|
}
|
|
}
|
|
|
|
// Verify that CipherSuiteID can find each suite by name (round-trip)
|
|
for _, cs := range suites {
|
|
id := CipherSuiteID(cs.Name)
|
|
if id != cs.ID {
|
|
t.Errorf("CipherSuiteID(%q) = 0x%04x, want 0x%04x", cs.Name, id, cs.ID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestProtocolName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
id uint16
|
|
want string
|
|
}{
|
|
{
|
|
name: "TLS 1.2",
|
|
id: tls.VersionTLS12,
|
|
want: "tls1.2",
|
|
},
|
|
{
|
|
name: "TLS 1.3",
|
|
id: tls.VersionTLS13,
|
|
want: "tls1.3",
|
|
},
|
|
{
|
|
name: "unsupported SSL 3.0",
|
|
id: tls.VersionSSL30, //nolint:staticcheck
|
|
want: "ssl3.0",
|
|
},
|
|
{
|
|
name: "unsupported TLS 1.0",
|
|
id: tls.VersionTLS10,
|
|
want: "tls1.0",
|
|
},
|
|
{
|
|
name: "unsupported TLS 1.1",
|
|
id: tls.VersionTLS11,
|
|
want: "tls1.1",
|
|
},
|
|
{
|
|
name: "unknown protocol falls back to hex",
|
|
id: 0x9999,
|
|
want: "0x9999",
|
|
},
|
|
{
|
|
name: "zero protocol falls back to hex",
|
|
id: 0,
|
|
want: "0x0000",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ProtocolName(tt.id)
|
|
if got != tt.want {
|
|
t.Errorf("ProtocolName(0x%04x) = %q, want %q", tt.id, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSupportedProtocolsMap(t *testing.T) {
|
|
// SupportedProtocols should contain at least TLS 1.2 and 1.3
|
|
expectedProtocols := map[string]uint16{
|
|
"tls1.2": tls.VersionTLS12,
|
|
"tls1.3": tls.VersionTLS13,
|
|
}
|
|
|
|
for name, wantID := range expectedProtocols {
|
|
gotID, ok := SupportedProtocols[name]
|
|
if !ok {
|
|
t.Errorf("SupportedProtocols missing %q", name)
|
|
continue
|
|
}
|
|
if gotID != wantID {
|
|
t.Errorf("SupportedProtocols[%q] = 0x%04x, want 0x%04x", name, gotID, wantID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSupportedCurvesMap(t *testing.T) {
|
|
// SupportedCurves should contain key exchanges
|
|
expectedCurves := []string{"x25519", "secp256r1", "secp384r1", "secp521r1"}
|
|
for _, name := range expectedCurves {
|
|
if _, ok := SupportedCurves[name]; !ok {
|
|
t.Errorf("SupportedCurves missing %q", name)
|
|
}
|
|
}
|
|
|
|
// All values should be non-zero
|
|
for name, id := range SupportedCurves {
|
|
if id == 0 {
|
|
t.Errorf("SupportedCurves[%q] has zero value", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetOptimalDefaultCipherSuites(t *testing.T) {
|
|
suites := getOptimalDefaultCipherSuites()
|
|
if len(suites) == 0 {
|
|
t.Fatal("getOptimalDefaultCipherSuites() returned empty list")
|
|
}
|
|
|
|
// All returned IDs should be non-zero
|
|
for i, id := range suites {
|
|
if id == 0 {
|
|
t.Errorf("getOptimalDefaultCipherSuites()[%d] is zero", i)
|
|
}
|
|
}
|
|
|
|
// All returned IDs should be recognized cipher suites
|
|
knownSuites := SupportedCipherSuites()
|
|
knownIDs := make(map[uint16]bool)
|
|
for _, cs := range knownSuites {
|
|
knownIDs[cs.ID] = true
|
|
}
|
|
for _, id := range suites {
|
|
if !knownIDs[id] {
|
|
t.Errorf("getOptimalDefaultCipherSuites() contains unrecognized ID 0x%04x", id)
|
|
}
|
|
}
|
|
}
|