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.
86 lines
3.2 KiB
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)
|
|
}
|
|
}
|