102 lines
3.5 KiB
Go
102 lines
3.5 KiB
Go
package tlsutil
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"testing"
|
|
|
|
"codeberg.org/VARASYS/ZDDC/zddc/internal/config"
|
|
)
|
|
|
|
// TestTLSConfig_NoneMode: TLSMode=="none" returns no config and useTLS=false.
|
|
func TestTLSConfig_NoneMode(t *testing.T) {
|
|
tlsCfg, useTLS, err := TLSConfig(config.Config{TLSMode: "none"})
|
|
if err != nil {
|
|
t.Fatalf("TLSConfig(none): %v", err)
|
|
}
|
|
if useTLS {
|
|
t.Errorf("useTLS = true, want false for TLSMode=none")
|
|
}
|
|
if tlsCfg != nil {
|
|
t.Errorf("tlsCfg = %+v, want nil for TLSMode=none", tlsCfg)
|
|
}
|
|
}
|
|
|
|
// TestTLSConfig_SelfSignedHardenedDefaults: the self-signed path returns a
|
|
// config that conforms to NIST SP 800-52 Rev. 2 — TLS 1.2 minimum, the
|
|
// AEAD-only cipher allowlist, and the X25519/P-256/P-384 curve list.
|
|
func TestTLSConfig_SelfSignedHardenedDefaults(t *testing.T) {
|
|
tlsCfg, useTLS, err := TLSConfig(config.Config{TLSMode: "selfsigned"})
|
|
if err != nil {
|
|
t.Fatalf("TLSConfig(selfsigned): %v", err)
|
|
}
|
|
if !useTLS {
|
|
t.Fatal("useTLS = false, want true")
|
|
}
|
|
if tlsCfg == nil {
|
|
t.Fatal("tlsCfg = nil")
|
|
}
|
|
|
|
if tlsCfg.MinVersion != tls.VersionTLS12 {
|
|
t.Errorf("MinVersion = %#x, want TLS 1.2 (%#x)", tlsCfg.MinVersion, tls.VersionTLS12)
|
|
}
|
|
|
|
wantCiphers := map[uint16]bool{
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true,
|
|
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true,
|
|
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
|
|
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true,
|
|
}
|
|
if len(tlsCfg.CipherSuites) != len(wantCiphers) {
|
|
t.Errorf("CipherSuites count = %d, want %d", len(tlsCfg.CipherSuites), len(wantCiphers))
|
|
}
|
|
for _, c := range tlsCfg.CipherSuites {
|
|
if !wantCiphers[c] {
|
|
t.Errorf("CipherSuites contains unexpected suite %#x; allowlist is the NIST SP 800-52 Rev. 2 set", c)
|
|
}
|
|
}
|
|
|
|
wantCurves := map[tls.CurveID]bool{
|
|
tls.X25519: true,
|
|
tls.CurveP256: true,
|
|
tls.CurveP384: true,
|
|
}
|
|
if len(tlsCfg.CurvePreferences) != len(wantCurves) {
|
|
t.Errorf("CurvePreferences count = %d, want %d", len(tlsCfg.CurvePreferences), len(wantCurves))
|
|
}
|
|
for _, c := range tlsCfg.CurvePreferences {
|
|
if !wantCurves[c] {
|
|
t.Errorf("CurvePreferences contains unexpected curve %v", c)
|
|
}
|
|
}
|
|
|
|
if len(tlsCfg.Certificates) != 1 {
|
|
t.Errorf("Certificates count = %d, want 1", len(tlsCfg.Certificates))
|
|
}
|
|
}
|
|
|
|
// TestTLSConfig_NoWeakCiphers: the allowlist must not include any of the
|
|
// federally-deprecated suites — CBC-mode, RC4, 3DES, SHA-1, NULL, EXPORT.
|
|
// This is a guardrail against accidental regressions if the list is edited.
|
|
func TestTLSConfig_NoWeakCiphers(t *testing.T) {
|
|
tlsCfg, _, err := TLSConfig(config.Config{TLSMode: "selfsigned"})
|
|
if err != nil {
|
|
t.Fatalf("TLSConfig: %v", err)
|
|
}
|
|
weak := map[uint16]string{
|
|
tls.TLS_RSA_WITH_AES_128_CBC_SHA: "AES-128-CBC-SHA (CBC mode)",
|
|
tls.TLS_RSA_WITH_AES_256_CBC_SHA: "AES-256-CBC-SHA (CBC mode)",
|
|
tls.TLS_RSA_WITH_AES_128_GCM_SHA256: "RSA-AES-128-GCM (no forward secrecy)",
|
|
tls.TLS_RSA_WITH_AES_256_GCM_SHA384: "RSA-AES-256-GCM (no forward secrecy)",
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: "ECDHE-RSA-AES-128-CBC-SHA (CBC mode)",
|
|
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "ECDHE-RSA-AES-256-CBC-SHA (CBC mode)",
|
|
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: "3DES",
|
|
tls.TLS_RSA_WITH_RC4_128_SHA: "RC4",
|
|
}
|
|
for _, c := range tlsCfg.CipherSuites {
|
|
if name, bad := weak[c]; bad {
|
|
t.Errorf("CipherSuites includes federally-deprecated suite: %s (%#x)", name, c)
|
|
}
|
|
}
|
|
}
|