thread-master/apps/backend/internal/lib/secretbox/secretbox_test.go

90 lines
2.5 KiB
Go

package secretbox
import (
"encoding/base64"
"errors"
"strings"
"testing"
)
func testCodec(t *testing.T) *Codec {
t.Helper()
c, err := New("test-key", base64.StdEncoding.EncodeToString(make([]byte, 32)))
if err != nil {
t.Fatal(err)
}
return c
}
func TestCodecRoundTripUsesRandomNonce(t *testing.T) {
c := testCodec(t)
one, err := c.Encrypt(42, "api_key", "xai", "top-secret")
if err != nil {
t.Fatal(err)
}
two, err := c.Encrypt(42, "api_key", "xai", "top-secret")
if err != nil {
t.Fatal(err)
}
if one == two {
t.Fatal("ciphertexts must differ")
}
if !strings.HasPrefix(one, "enc:v1:test-key:") {
t.Fatalf("unexpected prefix: %q", one)
}
got, err := c.Decrypt(42, "api_key", "xai", one)
if err != nil || got != "top-secret" {
t.Fatalf("round trip = %q, %v", got, err)
}
}
func TestCodecAADAndTamperingFail(t *testing.T) {
c := testCodec(t)
value, err := c.Encrypt(42, "api_key", "xai", "top-secret")
if err != nil {
t.Fatal(err)
}
parts := strings.Split(value, ":")
payload, err := base64.RawURLEncoding.DecodeString(parts[3])
if err != nil {
t.Fatal(err)
}
payload[len(payload)-1] ^= 0x01
tampered := strings.Join([]string{parts[0], parts[1], parts[2], base64.RawURLEncoding.EncodeToString(payload)}, ":")
for _, tc := range []struct {
name string
uid int64
field string
provider string
value string
}{
{name: "uid", uid: 43, field: "api_key", provider: "xai", value: value},
{name: "field", uid: 42, field: "exa_api_key", provider: "xai", value: value},
{name: "provider", uid: 42, field: "api_key", provider: "other", value: value},
{name: "tamper", uid: 42, field: "api_key", provider: "xai", value: tampered},
} {
t.Run(tc.name, func(t *testing.T) {
if _, err := c.Decrypt(tc.uid, tc.field, tc.provider, tc.value); !errors.Is(err, ErrInvalidCiphertext) {
t.Fatalf("error = %v", err)
}
})
}
}
func TestCodecCompatibilityAndValidation(t *testing.T) {
c := testCodec(t)
got, err := c.Decrypt(1, "api_key", "xai", "legacy-plaintext")
if err != nil || got != "legacy-plaintext" {
t.Fatalf("legacy = %q, %v", got, err)
}
if _, err := c.Decrypt(1, "api_key", "xai", "enc:v2:key:data"); !errors.Is(err, ErrUnsupportedVersion) {
t.Fatalf("version error = %v", err)
}
if _, err := c.Decrypt(1, "api_key", "xai", "enc:v1:other:data"); !errors.Is(err, ErrInvalidCiphertext) {
t.Fatalf("key ID error = %v", err)
}
if _, err := New("key", base64.StdEncoding.EncodeToString(make([]byte, 31))); !errors.Is(err, ErrInvalidConfig) {
t.Fatalf("key size error = %v", err)
}
}