package s3api import ( "testing" ) // TestSetKEKPassphraseEnablesEncryptedRoundTrip exercises the wrap/unwrap // round-trip after SetKEKPassphrase configures the manager. This is the // primary behaviour the new env-var wiring relies on: once the passphrase // is in place, wrapKEK produces v2-format ciphertext that unwrapKEK can // reverse. Without the SetKEKPassphrase plumbing, deriveWrappingKey would // fail with "no KEK passphrase configured". func TestSetKEKPassphraseEnablesEncryptedRoundTrip(t *testing.T) { km := NewSSES3KeyManager() km.SetKEKPassphrase("test-passphrase-32-bytes-or-anything") original := make([]byte, SSES3KeySize) for i := range original { original[i] = byte(i) } wrapped, err := km.wrapKEK(original) if err != nil { t.Fatalf("wrapKEK: %v", err) } got, isV2, err := km.unwrapKEK(wrapped) if err != nil { t.Fatalf("unwrapKEK: %v", err) } if !isV2 { t.Fatal("wrapped output should be reported as v2 by unwrapKEK") } if string(got) != string(original) { t.Fatalf("round-trip mismatch: got %x want %x", got, original) } } // TestSetKEKPassphraseDifferentInstancesNoCollision proves random salts // per-installation actually decorrelate two managers using the same // passphrase: their wrapped payloads must differ even when the input KEK // matches. func TestSetKEKPassphraseDifferentInstancesNoCollision(t *testing.T) { a := NewSSES3KeyManager() a.SetKEKPassphrase("shared-passphrase") b := NewSSES3KeyManager() b.SetKEKPassphrase("shared-passphrase") kek := make([]byte, SSES3KeySize) for i := range kek { kek[i] = 0xAB } wa, err := a.wrapKEK(kek) if err != nil { t.Fatalf("wrapKEK a: %v", err) } wb, err := b.wrapKEK(kek) if err != nil { t.Fatalf("wrapKEK b: %v", err) } if string(wa) == string(wb) { t.Fatal("two managers with the same passphrase produced byte-identical wrapped output; salt is not random") } // Both must still self-roundtrip. if got, _, _ := a.unwrapKEK(wa); string(got) != string(kek) { t.Fatal("manager a failed self roundtrip") } if got, _, _ := b.unwrapKEK(wb); string(got) != string(kek) { t.Fatal("manager b failed self roundtrip") } } // TestNoPassphraseKeepsLegacyHexDecodePath confirms that a manager left // without a passphrase still drives the historical plaintext-hex path // (loadSuperKeyFromFiler logs a warning and reads hex). That's the // fallback InitializeGlobalSSES3KeyManager keeps for upgrades. func TestNoPassphraseKeepsLegacyHexDecodePath(t *testing.T) { km := NewSSES3KeyManager() if km.kekPassphrase != "" { t.Fatalf("default passphrase should be empty, got %q", km.kekPassphrase) } // wrapKEK requires a passphrase; without one it must surface the error // rather than producing unencrypted output. if _, err := km.wrapKEK(make([]byte, SSES3KeySize)); err == nil { t.Fatal("wrapKEK without passphrase should fail; got nil error") } }