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) } } }