package password import "testing" func TestPrototypeKDFVerifiesWithoutPlaintext(t *testing.T) { record, err := PrototypeSHA256{}.Hash("mock-admin-secret", "tera-prototype-admin") if err != nil { t.Fatalf("hash password: %v", err) } if record.Hash == "" || record.Hash == "mock-admin-secret" { t.Fatalf("hash = %q, want derived value", record.Hash) } verified, err := PrototypeSHA256{}.Verify(record, "mock-admin-secret") if err != nil { t.Fatalf("verify password: %v", err) } if !verified { t.Fatalf("verified = false, want true") } } func TestArgon2idKDFVerifiesWithoutPlaintext(t *testing.T) { kdf := NewArgon2id(Params{ MemoryKiB: 1024, Iterations: 1, Parallelism: 1, KeyLength: 32, }) record, err := kdf.Hash("mock-admin-secret", "test-salt") if err != nil { t.Fatalf("hash password: %v", err) } if record.Algorithm != AlgorithmArgon2id { t.Fatalf("algorithm = %q, want argon2id", record.Algorithm) } if record.Hash == "" || record.Hash == "mock-admin-secret" { t.Fatalf("hash = %q, want derived value", record.Hash) } verified, err := kdf.Verify(record, "mock-admin-secret") if err != nil { t.Fatalf("verify password: %v", err) } if !verified { t.Fatalf("verified = false, want true") } verified, err = kdf.Verify(record, "wrong") if err != nil { t.Fatalf("verify wrong password: %v", err) } if verified { t.Fatalf("verified = true, want false for wrong password") } } func TestPBKDF2SHA256KDFVerifiesWithoutPlaintext(t *testing.T) { kdf := NewPBKDF2SHA256(Params{ Iterations: 2, KeyLength: 32, }) record, err := kdf.Hash("mock-admin-secret", "test-salt") if err != nil { t.Fatalf("hash password: %v", err) } if record.Algorithm != AlgorithmPBKDF2SHA256 { t.Fatalf("algorithm = %q, want pbkdf2-hmac-sha256", record.Algorithm) } if record.Hash == "" || record.Hash == "mock-admin-secret" { t.Fatalf("hash = %q, want derived value", record.Hash) } if record.Params.Iterations != 2 || record.Params.KeyLength != 32 { t.Fatalf("params = %#v, want explicit iterations/key length", record.Params) } verified, err := kdf.Verify(record, "mock-admin-secret") if err != nil { t.Fatalf("verify password: %v", err) } if !verified { t.Fatalf("verified = false, want true") } verified, err = kdf.Verify(record, "wrong") if err != nil { t.Fatalf("verify wrong password: %v", err) } if verified { t.Fatalf("verified = true, want false for wrong password") } } func TestRegistryCanAddFIPSKDFWithoutChangingArgon2idDefault(t *testing.T) { production := NewProductionRegistry() if algorithms := production.Algorithms(); len(algorithms) != 2 || algorithms[0] != AlgorithmArgon2id || algorithms[1] != AlgorithmPrototypeSHA256 { t.Fatalf("production algorithms = %#v, want argon2id and prototype fallback", algorithms) } registry := NewRegistry(NewArgon2id(Params{MemoryKiB: 1024, Iterations: 1, Parallelism: 1, KeyLength: 32}), NewPBKDF2SHA256(Params{Iterations: 2, KeyLength: 32})) record, err := NewPBKDF2SHA256(Params{Iterations: 2, KeyLength: 32}).Hash("mock-admin-secret", "test-salt") if err != nil { t.Fatalf("hash pbkdf2 password: %v", err) } verified, err := registry.Verify(record, "mock-admin-secret") if err != nil { t.Fatalf("verify pbkdf2 password via registry: %v", err) } if !verified { t.Fatalf("verified = false, want true") } } func TestKDFPolicyRecordsSupportArgon2idAndFIPSFallback(t *testing.T) { argon2id := Argon2idPolicyRecord() if argon2id.Algorithm != AlgorithmArgon2id || argon2id.Version != 1 { t.Fatalf("argon2id policy = %#v, want algorithm/version", argon2id) } if argon2id.Params.MemoryKiB == 0 || argon2id.Params.Iterations == 0 || argon2id.Params.KeyLength == 0 { t.Fatalf("argon2id params = %#v, want memory/iterations/key length", argon2id.Params) } pbkdf2 := PBKDF2SHA256PolicyRecord() if pbkdf2.Algorithm != AlgorithmPBKDF2SHA256 || pbkdf2.Version != 1 { t.Fatalf("pbkdf2 policy = %#v, want algorithm/version", pbkdf2) } if pbkdf2.Params.Iterations == 0 || pbkdf2.Params.KeyLength == 0 { t.Fatalf("pbkdf2 params = %#v, want iterations/key length", pbkdf2.Params) } }