Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
package locator_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"encoding/hex"
|
Test data: locator.json with the cases of spec v0.12, section 64
- uri_cases: the first and the last address of each IPv4 block of 44.1,
with the public addresses next to them; the IPv6 blocks and the
addresses that hold an IPv4 one; the local names; characters outside
RFC 3986 and broken percent signs; "." and ".." segments; base32 that
is not a CID v1.
- mixed: a locator whose http and NAT64 addresses a reader rejects, and
whose third address it uses to find the rest.
- rest_cases: the rest alone, a host with bytes after the rest, a rest
with a byte changed, an offset that is not its own, a rest cut short.
- extension_cases: a locator sealed for round 1001 with a DateKey of
round 1000, and the other data that a reader cannot use.
- plaintext_cases: change 7, the bases 4094, 4070 and 3837 completed to
4096 with an empty key 6 or a length not in its shortest form, and a
defect in each field of the map.
- padding_cases: the bases 3837, 4070, 4094 and 4095 and those of the
next multiple, checked against the rule of 44.1.
The generator checks every case against this module and moves to its
own file. The vector is frozen: delete it to make it again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 days ago
|
|
|
"errors"
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
"path/filepath"
|
Test data: locator.json with the cases of spec v0.12, section 64
- uri_cases: the first and the last address of each IPv4 block of 44.1,
with the public addresses next to them; the IPv6 blocks and the
addresses that hold an IPv4 one; the local names; characters outside
RFC 3986 and broken percent signs; "." and ".." segments; base32 that
is not a CID v1.
- mixed: a locator whose http and NAT64 addresses a reader rejects, and
whose third address it uses to find the rest.
- rest_cases: the rest alone, a host with bytes after the rest, a rest
with a byte changed, an offset that is not its own, a rest cut short.
- extension_cases: a locator sealed for round 1001 with a DateKey of
round 1000, and the other data that a reader cannot use.
- plaintext_cases: change 7, the bases 4094, 4070 and 3837 completed to
4096 with an empty key 6 or a length not in its shortest form, and a
defect in each field of the map.
- padding_cases: the bases 3837, 4070, 4094 and 4095 and those of the
next multiple, checked against the rule of 44.1.
The generator checks every case against this module and moves to its
own file. The vector is frozen: delete it to make it again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 days ago
|
|
|
"slices"
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
"testing"
|
|
|
|
|
|
Test data: locator.json with the cases of spec v0.12, section 64
- uri_cases: the first and the last address of each IPv4 block of 44.1,
with the public addresses next to them; the IPv6 blocks and the
addresses that hold an IPv4 one; the local names; characters outside
RFC 3986 and broken percent signs; "." and ".." segments; base32 that
is not a CID v1.
- mixed: a locator whose http and NAT64 addresses a reader rejects, and
whose third address it uses to find the rest.
- rest_cases: the rest alone, a host with bytes after the rest, a rest
with a byte changed, an offset that is not its own, a rest cut short.
- extension_cases: a locator sealed for round 1001 with a DateKey of
round 1000, and the other data that a reader cannot use.
- plaintext_cases: change 7, the bases 4094, 4070 and 3837 completed to
4096 with an empty key 6 or a length not in its shortest form, and a
defect in each field of the map.
- padding_cases: the bases 3837, 4070, 4094 and 4095 and those of the
next multiple, checked against the rule of 44.1.
The generator checks every case against this module and moves to its
own file. The vector is frozen: delete it to make it again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 days ago
|
|
|
datekeys "g.activething.com/go/DateKeys"
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
"g.activething.com/go/DateKeys/extension"
|
|
|
|
|
"g.activething.com/go/DateKeys/internal/testkit"
|
|
|
|
|
"g.activething.com/go/DateKeys/locator"
|
|
|
|
|
"g.activething.com/go/DateKeys/profile"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func unhex(t *testing.T, s string) []byte {
|
|
|
|
|
t.Helper()
|
|
|
|
|
b, err := hex.DecodeString(s)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// testdata/vectors/locator.json is frozen: the extension of the .dkk reads,
|
|
|
|
|
// the sealed locator opens with the release of its round, the rest is found
|
|
|
|
|
// in the host at its offset, the envelope gives the .dkc back, and the rules
|
Test data: locator.json with the cases of spec v0.12, section 64
- uri_cases: the first and the last address of each IPv4 block of 44.1,
with the public addresses next to them; the IPv6 blocks and the
addresses that hold an IPv4 one; the local names; characters outside
RFC 3986 and broken percent signs; "." and ".." segments; base32 that
is not a CID v1.
- mixed: a locator whose http and NAT64 addresses a reader rejects, and
whose third address it uses to find the rest.
- rest_cases: the rest alone, a host with bytes after the rest, a rest
with a byte changed, an offset that is not its own, a rest cut short.
- extension_cases: a locator sealed for round 1001 with a DateKey of
round 1000, and the other data that a reader cannot use.
- plaintext_cases: change 7, the bases 4094, 4070 and 3837 completed to
4096 with an empty key 6 or a length not in its shortest form, and a
defect in each field of the map.
- padding_cases: the bases 3837, 4070, 4094 and 4095 and those of the
next multiple, checked against the rule of 44.1.
The generator checks every case against this module and moves to its
own file. The vector is frozen: delete it to make it again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 days ago
|
|
|
// of the addresses and of the padding give what the file says (spec v0.12,
|
|
|
|
|
// §44.1). So do its cases of §64: a locator whose addresses a reader rejects
|
|
|
|
|
// and uses in turn, the resources of the rest, the data of the extension and
|
|
|
|
|
// the plaintexts of the locator.
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
func TestLocatorVectors(t *testing.T) {
|
|
|
|
|
var v testkit.LocatorVectorFile
|
|
|
|
|
if err := testkit.ReadJSON(filepath.Join("..", "testdata", "vectors", "locator.json"), &v); err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
p := profile.Quicknet()
|
|
|
|
|
|
|
|
|
|
info, err := locator.ParseInfo(extension.Extension{ID: extension.CapsuleID, Version: 1, Data: unhex(t, v.Extension)})
|
|
|
|
|
if err != nil || info.Note != v.Note || info.DateKey.Compact() != v.DateKey || info.DateKey.Round != v.Round || !bytes.Equal(info.Sealed, unhex(t, v.Sealed)) {
|
|
|
|
|
t.Fatalf("the extension: %+v, %v", info, err)
|
|
|
|
|
}
|
|
|
|
|
loc, err := locator.Open(p, v.Round, testkit.Release(v.Round), unhex(t, v.Sealed))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
plain, err := loc.Marshal()
|
|
|
|
|
if err != nil || !bytes.Equal(plain, unhex(t, v.Plaintext)) || len(plain) != locator.Block {
|
|
|
|
|
t.Fatalf("the plaintext of the locator: %d bytes, %v", len(plain), err)
|
|
|
|
|
}
|
|
|
|
|
if hex.EncodeToString(loc.EnvelopeKey[:]) != v.EnvelopeKey || hex.EncodeToString(loc.RestDigest[:]) != v.RestDigest || loc.RestSize != v.RestSize ||
|
|
|
|
|
hex.EncodeToString(loc.CapsuleDigest[:]) != v.CapsuleDigest || hex.EncodeToString(loc.EnvelopeHeader) != v.Header || len(loc.Addresses) != len(v.Addresses) {
|
|
|
|
|
t.Fatalf("the fields of the locator: %+v", loc)
|
|
|
|
|
}
|
|
|
|
|
for i, a := range v.Addresses {
|
|
|
|
|
if loc.Addresses[i].URI != a.URI || loc.Addresses[i].Offset != a.Offset || loc.Addresses[i].Host() != a.Host {
|
|
|
|
|
t.Errorf("address %d: %+v", i, loc.Addresses[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// The rest, from the host at the offset of the first address, opens the envelope.
|
|
|
|
|
rest, err := loc.RestIn(unhex(t, v.Host), v.HostOffset)
|
|
|
|
|
if err != nil || !bytes.Equal(rest, unhex(t, v.Rest)) {
|
|
|
|
|
t.Fatalf("the rest in the host: %v", err)
|
|
|
|
|
}
|
|
|
|
|
dkc, err := loc.OpenEnvelope(rest)
|
|
|
|
|
if err != nil || !bytes.Equal(dkc, unhex(t, v.DKC)) {
|
|
|
|
|
t.Fatalf("the envelope: %v", err)
|
|
|
|
|
}
|
|
|
|
|
for _, c := range v.PaddingCases {
|
|
|
|
|
if got := locator.PlaintextLength(c.Base); got != c.Total || got%locator.Block != 0 {
|
|
|
|
|
t.Errorf("padding of %d: %d, want %d", c.Base, got, c.Total)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, c := range v.URICases {
|
|
|
|
|
if got := locator.CheckURI(c.URI) == nil; got != c.OK {
|
|
|
|
|
t.Errorf("%q: accepted %v, want %v", c.URI, got, c.OK)
|
|
|
|
|
}
|
|
|
|
|
}
|
Test data: locator.json with the cases of spec v0.12, section 64
- uri_cases: the first and the last address of each IPv4 block of 44.1,
with the public addresses next to them; the IPv6 blocks and the
addresses that hold an IPv4 one; the local names; characters outside
RFC 3986 and broken percent signs; "." and ".." segments; base32 that
is not a CID v1.
- mixed: a locator whose http and NAT64 addresses a reader rejects, and
whose third address it uses to find the rest.
- rest_cases: the rest alone, a host with bytes after the rest, a rest
with a byte changed, an offset that is not its own, a rest cut short.
- extension_cases: a locator sealed for round 1001 with a DateKey of
round 1000, and the other data that a reader cannot use.
- plaintext_cases: change 7, the bases 4094, 4070 and 3837 completed to
4096 with an empty key 6 or a length not in its shortest form, and a
defect in each field of the map.
- padding_cases: the bases 3837, 4070, 4094 and 4095 and those of the
next multiple, checked against the rule of 44.1.
The generator checks every case against this module and moves to its
own file. The vector is frozen: delete it to make it again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 days ago
|
|
|
|
|
|
|
|
// The mixed locator reads: a reader rejects the addresses that break the
|
|
|
|
|
// rules and uses the other, which finds the rest in the host.
|
|
|
|
|
want := unhex(t, v.DKC)
|
|
|
|
|
mixed, err := locator.Open(p, v.Round, testkit.Release(v.Round), unhex(t, v.Mixed.Sealed))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if back, err := locator.Unmarshal(unhex(t, v.Mixed.Plaintext)); err != nil || len(back.Addresses) != len(v.Mixed.Addresses) || len(mixed.Addresses) != len(v.Mixed.Addresses) {
|
|
|
|
|
t.Fatalf("the mixed locator: %v", err)
|
|
|
|
|
}
|
|
|
|
|
var usable []locator.Address
|
|
|
|
|
for i, a := range v.Mixed.Addresses {
|
|
|
|
|
if mixed.Addresses[i] != (locator.Address{URI: a.URI, Offset: a.Offset}) {
|
|
|
|
|
t.Errorf("mixed address %d: %+v", i, mixed.Addresses[i])
|
|
|
|
|
}
|
|
|
|
|
if a.Usable {
|
|
|
|
|
usable = append(usable, mixed.Addresses[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if got := mixed.Usable(); len(usable) == 0 || !slices.Equal(got, usable) {
|
|
|
|
|
t.Fatalf("usable: %v, want %v", got, usable)
|
|
|
|
|
}
|
|
|
|
|
if rest, err = mixed.RestIn(unhex(t, v.Host), usable[0].Offset); err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if dkc, err := mixed.OpenEnvelope(rest); err != nil || !bytes.Equal(dkc, want) {
|
|
|
|
|
t.Fatalf("the envelope of the mixed locator: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A reader reads RestSize bytes from the offset, whatever follows, and
|
|
|
|
|
// uses them only when their SHA-256 is resto_digest.
|
|
|
|
|
for _, c := range v.RestCases {
|
|
|
|
|
opens := false
|
|
|
|
|
if r, err := loc.RestIn(unhex(t, c.Resource), c.Offset); err == nil {
|
|
|
|
|
dkc, err := loc.OpenEnvelope(r)
|
|
|
|
|
opens = err == nil && bytes.Equal(dkc, want)
|
|
|
|
|
}
|
|
|
|
|
if opens != c.Opens {
|
|
|
|
|
t.Errorf("%s: opens %v, want %v", c.Name, opens, c.Opens)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// An extension that a reader cannot use carries only
|
|
|
|
|
// ERR_EXTENSION_DATA_INVALID (spec §54).
|
|
|
|
|
for _, c := range v.ExtensionCases {
|
|
|
|
|
_, err := locator.ParseInfo(extension.Extension{ID: extension.CapsuleID, Version: 1, Data: unhex(t, c.Data)})
|
|
|
|
|
if (err == nil) != c.OK || err != nil && !errors.Is(err, datekeys.ErrExtensionDataInvalid) {
|
|
|
|
|
t.Errorf("%s: %v", c.Name, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, c := range v.PlaintextCases {
|
|
|
|
|
if _, err := locator.Unmarshal(unhex(t, c.Plaintext)); (err == nil) != c.OK {
|
|
|
|
|
t.Errorf("%s: %v", c.Name, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
Test data for the second implementation: alg 2, the seal and the locator
Fixtures format3_signed_cms (alg 2, two certificates, each sealed, F6) and
format3_sealed (alg 1 and a seal of seal_type 2, F4 and S4), with the
certificates, SIGNERS, the commitments, SEAL_SUBJECT, the token and the
result of each signer in their records. vectors/security_cms.json has 22
frozen areas with their context and verdicts (F1, F2, F5, F6, S1 to S5), and
vectors/locator.json the extension datekeys.capsule with its envelope hidden
in a host, its locator sealed with tlock, the padding at the boundaries and
the rules of the addresses. The README of testdata describes all of it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
}
|