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.
99 lines
3.3 KiB
99 lines
3.3 KiB
|
6 days ago
|
package capsule_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"context"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"g.activething.com/go/DateKeys/authorkey"
|
||
|
|
"g.activething.com/go/DateKeys/capsule"
|
||
|
|
"g.activething.com/go/DateKeys/internal/testkit"
|
||
|
|
)
|
||
|
|
|
||
|
|
// openSigned opens dkc with the author keys that the person saved.
|
||
|
|
func openSigned(t *testing.T, dkc []byte, saved map[string]string) *capsule.Opened {
|
||
|
|
t.Helper()
|
||
|
|
o := defaultOpen(1000)
|
||
|
|
o.Sink, o.AuthorKeys = &testkit.MemorySink{}, saved
|
||
|
|
opened, err := capsule.Open(context.Background(), nil, bytes.NewReader(dkc), o)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
return opened
|
||
|
|
}
|
||
|
|
|
||
|
|
// Spec v0.11 §29.7, §29.8, §62.1 rule 19: EncryptFiles signs with the key of
|
||
|
|
// opts.AuthorKey and Open gives F4, or F3 with the key saved.
|
||
|
|
func TestEncryptFilesSigned(t *testing.T) {
|
||
|
|
key, err := authorkey.Generate()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
pub, _ := authorkey.PublicString(key.Public())
|
||
|
|
opts := files3(t)
|
||
|
|
opts.AuthorKey = key
|
||
|
|
var dkc bytes.Buffer
|
||
|
|
if _, err := capsule.EncryptFiles(&dkc, []capsule.Source{source("nota.txt", "Hola.\n")}, opts); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
o := openSigned(t, dkc.Bytes(), nil)
|
||
|
|
if o.Verdicts.Signature != capsule.VerdictSignedOther || o.Verdicts.AuthorKey != [32]byte(key.Public()) || o.Verdicts.Seal != capsule.VerdictNoSeal || o.AreaLen != capsule.AreaLen {
|
||
|
|
t.Errorf("verdicts %+v, area %d", o.Verdicts, o.AreaLen)
|
||
|
|
}
|
||
|
|
o = openSigned(t, dkc.Bytes(), map[string]string{pub: "Ana"})
|
||
|
|
if o.Verdicts.Signature != capsule.VerdictSignedSaved || o.Verdicts.AuthorLabel != "Ana" {
|
||
|
|
t.Errorf("saved key: verdicts %+v", o.Verdicts)
|
||
|
|
}
|
||
|
|
other, _ := authorkey.Generate()
|
||
|
|
otherPub, _ := authorkey.PublicString(other.Public())
|
||
|
|
if o = openSigned(t, dkc.Bytes(), map[string]string{otherPub: "Luis"}); o.Verdicts.Signature != capsule.VerdictSignedOther {
|
||
|
|
t.Errorf("another saved key: verdicts %+v", o.Verdicts)
|
||
|
|
}
|
||
|
|
|
||
|
|
// The area grows only when asked, and the signature still verifies.
|
||
|
|
opts.LargeArea = true
|
||
|
|
dkc.Reset()
|
||
|
|
if _, err := capsule.EncryptFiles(&dkc, []capsule.Source{source("nota.txt", "Hola.\n")}, opts); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if o = openSigned(t, dkc.Bytes(), nil); o.AreaLen != capsule.LargeAreaLen || o.Verdicts.Signature != capsule.VerdictSignedOther {
|
||
|
|
t.Errorf("large area: verdicts %+v, area %d", o.Verdicts, o.AreaLen)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// badKey is an AuthorKey that signs wrongly or has a public key of the wrong
|
||
|
|
// length.
|
||
|
|
type badKey struct {
|
||
|
|
pub, sig []byte
|
||
|
|
}
|
||
|
|
|
||
|
|
func (k badKey) Public() []byte { return k.pub }
|
||
|
|
func (k badKey) Sign([]byte) []byte { return k.sig }
|
||
|
|
|
||
|
|
// Spec v0.11 §62.1 rule 19: a signature that does not verify, or a key of
|
||
|
|
// another length, fails before anything is written.
|
||
|
|
func TestEncryptFilesSignatureChecked(t *testing.T) {
|
||
|
|
key, _ := authorkey.Generate()
|
||
|
|
for _, tc := range []struct {
|
||
|
|
name string
|
||
|
|
key capsule.AuthorKey
|
||
|
|
want string
|
||
|
|
}{
|
||
|
|
{"wrong signature", badKey{key.Public(), make([]byte, 64)}, "self-check"},
|
||
|
|
{"short key", badKey{key.Public()[:31], make([]byte, 64)}, "not 32"},
|
||
|
|
} {
|
||
|
|
opts := files3(t)
|
||
|
|
opts.AuthorKey = tc.key
|
||
|
|
var dkc bytes.Buffer
|
||
|
|
_, err := capsule.EncryptFiles(&dkc, []capsule.Source{source("nota.txt", "x")}, opts)
|
||
|
|
if err == nil || !strings.Contains(err.Error(), tc.want) {
|
||
|
|
t.Errorf("%s: %v", tc.name, err)
|
||
|
|
}
|
||
|
|
if dkc.Len() != 0 {
|
||
|
|
t.Errorf("%s: %d bytes written", tc.name, dkc.Len())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|