Files
orbit/internal/credentialvault/vault_test.go

81 lines
2.5 KiB
Go

package credentialvault
import (
"bytes"
"encoding/base64"
"fmt"
"strings"
"testing"
core "git.yuntuo.hk/k2safe/orbit/model"
)
func TestCredentialEncryption(t *testing.T) {
key := base64.StdEncoding.EncodeToString(bytes.Repeat([]byte{7}, 32))
ring, err := Read(strings.NewReader(`{"active":"one","keys":{"one":"` + key + `"}}`))
if err != nil {
t.Fatal(err)
}
ns, _ := core.NewID()
id, _ := core.NewID()
other, _ := core.NewID()
k, a, err := ring.Seal(ns, id, "test-only-secret")
if err != nil {
t.Fatal(err)
}
_, b, _ := ring.Seal(ns, id, "test-only-secret")
if bytes.Equal(a, b) || bytes.Contains(a, []byte("test-only-secret")) {
t.Fatal("nonce reused or plaintext stored")
}
got, err := ring.Open(ns, id, *k, a)
if err != nil || got != "test-only-secret" {
t.Fatal("round trip failed")
}
if _, err = ring.Open(ns, other, *k, a); err == nil {
t.Fatal("different credential accepted")
}
if _, err = ring.Open(other, id, *k, a); err == nil {
t.Fatal("different namespace accepted")
}
if _, err = ring.Open(ns, id, "unknown", a); err == nil {
t.Fatal("unknown key accepted")
}
a[len(a)-1] ^= 1
if _, err = ring.Open(ns, id, *k, a); err == nil {
t.Fatal("tampered ciphertext accepted")
}
for _, v := range []string{fmt.Sprint(ring), fmt.Sprintf("%#v", ring)} {
if strings.Contains(v, key) || !strings.Contains(v, "REDACTED") {
t.Fatal("keyring formatting not redacted")
}
}
old, _ := Read(strings.NewReader(`{"active":"one","keys":{"one":"` + key + `"}}`))
k, c, _ := old.Seal(ns, id, "old-secret")
newKey := base64.StdEncoding.EncodeToString(bytes.Repeat([]byte{8}, 32))
rotated, err := Read(strings.NewReader(`{"active":"two","keys":{"one":"` + key + `","two":"` + newKey + `"}}`))
if err != nil {
t.Fatal(err)
}
if v, err := rotated.Open(ns, id, *k, c); err != nil || v != "old-secret" {
t.Fatal("retained key cannot read old data")
}
if k, _, _ := rotated.Seal(ns, id, "new-secret"); *k != "two" {
t.Fatal("active key ignored")
}
}
func TestCredentialKeyValidation(t *testing.T) {
for _, raw := range []string{`{}`, `{"active":"x","keys":{"x":"bad"}}`, `{"active":"missing","keys":{"x":"` + base64.StdEncoding.EncodeToString(make([]byte, 32)) + `"}}`, strings.Repeat(" ", 65537)} {
if _, err := Read(strings.NewReader(raw)); err == nil {
t.Fatal("invalid key configuration accepted")
}
}
k, err := LoadFile("")
if err != nil || k != nil {
t.Fatal("empty path must disable vault")
}
if id, c, err := k.Seal("", "", ""); err != nil || id != nil || c != nil {
t.Fatal("disabled vault must use SQL NULL pair")
}
}