81 lines
2.5 KiB
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")
|
|
}
|
|
}
|