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/capsule/note_test.go

86 lines
3.2 KiB

package capsule_test
import (
"bytes"
"context"
"errors"
"strings"
"testing"
datekeys "g.activething.com/go/DateKeys"
"g.activething.com/go/DateKeys/capsule"
"g.activething.com/go/DateKeys/extension"
"g.activething.com/go/DateKeys/internal/testkit"
)
// Spec v0.11 §24.1, §62.1 rule 23: the public note is in PUBLIC_HEADER, in
// clear, and header_binding ties it to the control: changing it makes step 15
// fail.
func TestPublicNote(t *testing.T) {
opts := files3(t)
opts.PublicNote = "Cartas del viaje a Lisboa"
var dkc bytes.Buffer
if _, err := capsule.EncryptFiles(&dkc, []capsule.Source{source("nota.txt", "Hola.\n")}, opts); err != nil {
t.Fatal(err)
}
in, err := capsule.Inspect(bytes.NewReader(dkc.Bytes()), capsule.InspectOptions{Registry: testkit.Registry()})
if err != nil {
t.Fatal(err)
}
if note, ok := in.Header.PublicNote(); !ok || note != "Cartas del viaje a Lisboa" {
t.Errorf("the note: %q %v", note, ok)
}
// The same bytes with another letter in the note: it still inspects, and
// Open fails at step 15 with ERR_HEADER_BINDING.
changed := bytes.Replace(dkc.Bytes(), []byte("Lisboa"), []byte("Lisbon"), 1)
if bytes.Equal(changed, dkc.Bytes()) {
t.Fatal("the note is not in clear in the capsule")
}
o := defaultOpen(1000)
o.Sink = &testkit.MemorySink{}
if _, err := capsule.Open(context.Background(), nil, bytes.NewReader(changed), o); !errors.Is(err, datekeys.ErrHeaderBinding) {
t.Errorf("a note changed: %v", err)
}
if _, err := capsule.Open(context.Background(), nil, bytes.NewReader(dkc.Bytes()), o); err != nil {
t.Errorf("the capsule with its note: %v", err)
}
}
func TestPublicNoteRules(t *testing.T) {
for name, text := range map[string]string{
"a tab": "a\tb",
"a line feed": "a\nb",
"a space at the end": "a ",
"a space at the start": " a",
"too long": strings.Repeat("a", extension.MaxNoteLen+1),
"not UTF-8": "\xff",
} {
if err := extension.CheckNote(text); err == nil {
t.Errorf("%s: accepted", name)
}
opts := files3(t)
opts.PublicNote = text
if _, err := capsule.EncryptFiles(&bytes.Buffer{}, []capsule.Source{source("a", "x")}, opts); err == nil {
t.Errorf("%s: written", name)
}
}
if err := extension.CheckNote(strings.Repeat("a", extension.MaxNoteLen)); err != nil {
t.Errorf("1024 bytes: %v", err)
}
// An unusable note shows nothing.
if _, ok := extension.Note([]extension.Extension{{ID: extension.NoteID, Version: 1, Data: []byte("a\nb")}}); ok {
t.Error("an unusable note was shown")
}
// The registry knows it only in PUBLIC_HEADER, noncritical.
var reg extension.Standard
if !extension.KnownIn(reg, extension.NoteID, 1, extension.PublicHeader, extension.Noncritical) ||
extension.KnownIn(reg, extension.NoteID, 1, extension.Control, extension.Noncritical) ||
extension.KnownIn(reg, extension.NoteID, 1, extension.PublicHeader, extension.Critical) ||
extension.KnownIn(reg, extension.NoteID, 2, extension.PublicHeader, extension.Noncritical) {
t.Error("registration of datekeys.note")
}
if us := extension.CheckNoncriticalIn(extension.PublicHeader, []extension.Extension{{ID: extension.NoteID, Version: 1, Data: []byte("a\tb")}}, reg); len(us) != 1 {
t.Errorf("the note with a tab is not unusable: %v", us)
}
}

Powered by TurnKey Linux.