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.
62 lines
2.7 KiB
62 lines
2.7 KiB
|
2 weeks ago
|
package accesskey_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"errors"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
datekeys "g.activething.com/go/DateKeys"
|
||
|
|
"g.activething.com/go/DateKeys/accesskey"
|
||
|
|
"g.activething.com/go/DateKeys/internal/cbortest"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Spec §40, §57, §69.1: a .dkk reports the code of its first failing layer:
|
||
|
|
// the frame (magic, framing version, FLAGS and RESERVED, BODY_LEN in 1 to
|
||
|
|
// 16 MiB, the body present and nothing after it), then the type tag and the
|
||
|
|
// schema version, then the CDDL, and last access_type and access_material
|
||
|
|
// (keys 4 and 5), whose own code is ERR_ACCESS_INVALID. A field of the wrong
|
||
|
|
// CBOR type breaks the CDDL (layer 3), not its own rule.
|
||
|
|
func TestDecodePrecedence(t *testing.T) {
|
||
|
|
good, _ := loadDKK(t, "time_and_key_portable")
|
||
|
|
w, err := cbortest.UnmarshalMap(good[accesskey.PreludeSize:])
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
with := func(edit func(m map[uint64]any)) []byte {
|
||
|
|
m := map[uint64]any{}
|
||
|
|
for k, v := range w {
|
||
|
|
m[k] = v
|
||
|
|
}
|
||
|
|
edit(m)
|
||
|
|
b, err := cbortest.Marshal(m)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
return frame(b)
|
||
|
|
}
|
||
|
|
set := func(b []byte, i int, v byte) []byte { c := bytes.Clone(b); c[i] = v; return c }
|
||
|
|
malformed := frame([]byte{0xff})
|
||
|
|
a := map[uint64]any{0: "org.example.a", 1: uint64(1)}
|
||
|
|
for _, tc := range []struct {
|
||
|
|
name string
|
||
|
|
in []byte
|
||
|
|
want error
|
||
|
|
}{
|
||
|
|
{"BODY_LEN 0", frame(nil), datekeys.ErrIntegrity},
|
||
|
|
{"BODY_LEN 0 and FLAGS 1", set(frame(nil), 5, 1), datekeys.ErrInvalidFlags},
|
||
|
|
{"FLAGS 1 and a malformed body", set(malformed, 5, 1), datekeys.ErrInvalidFlags},
|
||
|
|
{"data after a malformed body", append(bytes.Clone(malformed), 0), datekeys.ErrIntegrity},
|
||
|
|
{"type tag of another schema and version 2", with(func(m map[uint64]any) { m[0], m[1] = "datekeycap", uint64(2) }), datekeys.ErrNonCanonicalCBOR},
|
||
|
|
{"version 2, unknown key and unknown access_type", with(func(m map[uint64]any) { m[1], m[9], m[4] = uint64(2), "x", "mlkem768" }), datekeys.ErrUnsupportedVersion},
|
||
|
|
{"unknown key and unknown access_type", with(func(m map[uint64]any) { m[9], m[4] = "x", "mlkem768" }), datekeys.ErrNonCanonicalCBOR},
|
||
|
|
{"extension_id in both arrays and short material", with(func(m map[uint64]any) { m[7], m[8], m[5] = []any{a}, []any{a}, make([]byte, 31) }), datekeys.ErrNonCanonicalCBOR},
|
||
|
|
{"access_type of another CBOR type", with(func(m map[uint64]any) { m[4] = uint64(1) }), datekeys.ErrNonCanonicalCBOR},
|
||
|
|
{"access_material of another CBOR type", with(func(m map[uint64]any) { m[5] = "material" }), datekeys.ErrNonCanonicalCBOR},
|
||
|
|
{"unknown access_type and short material", with(func(m map[uint64]any) { m[4], m[5] = "mlkem768", make([]byte, 31) }), datekeys.ErrAccessInvalid},
|
||
|
|
} {
|
||
|
|
if _, err := accesskey.Decode(bytes.NewReader(tc.in)); !errors.Is(err, tc.want) {
|
||
|
|
t.Errorf("%s: got %v, want %v", tc.name, err, tc.want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|