package vault import ( "bytes" "errors" "strings" "testing" ) const master = "0123456789abcdef0123456789abcdef" func must(t *testing.T, m, iss, sub string) *Cipher { t.Helper() c, err := New(m, iss, sub) if err != nil { t.Fatal(err) } return c } func TestRoundTrip(t *testing.T) { c := must(t, master, "https://a/", "alice") plain := []byte("---\ntitle: \"Secret\"\n---\n\ndear diary") sealed := c.Seal(plain, "page-1") if !IsSealed(sealed) || bytes.Contains(sealed, []byte("diary")) || bytes.Contains(sealed, []byte("Secret")) { t.Fatalf("not encrypted: %q", sealed) } got, err := c.Open(sealed, "page-1") if err != nil || !bytes.Equal(got, plain) { t.Fatalf("open: %q %v", got, err) } if bytes.Equal(sealed, c.Seal(plain, "page-1")) { t.Fatal("two seals of the same text must differ") } } func TestWrongKeyNameOrDamage(t *testing.T) { c := must(t, master, "https://a/", "alice") sealed := c.Seal([]byte("hello"), "p1") cases := map[string]*Cipher{ "another person": must(t, master, "https://a/", "bob"), "another issuer": must(t, master, "https://b/", "alice"), "another master key": must(t, strings.Repeat("z", 40), "https://a/", "alice"), } for name, other := range cases { if _, err := other.Open(sealed, "p1"); !errors.Is(err, ErrWrongKey) { t.Errorf("%s: want ErrWrongKey, got %v", name, err) } } if _, err := c.Open(sealed, "p2"); !errors.Is(err, ErrWrongKey) { t.Errorf("a file moved to another page name opened: %v", err) } bad := append([]byte{}, sealed...) bad[len(bad)-1] ^= 1 if _, err := c.Open(bad, "p1"); !errors.Is(err, ErrWrongKey) { t.Errorf("a damaged file opened: %v", err) } if _, err := c.Open([]byte("plain text"), "p1"); !errors.Is(err, ErrWrongKey) { t.Errorf("plain text opened: %v", err) } } func TestNewChecks(t *testing.T) { if _, err := New("short", "i", "s"); err == nil { t.Error("a short key was accepted") } if _, err := New(master, "i", ""); err == nil { t.Error("an empty user was accepted") } }