You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/authorkey/authorkey_test.go

139 lines
4.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package authorkey_test
import (
"bytes"
"fmt"
"strings"
"testing"
"g.activething.com/go/DateKeys/authorkey"
"g.activething.com/go/DateKeys/codec/bech32"
"g.activething.com/go/DateKeys/internal/ed25519strict"
)
func TestStrings(t *testing.T) {
seed := bytes.Repeat([]byte{7}, 32)
k, err := authorkey.NewFromSeed(seed)
if err != nil {
t.Fatal(err)
}
pub, err := authorkey.PublicString(k.Public())
if err != nil {
t.Fatal(err)
}
secret := k.Secret()
if len(pub) != authorkey.PublicLength || !strings.HasPrefix(pub, "dkauthor1") {
t.Errorf("public %q", pub)
}
if len(secret) != authorkey.SecretLength || !strings.HasPrefix(secret, "DKAUTHOR-SECRET-KEY-1") {
t.Errorf("secret %q", secret)
}
back, err := authorkey.ParseSecret(secret)
if err != nil || !bytes.Equal(back.Public(), k.Public()) {
t.Fatalf("ParseSecret: %v", err)
}
a, err := authorkey.ParsePublic(pub)
if err != nil || !bytes.Equal(a, k.Public()) {
t.Fatalf("ParsePublic: %v", err)
}
msg := []byte("datekeys:dkc3:author-signature:v1")
if !ed25519strict.Verify(a, msg, k.Sign(msg)) {
t.Error("the signature does not verify")
}
// Printing a key, or an options struct that holds one, never shows the
// secret.
for _, s := range []string{fmt.Sprint(k), fmt.Sprintf("%v %+v %#v %s", k, k, k, k), fmt.Sprintf("%+v", struct{ K *authorkey.Key }{k})} {
if strings.Contains(s, secret[len("DKAUTHOR-SECRET-KEY-1"):]) {
t.Fatalf("the secret key is printed: %s", s)
}
}
k.Clear()
if !bytes.Equal(k.Public(), make([]byte, 32)) {
t.Error("Clear leaves the key")
}
}
func TestParseRejects(t *testing.T) {
k, _ := authorkey.Generate()
pub, _ := authorkey.PublicString(k.Public())
secret := k.Secret()
short, _ := bech32.Encode("dkauthor", make([]byte, 31))
other, _ := bech32.Encode("dkauthoz", k.Public())
last := "q"
if pub[66] == 'q' {
last = "p"
}
identity := make([]byte, 32)
identity[0] = 1
small, _ := authorkey.PublicString(identity)
// y = 2 is canonical, and (y² − 1)/(d·y² + 1) is not a square: no point.
two := make([]byte, 32)
two[0] = 2
offCurve, _ := authorkey.PublicString(two)
for _, c := range []struct{ s, want string }{
{strings.ToUpper(pub), "lower case"},
{pub[:66] + last, "checksum"},
{short, "characters"},
{other, "is not a public key"},
{small, "small order"},
{offCurve, "not a point of the curve"},
} {
if _, err := authorkey.ParsePublic(c.s); err == nil || !strings.Contains(err.Error(), c.want) {
t.Errorf("ParsePublic(%q) = %v, want %q", c.s, err, c.want)
}
}
for _, c := range []struct{ s, want string }{
{strings.ToLower(secret), "upper case"},
{secret[:78], "characters"},
{"DKAUTHOR-SECRET-KEY-1" + strings.Repeat("Q", 58), "checksum"},
} {
if _, err := authorkey.ParseSecret(c.s); err == nil || !strings.Contains(err.Error(), c.want) {
t.Errorf("ParseSecret(%q) = %v, want %q", c.s, err, c.want)
}
}
if _, err := authorkey.PublicString(make([]byte, 31)); err == nil {
t.Error("PublicString takes 31 bytes")
}
if _, err := authorkey.NewFromSeed(make([]byte, 31)); err == nil {
t.Error("NewFromSeed takes 31 bytes")
}
}
func TestFiles(t *testing.T) {
k, _ := authorkey.Generate()
var enc bytes.Buffer
if err := authorkey.Encrypt(&enc, k, "contraseña larga"); err != nil {
t.Fatal(err)
}
if !bytes.HasPrefix(enc.Bytes(), []byte("age-encryption.org/v1\n-> scrypt ")) || !bytes.Contains(enc.Bytes(), []byte(" 16\n")) {
t.Errorf("not age scrypt with a work factor of 16: %q", enc.Bytes()[:60])
}
got, err := authorkey.Read(bytes.NewReader(enc.Bytes()), "contraseña larga")
if err != nil || !bytes.Equal(got.Public(), k.Public()) {
t.Fatalf("Read: %v", err)
}
if _, err := authorkey.Read(bytes.NewReader(enc.Bytes()), "otra"); err == nil {
t.Error("another passphrase opens the file")
}
if _, err := authorkey.Read(bytes.NewReader(enc.Bytes()), ""); err == nil || !strings.Contains(err.Error(), "needs its passphrase") {
t.Errorf("no passphrase: %v", err)
}
if err := authorkey.Encrypt(&enc, k, ""); err == nil {
t.Error("Encrypt takes an empty passphrase")
}
plain := authorkey.Marshal(k)
if got, err := authorkey.Read(bytes.NewReader(plain), ""); err != nil || !bytes.Equal(got.Public(), k.Public()) {
t.Fatalf("Read of a plain file: %v", err)
}
for _, c := range []struct{ file, want string }{
{"# nothing\n\n", "no secret key"},
{string(plain) + k.String() + "\n", "one secret key"},
{"age1notakey\n", "characters"},
{strings.Repeat("#", 64<<10+1), "more than"},
} {
if _, err := authorkey.Read(strings.NewReader(c.file), ""); err == nil || !strings.Contains(err.Error(), c.want) {
t.Errorf("Read(%.20q) = %v, want %q", c.file, err, c.want)
}
}
}

Powered by TurnKey Linux.