diff --git a/capsule/cmsvectors_test.go b/capsule/cmsvectors_test.go new file mode 100644 index 0000000..1f772d7 --- /dev/null +++ b/capsule/cmsvectors_test.go @@ -0,0 +1,61 @@ +package capsule_test + +import ( + "encoding/hex" + "path/filepath" + "reflect" + "testing" + "time" + + "g.activething.com/go/DateKeys/capsule" + "g.activething.com/go/DateKeys/internal/testkit" +) + +// testdata/vectors/security_cms.json is frozen: each case is evaluated again, +// with its context, and must give its verdicts, the results of each signer +// and the authority of a valid seal (spec v0.11 §29.7, §29.10, §29.11). +func TestCMSVectors(t *testing.T) { + var f testkit.CMSVectorFile + if err := testkit.ReadJSON(filepath.Join("..", "testdata", "vectors", "security_cms.json"), &f); err != nil { + t.Fatal(err) + } + if len(f.Cases) < 20 { + t.Fatalf("%d cases", len(f.Cases)) + } + for _, c := range f.Cases { + t.Run(c.Name, func(t *testing.T) { + area, err := hex.DecodeString(c.SecurityCBOR) + if err != nil { + t.Fatal(err) + } + var v capsule.Verdicts + if c.NoContext { + v = capsule.EvaluateSecurity(area) + } else { + var sc capsule.SecurityContext + cc, _ := hex.DecodeString(c.Context.ControlCommit) + hd, _ := hex.DecodeString(c.Context.HeadDigest) + copy(sc.ControlCommit[:], cc) + copy(sc.HeadDigest[:], hd) + if sc.RoundTime, err = time.Parse(time.RFC3339, c.Context.RoundTime); err != nil { + t.Fatal(err) + } + v = capsule.EvaluateSecurityIn(area, &sc) + } + if string(v.Signature) != c.Signature || string(v.Seal) != c.Seal { + t.Fatalf("verdicts %s and %s, want %s and %s", v.Signature, v.Seal, c.Signature, c.Seal) + } + var signers, foreign []testkit.FixtureSignerResult + var holder, when string + if d := v.Detail; d != nil { + signers, foreign = signerResults(d.Signers), signerResults(d.Foreign) + if !d.SealTime.IsZero() { + holder, when = d.SealHolder, d.SealTime.UTC().Format(time.RFC3339) + } + } + if !reflect.DeepEqual(signers, c.Signers) || !reflect.DeepEqual(foreign, c.Foreign) || holder != c.SealHolder || when != c.SealTime { + t.Errorf("signers %+v foreign %+v seal %q %q; want %+v %+v %q %q", signers, foreign, holder, when, c.Signers, c.Foreign, c.SealHolder, c.SealTime) + } + }) + } +} diff --git a/capsule/conformance_test.go b/capsule/conformance_test.go index 45cad18..91a25d9 100644 --- a/capsule/conformance_test.go +++ b/capsule/conformance_test.go @@ -36,7 +36,7 @@ var fixtureNames = []string{ "format2_time_and_key_portable", "format2_time_and_key_recipients", "format2_time_and_key_sixteen", "format3_single", "format3_tree", "format3_comment_only", "format3_bloque256", "format3_time_and_key_portable", "format3_area_1024", "format3_security_v2", "format3_signature_unsupported", "format3_seal_unsupported", - "format3_signed", + "format3_signed", "format3_signed_cms", "format3_sealed", } type fixture struct { @@ -328,15 +328,16 @@ func TestConformanceFixtures(t *testing.T) { } } -// checkSignature3 checks the record of the signature of a format 3 fixture -// against what this implementation computes from the control, the head and -// the security of the fixture (spec v0.11, §29.8, §29.9): the commitments, -// AUTHOR_MESSAGE and its code, the signature, which Ed25519 makes again -// from the seed of the record, and the key. It returns the verdicts in the +// checkSignature3 checks the record of the signature and of the seal of a +// format 3 fixture against what this implementation computes from the +// control, the head and the security of the fixture (spec v0.11, §29.8 to +// §29.11): the commitments, AUTHOR_MESSAGE and its code, the signature, which +// Ed25519 makes again from the seed of the record with alg 1, the key, and +// with alg 2 SIGNERS, the certificates and the result of each signer; +// SEAL_SUBJECT and the token of a seal. It returns the verdicts in the // context of the capsule. func checkSignature3(t *testing.T, f *fixture, security, head []byte) capsule.Verdicts { t.Helper() - s := f.Signature cb, err := hex.DecodeString(f.ControlCBOR) if err != nil { t.Fatal(err) @@ -349,32 +350,92 @@ func checkSignature3(t *testing.T, f *fixture, security, head []byte) capsule.Ve if err != nil { t.Fatal(err) } - hd, sd := capsule.HeadDigest(head), capsule.SignersDigest(capsule.AlgEd25519, nil) - msg := capsule.AuthorMessage(cc, hd, sd) - content, value, err := capsule.SecurityKey2(security) + hd := capsule.HeadDigest(head) + unlock, err := time.Parse(time.RFC3339, f.UnlockAt) if err != nil { t.Fatal(err) } - seed, err := hex.DecodeString(s.SecretSeed) + v := capsule.EvaluateSecurityIn(security, &capsule.SecurityContext{ControlCommit: cc, HeadDigest: hd, RoundTime: unlock}) + if s := f.Signature; s != nil { + checkSignatureRecord(t, s, security, cc, hd, v) + } + if s := f.Seal; s != nil { + var part []byte + if content, _, err := capsule.SecurityKey2(security); err == nil { + part = content + } + subject := capsule.SealSubject(cc, hd, capsule.SigPart(part)) + typ, token, err := capsule.SecurityKey3(security) + if err != nil { + t.Fatal(err) + } + if s.SealType != capsule.SealTypeRFC3161 || uint64(s.SealType) != typ || s.SealSubject != hex.EncodeToString(subject[:]) || s.Token != hex.EncodeToString(token) || + v.Detail == nil || s.Holder != v.Detail.SealHolder || s.Time != v.Detail.SealTime.UTC().Format(time.RFC3339) { + t.Fatalf("the record of the seal differs from what is computed: %+v", s) + } + } + return v +} + +func checkSignatureRecord(t *testing.T, s *testkit.FixtureSignature, security []byte, cc, hd [32]byte, v capsule.Verdicts) { + t.Helper() + content, value, err := capsule.SecurityKey2(security) if err != nil { t.Fatal(err) } - key, err := authorkey.NewFromSeed(seed) + alg, key, _, err := capsule.DecodeAuthorSignature(content) if err != nil { t.Fatal(err) } - pub, _ := authorkey.PublicString(key.Public()) - if s.Alg != capsule.AlgEd25519 || s.AuthorKey != pub || s.ControlCommit != hex.EncodeToString(cc[:]) || s.HeadDigest != hex.EncodeToString(hd[:]) || - s.SignersDigest != hex.EncodeToString(sd[:]) || s.AuthorMessage != string(msg) || s.AuthorCode != capsule.AuthorCode(msg) || - s.SignatureValue != hex.EncodeToString(value) || s.SecurityKey2 != hex.EncodeToString(content) || - hex.EncodeToString(key.Sign(msg)) != s.SignatureValue { - t.Fatalf("the record of the signature differs from what is computed: %+v", s) + if uint64(s.Alg) != alg || s.SignatureValue != hex.EncodeToString(value) || s.SecurityKey2 != hex.EncodeToString(content) || + s.ControlCommit != hex.EncodeToString(cc[:]) || s.HeadDigest != hex.EncodeToString(hd[:]) { + t.Fatalf("the record of the signature differs from the security area: %+v", s) } - unlock, err := time.Parse(time.RFC3339, f.UnlockAt) - if err != nil { - t.Fatal(err) + var sd [32]byte + switch alg { + case capsule.AlgEd25519: + sd = capsule.SignersDigest(capsule.AlgEd25519, nil) + seed, err := hex.DecodeString(s.SecretSeed) + if err != nil { + t.Fatal(err) + } + k, err := authorkey.NewFromSeed(seed) + if err != nil { + t.Fatal(err) + } + pub, _ := authorkey.PublicString(k.Public()) + msg := capsule.AuthorMessage(cc, hd, sd) + if s.AuthorKey != pub || hex.EncodeToString(k.Sign(msg)) != s.SignatureValue { + t.Fatalf("the key or the signature of the record: %+v", s) + } + case capsule.AlgCMS: + sd = capsule.SignersDigest(capsule.AlgCMS, key) + if s.Signers != hex.EncodeToString(key) || v.Detail == nil || + !reflect.DeepEqual(s.Results, signerResults(v.Detail.Signers)) || !reflect.DeepEqual(s.Foreign, signerResults(v.Detail.Foreign)) { + t.Fatalf("SIGNERS or the results of the record: %+v", s) + } + if len(s.Certificates) == 0 { + t.Fatal("no certificates in the record") + } + default: + t.Fatalf("alg %d", alg) + } + msg := capsule.AuthorMessage(cc, hd, sd) + if s.SignersDigest != hex.EncodeToString(sd[:]) || s.AuthorMessage != string(msg) || s.AuthorCode != capsule.AuthorCode(msg) { + t.Fatalf("SIGNERS digest or AUTHOR_MESSAGE of the record: %+v", s) + } +} + +func signerResults(lines []capsule.SignerLine) []testkit.FixtureSignerResult { + var out []testkit.FixtureSignerResult + for _, l := range lines { + r := testkit.FixtureSignerResult{Holder: l.Holder, Issuer: l.Issuer, Result: l.Result, Before: l.Before} + if !l.SealTime.IsZero() { + r.SealTime = l.SealTime.UTC().Format(time.RFC3339) + } + out = append(out, r) } - return capsule.EvaluateSecurityIn(security, &capsule.SecurityContext{ControlCommit: cc, HeadDigest: hd, RoundTime: unlock}) + return out } // checkBody3 checks BODY, the plaintext file of a format 3 fixture, against @@ -399,7 +460,7 @@ func checkBody3(t *testing.T, f *fixture) { t.Fatal("the area, security, the head or the offset of CONTENT differ") } v := capsule.EvaluateSecurity(security) - if f.Signature != nil { + if f.Signature != nil || f.Seal != nil { v = checkSignature3(t, f, security, hb) } if f.Verdicts == nil || string(v.Signature) != f.Verdicts.Signature || string(v.Seal) != f.Verdicts.Seal || !reflect.DeepEqual(v.Lines(), f.Verdicts.Lines) { diff --git a/capsule/signature.go b/capsule/signature.go index 4a9fcc0..879e9f7 100644 --- a/capsule/signature.go +++ b/capsule/signature.go @@ -160,6 +160,31 @@ func SecurityKey2(security []byte) (content, value []byte, err error) { return w.signature, a.value, nil } +// SecurityKey3 returns the seal_type and the token of key 3 of SECURITY_CBOR: +// what a generator of test vectors records about a seal. It fails when +// security has no key 3 or its content does not decode. +func SecurityKey3(security []byte) (sealType uint64, token []byte, err error) { + w, ok := decodeSecurity(security) + if !ok || w.seal == nil { + return 0, nil, errors.New("capsule: SECURITY_CBOR holds no seal") + } + s, err := decodeSeal(w.seal) + if err != nil { + return 0, nil, err + } + return s.sealType, s.token, nil +} + +// DecodeAuthorSignature reads the content of key 2 of SECURITY_CBOR: the alg, +// key 1 (the public key of alg 1, SIGNERS of alg 2) and the signature value. +func DecodeAuthorSignature(content []byte) (alg uint64, key, value []byte, err error) { + a, err := decodeAuthorSignature(content) + if err != nil { + return 0, nil, nil, err + } + return a.alg, a.key, a.value, nil +} + // SecurityContext is what the verdicts of a signature or a seal need besides // SECURITY_CBOR: the commitments of the capsule, the time of its round, and // the author keys that the person saved, by their dkauthor1… string, with the diff --git a/cmd/datekeys/main_test.go b/cmd/datekeys/main_test.go index e6e34b0..0aed4e8 100644 --- a/cmd/datekeys/main_test.go +++ b/cmd/datekeys/main_test.go @@ -134,6 +134,8 @@ func TestDecryptFormat3Fixtures(t *testing.T) { {"format3_time_and_key_portable", "format3_time_and_key_portable.dkk"}, {"format3_seal_unsupported", ""}, {"format3_signed", ""}, + {"format3_signed_cms", ""}, + {"format3_sealed", ""}, } { t.Run(tc.name, func(t *testing.T) { var f testkit.DKCFixture @@ -476,8 +478,8 @@ func TestInspectJSONGoldens(t *testing.T) { if err != nil { t.Fatal(err) } - if len(names) != len(dkcs) || len(dkcs) != 22 { - t.Fatalf("%d frozen inspect outputs, want one per official .dkc (%d, 22)", len(names), len(dkcs)) + if len(names) != len(dkcs) || len(dkcs) != 24 { + t.Fatalf("%d frozen inspect outputs, want one per official .dkc (%d, 24)", len(names), len(dkcs)) } t.Chdir(fixtures) for _, path := range names { diff --git a/internal/testkit/cmsvectors.go b/internal/testkit/cmsvectors.go new file mode 100644 index 0000000..178e029 --- /dev/null +++ b/internal/testkit/cmsvectors.go @@ -0,0 +1,97 @@ +package testkit + +// CMSVectorFile is testdata/vectors/security_cms.json: SECURITY_CBOR areas +// with an author signature of alg 2 (CMS with certificates) or a time seal +// of seal_type 2 (RFC 3161), each with the context of its capsule and the +// verdicts that spec v0.11 §29.7, §29.10 and §29.11 give. The certificates +// and the tokens are made once, with test keys, and the file is frozen: a +// second implementation reads them and must reach the same verdicts. +type CMSVectorFile struct { + Description string `json:"description"` + Spec string `json:"spec"` + Cases []CMSVectorCase `json:"cases"` +} + +// CMSVectorContext is what a verdict needs besides SECURITY_CBOR (§29.7): +// control_commit and head_digest in hexadecimal, and round_time in RFC 3339. +type CMSVectorContext struct { + ControlCommit string `json:"control_commit"` + HeadDigest string `json:"head_digest"` + RoundTime string `json:"round_time"` +} + +// CMSVectorCase is one case: the area, its context, and the verdicts. +type CMSVectorCase struct { + Name string `json:"name"` + SecurityCBOR string `json:"security_cbor"` + // NoContext is true when the area is read without the context of a + // capsule, as a reader of v0.10 does: any signature is F1, any seal S1. + NoContext bool `json:"no_context,omitempty"` + Context CMSVectorContext `json:"context"` + Signature string `json:"signature"` + Seal string `json:"seal"` + // Signers and Foreign are the results of an alg 2 signature, in the + // order of SIGNERS; SealHolder and SealTime are those of a valid seal. + Signers []FixtureSignerResult `json:"signers,omitempty"` + Foreign []FixtureSignerResult `json:"foreign_signers,omitempty"` + SealHolder string `json:"seal_holder,omitempty"` + SealTime string `json:"seal_time,omitempty"` +} + +// LocatorVectorFile is testdata/vectors/locator.json: the extension +// datekeys.capsule of a .dkk and what it points to (spec v0.11, §44.1). It is +// made once and frozen: the envelope and the sealed locator hold randomness. +type LocatorVectorFile struct { + Description string `json:"description"` + Spec string `json:"spec"` + // Round is the round of the DateKey of the extension, and the locator is + // sealed with tlock for it: it opens with the release of that round. + Round uint64 `json:"round"` + DateKey string `json:"datekey"` + Note string `json:"note"` + // DKC is the capsule that the envelope hides, in hexadecimal. + DKC string `json:"dkc"` + // Rest is what is kept outside, Header what the locator carries, and Host + // a file with the rest appended at HostOffset. + Rest string `json:"rest"` + Header string `json:"envelope_header"` + Host string `json:"host"` + HostOffset uint64 `json:"host_offset"` + // Plaintext is the plaintext of the locator, in 4096 bytes; Sealed, the + // age file with the tlock stanza; Extension, the data of datekeys.capsule. + Plaintext string `json:"locator_plaintext"` + Sealed string `json:"locator_sealed"` + Extension string `json:"extension_data"` + // The fields of the locator, for a reader that compares them. + Addresses []LocatorVectorAddress `json:"addresses"` + EnvelopeKey string `json:"envelope_key"` + RestDigest string `json:"rest_digest"` + RestSize uint64 `json:"rest_size"` + CapsuleDigest string `json:"capsule_digest"` + // PaddingCases give the length of the plaintext for a length of the CBOR + // without key 6, around the boundaries where the CBOR length of key 6 + // changes: the least multiple of 4096 that key 6 can fill exactly. + PaddingCases []LocatorPaddingCase `json:"padding_cases"` + // URICases give the verdict of the rules of §44.1 on an address. + URICases []LocatorURICase `json:"uri_cases"` +} + +// LocatorVectorAddress is an address of the locator. +type LocatorVectorAddress struct { + URI string `json:"uri"` + Offset uint64 `json:"offset"` + Host string `json:"host"` +} + +// LocatorPaddingCase is a length of the CBOR without padding and the length of +// the plaintext that results. +type LocatorPaddingCase struct { + Base int `json:"base"` + Total int `json:"total"` +} + +// LocatorURICase is an address and whether it is accepted. +type LocatorURICase struct { + URI string `json:"uri"` + OK bool `json:"ok"` +} diff --git a/internal/testkit/fixture.go b/internal/testkit/fixture.go index 4c52377..69db98d 100644 --- a/internal/testkit/fixture.go +++ b/internal/testkit/fixture.go @@ -88,7 +88,10 @@ type DKCFixture struct { // implementation needs to check the signature and to make it again // (spec v0.11, §29.8, §29.9). Signature *FixtureSignature `json:"signature,omitempty"` - Stages []FixtureStage `json:"stages"` + // Seal is, in a fixture with a valid time seal, what a second + // implementation needs to check it (spec v0.11, §29.11). + Seal *FixtureSeal `json:"seal,omitempty"` + Stages []FixtureStage `json:"stages"` } // FixtureFile is a file of a format 3 fixture: its entry of the head. Its @@ -120,16 +123,47 @@ type FixtureVerdicts struct { // signed, and AuthorCode its code. SecurityKey2 is the exact content of key // 2 of SECURITY_CBOR, in hexadecimal. type FixtureSignature struct { - Alg int `json:"alg"` - SecretSeed string `json:"secret_seed"` - AuthorKey string `json:"author_key"` - ControlCommit string `json:"control_commit"` - HeadDigest string `json:"head_digest"` - SignersDigest string `json:"signers_digest"` - AuthorMessage string `json:"author_message"` - AuthorCode string `json:"author_code"` + Alg int `json:"alg"` + // SecretSeed and AuthorKey are those of an alg 1 signature. + SecretSeed string `json:"secret_seed,omitempty"` + AuthorKey string `json:"author_key,omitempty"` + ControlCommit string `json:"control_commit"` + HeadDigest string `json:"head_digest"` + SignersDigest string `json:"signers_digest"` + AuthorMessage string `json:"author_message"` + AuthorCode string `json:"author_code"` + // SignatureValue is the 64 bytes of alg 1, or the DER of the CMS + // signature of alg 2. SignatureValue string `json:"signature"` SecurityKey2 string `json:"security_key_2"` + // Signers is, with alg 2, SIGNERS in hexadecimal, Certificates the DER of + // the certificates inside the signature, and Results what each required + // signer gave, in the order of SIGNERS; Foreign are the others. + Signers string `json:"signers,omitempty"` + Certificates []string `json:"certificates,omitempty"` + Results []FixtureSignerResult `json:"signer_results,omitempty"` + Foreign []FixtureSignerResult `json:"foreign_signers,omitempty"` +} + +// FixtureSignerResult is a signer of an alg 2 signature as a reader shows it +// (spec §29.7, §29.10). +type FixtureSignerResult struct { + Holder string `json:"holder"` + Issuer string `json:"issuer"` + Result string `json:"result"` + SealTime string `json:"seal_time,omitempty"` + Before bool `json:"before_round_time"` +} + +// FixtureSeal describes the seal of seal_type 2 of a format 3 fixture: +// SEAL_SUBJECT, the token in hexadecimal, the holder of the certificate of +// the authority as §29.7 shows it, and t. +type FixtureSeal struct { + SealType int `json:"seal_type"` + SealSubject string `json:"seal_subject"` + Token string `json:"token"` + Holder string `json:"holder"` + Time string `json:"time"` } // FixtureExt is an extension in a fixture. diff --git a/internal/testkit/genfixtures/cmsfix.go b/internal/testkit/genfixtures/cmsfix.go new file mode 100644 index 0000000..e100d99 --- /dev/null +++ b/internal/testkit/genfixtures/cmsfix.go @@ -0,0 +1,71 @@ +package main + +import ( + "crypto/elliptic" + "crypto/sha256" + "time" + + "g.activething.com/go/DateKeys/capsule" + "g.activething.com/go/DateKeys/internal/cms/cmstest" + "g.activething.com/go/DateKeys/internal/testkit" +) + +// The fixtures with certificates (spec v0.11, §29.10, §29.11) are signed by +// test certificates made when the fixture is generated, so their bytes are +// random and, like those of the other fixtures, frozen once written. The +// private keys are not kept: a reader only verifies. +var ( + certFrom = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) + certTo = time.Date(2040, 1, 1, 0, 0, 0, 0, time.UTC) +) + +func sum256(b []byte) [32]byte { return sha256.Sum256(b) } + +// certSigner is a CMSSigner that signs as a signing application would, and +// seals each signature with the authority tsa at the writing time. +type certSigner struct { + signers []cmstest.Signer + tsa cmstest.Signer + when time.Time +} + +func (c *certSigner) Signers() (out [][32]byte) { + for _, s := range c.signers { + out = append(out, sum256(s.Cert.Raw)) + } + return out +} + +func (c *certSigner) Sign(message []byte) ([]byte, error) { + return cmstest.Signature(message, cmstest.Options{Token: func(sig []byte) []byte { + return cmstest.Token(sig, c.when, cmstest.TokenOptions{Accuracy: time.Second}, c.tsa) + }}, c.signers...), nil +} + +// tokenSealer asks the authority tsa for the token over SEAL_SUBJECT. +type tokenSealer struct { + tsa cmstest.Signer + when time.Time +} + +func (s tokenSealer) Seal(subject [32]byte) ([]byte, error) { + return cmstest.Token(subject[:], s.when, cmstest.TokenOptions{Accuracy: time.Second}, s.tsa), nil +} + +// configureCMS makes the capsule be signed by two certificates, an ECDSA one +// and an RSA one, each sealed by a time-stamping authority: verdict F6. +func configureCMS(o *capsule.EncryptOptions) error { + ana := cmstest.NewECDSA("Ana López", elliptic.P256(), certFrom, certTo) + luis := cmstest.NewRSA("Luis Gómez", 2048, certFrom, certTo) + tsa := cmstest.NewECDSA("Autoridad de Sellado de prueba", elliptic.P256(), certFrom, certTo) + o.CMSSigner = &certSigner{signers: []cmstest.Signer{ana, luis}, tsa: tsa, when: testkit.Genesis()} + return nil +} + +// configureSeal makes the capsule carry a seal of seal_type 2 over the +// signature of alg 1 that its spec gives a key for: verdicts F4 and S4. +func configureSeal(o *capsule.EncryptOptions) error { + tsa := cmstest.NewECDSA("Autoridad de Sellado de prueba", elliptic.P256(), certFrom, certTo) + o.Sealer = tokenSealer{tsa: tsa, when: testkit.Genesis()} + return nil +} diff --git a/internal/testkit/genfixtures/cmsvectors.go b/internal/testkit/genfixtures/cmsvectors.go new file mode 100644 index 0000000..0932125 --- /dev/null +++ b/internal/testkit/genfixtures/cmsvectors.go @@ -0,0 +1,260 @@ +package main + +import ( + "bytes" + "crypto" + "crypto/elliptic" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "os" + "path/filepath" + "time" + + "g.activething.com/go/DateKeys/authorkey" + "g.activething.com/go/DateKeys/capsule" + "g.activething.com/go/DateKeys/datekey" + "g.activething.com/go/DateKeys/extension" + "g.activething.com/go/DateKeys/internal/cms/cmstest" + "g.activething.com/go/DateKeys/internal/testkit" + "g.activething.com/go/DateKeys/locator" + "g.activething.com/go/DateKeys/profile" +) + +// frozenVectors writes testdata/vectors/security_cms.json and locator.json +// when they are missing: their bytes hold the randomness of certificates, of +// age and of tlock, so they are made once and kept, as the fixtures are. +// Delete a file to make it again. +func frozenVectors(dir string) error { + for name, gen := range map[string]func() (any, error){ + "security_cms.json": securityCMSVectors, + "locator.json": locatorVectors, + } { + path := filepath.Join(dir, name) + if _, err := os.Stat(path); err == nil { + continue + } + v, err := gen() + if err != nil { + return fmt.Errorf("%s: %w", name, err) + } + if err := testkit.WriteJSON(path, v); err != nil { + return err + } + } + return nil +} + +var ( + vecRound = time.Date(2030, 1, 1, 0, 0, 0, 0, time.UTC) + vecSigned = time.Date(2026, 9, 30, 12, 0, 0, 0, time.UTC) +) + +func hex32(b [32]byte) string { return hex.EncodeToString(b[:]) } + +// cmsArea builds SECURITY_CBOR with an alg 2 signature by the signers over +// the context c, sealed by tsa at when; required lists who must sign. +func cmsArea(c *capsule.SecurityContext, required, signers []cmstest.Signer, tsa cmstest.Signer, when time.Time, seal []byte) ([]byte, error) { + var hashes [][32]byte + for _, s := range required { + hashes = append(hashes, sum256(s.Cert.Raw)) + } + list, err := capsule.EncodeSigners(hashes) + if err != nil { + return nil, err + } + msg := capsule.AuthorMessage(c.ControlCommit, c.HeadDigest, capsule.SignersDigest(capsule.AlgCMS, list)) + opts := cmstest.Options{} + if tsa.Key != nil { + opts.Token = func(sig []byte) []byte { + return cmstest.Token(sig, when, cmstest.TokenOptions{Accuracy: time.Second}, tsa) + } + } + content, err := capsule.EncodeAuthorSignature(capsule.AlgCMS, list, cmstest.Signature(msg, opts, signers...)) + if err != nil { + return nil, err + } + return capsule.EncodeSecurityWith(content, seal) +} + +func securityCMSVectors() (any, error) { + ana := cmstest.NewECDSA("Ana López", elliptic.P256(), certFrom, certTo) + luis := cmstest.NewRSA("Luis Gómez", 2048, certFrom, certTo) + otro := cmstest.NewECDSA("Otro", elliptic.P384(), certFrom, certTo) + tsa := cmstest.NewECDSA("Autoridad de Sellado de prueba", elliptic.P256(), certFrom, certTo) + ctx := func() *capsule.SecurityContext { + return &capsule.SecurityContext{ControlCommit: sha256.Sum256([]byte("control")), HeadDigest: sha256.Sum256([]byte("head")), RoundTime: vecRound} + } + key, err := authorkey.NewFromSeed(bytes.Repeat([]byte{7}, 32)) + if err != nil { + return nil, err + } + + f := testkit.CMSVectorFile{ + Spec: testkit.SpecVersion, + Description: "SECURITY_CBOR with an author signature of alg 2 or a time seal of seal_type 2, its context and the verdicts of spec v0.11 29.7, 29.10 and 29.11. " + + "Certificates and tokens are made once with test keys and the file is frozen. See testdata/README.md.", + } + var errs []error + add := func(name string, area []byte, c *capsule.SecurityContext, wantSig, wantSeal capsule.Verdict) { + var v capsule.Verdicts + vc := testkit.CMSVectorCase{Name: name, SecurityCBOR: hex.EncodeToString(area)} + if c == nil { + v, vc.NoContext = capsule.EvaluateSecurity(area), true + c = ctx() + } else { + v = capsule.EvaluateSecurityIn(area, c) + } + vc.Context = testkit.CMSVectorContext{ControlCommit: hex32(c.ControlCommit), HeadDigest: hex32(c.HeadDigest), RoundTime: c.RoundTime.UTC().Format(time.RFC3339)} + vc.Signature, vc.Seal = string(v.Signature), string(v.Seal) + if v.Signature != wantSig || v.Seal != wantSeal { + errs = append(errs, fmt.Errorf("%s: verdicts %s and %s, want %s and %s", name, v.Signature, v.Seal, wantSig, wantSeal)) + } + if d := v.Detail; d != nil { + vc.Signers, vc.Foreign = signerResults(d.Signers), signerResults(d.Foreign) + if !d.SealTime.IsZero() { + vc.SealHolder, vc.SealTime = d.SealHolder, d.SealTime.UTC().Format(time.RFC3339) + } + } + f.Cases = append(f.Cases, vc) + } + must := func(b []byte, err error) []byte { + if err != nil { + errs = append(errs, err) + } + return b + } + both := []cmstest.Signer{ana, luis} + + c := ctx() + add("alg 2: two signers, each sealed before the round time", must(cmsArea(c, both, both, tsa, vecSigned, nil)), c, capsule.VerdictSignedComplete, capsule.VerdictNoSeal) + add("alg 2: a seal after the round time proves nothing before it", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana}, tsa, vecRound.Add(time.Hour), nil)), c, capsule.VerdictSignedComplete, capsule.VerdictNoSeal) + add("alg 2: a signer who is not required shows apart", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana, otro}, tsa, vecSigned, nil)), c, capsule.VerdictSignedComplete, capsule.VerdictNoSeal) + add("alg 2: a required signer is absent", must(cmsArea(c, both, []cmstest.Signer{ana}, tsa, vecSigned, nil)), c, capsule.VerdictSignedIncomplete, capsule.VerdictNoSeal) + add("alg 2: no seal", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana}, cmstest.Signer{}, vecSigned, nil)), c, capsule.VerdictSignedIncomplete, capsule.VerdictNoSeal) + add("alg 2: a seal from before the certificate was valid", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana}, tsa, certFrom.AddDate(-1, 0, 0), nil)), c, capsule.VerdictSignedIncomplete, capsule.VerdictNoSeal) + add("alg 2: a key 3 beside it", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana}, tsa, vecSigned, must(capsule.EncodeSeal(1, []byte{1})))), c, capsule.VerdictSignedIncomplete, capsule.VerdictSealUnsupported) + other := ctx() + other.HeadDigest[5] ^= 9 + add("alg 2: another head", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana}, tsa, vecSigned, nil)), other, capsule.VerdictSignatureInvalid, capsule.VerdictNoSeal) + add("alg 2: without the context of a capsule", must(cmsArea(c, []cmstest.Signer{ana}, []cmstest.Signer{ana}, tsa, vecSigned, nil)), nil, capsule.VerdictSignatureUnchecked, capsule.VerdictNoSeal) + + one, two := sum256([]byte("a")), sum256([]byte("b")) + if bytes.Compare(one[:], two[:]) > 0 { + one, two = two, one + } + unsorted := append(append([]byte{0x82, 0x58, 0x20}, two[:]...), append([]byte{0x58, 0x20}, one[:]...)...) + for name, signers := range map[string][]byte{"alg 2: SIGNERS out of order": unsorted, "alg 2: an empty SIGNERS": {0x80}} { + content, _ := capsule.EncodeAuthorSignature(capsule.AlgCMS, signers, []byte{0x30, 0x00}) + add(name, must(capsule.EncodeSecurityWith(content, nil)), c, capsule.VerdictSignatureUnchecked, capsule.VerdictNoSeal) + } + { + list, _ := capsule.EncodeSigners([][32]byte{sum256(ana.Cert.Raw)}) + content, _ := capsule.EncodeAuthorSignature(capsule.AlgCMS, list, []byte("not DER")) + add("alg 2: not a CMS", must(capsule.EncodeSecurityWith(content, nil)), c, capsule.VerdictSignatureUnchecked, capsule.VerdictNoSeal) + } + + // Seals of seal_type 2 over an alg 1 signature. + msg := capsule.AuthorMessage(c.ControlCommit, c.HeadDigest, capsule.SignersDigest(capsule.AlgEd25519, nil)) + sig := must(capsule.EncodeAuthorSignature(capsule.AlgEd25519, key.Public(), key.Sign(msg))) + subject := capsule.SealSubject(c.ControlCommit, c.HeadDigest, capsule.SigPart(sig)) + sealed := func(token []byte) []byte { + return must(capsule.EncodeSecurityWith(sig, must(capsule.EncodeSeal(capsule.SealTypeRFC3161, token)))) + } + tok := func(subject []byte, when time.Time, o cmstest.TokenOptions, s cmstest.Signer) []byte { + return cmstest.Token(subject, when, o, s) + } + okSig := capsule.VerdictSignedOther + add("seal: before the round time", sealed(tok(subject[:], vecSigned, cmstest.TokenOptions{}, tsa)), c, okSig, capsule.VerdictSealed) + add("seal: after the round time", sealed(tok(subject[:], vecRound.Add(time.Minute), cmstest.TokenOptions{}, tsa)), c, okSig, capsule.VerdictSealedLate) + add("seal: the accuracy reaches the round time", sealed(tok(subject[:], vecRound.Add(-time.Second), cmstest.TokenOptions{Accuracy: 2 * time.Second}, tsa)), c, okSig, capsule.VerdictSealedLate) + add("seal: over another subject", sealed(tok([]byte("other"), vecSigned, cmstest.TokenOptions{}, tsa)), c, okSig, capsule.VerdictSealInvalid) + add("seal: the authority had expired at its time", sealed(tok(subject[:], certTo.AddDate(1, 0, 0), cmstest.TokenOptions{}, tsa)), c, okSig, capsule.VerdictSealInvalid) + add("seal: a TSTInfo of version 2", sealed(tok(subject[:], vecSigned, cmstest.TokenOptions{Version: 2}, tsa)), c, okSig, capsule.VerdictSealUnreadable) + add("seal: not DER", sealed([]byte("not DER")), c, okSig, capsule.VerdictSealUnreadable) + add("seal: SHA-384 in the imprint", sealed(tok(subject[:], vecSigned, cmstest.TokenOptions{Hash: crypto.SHA384}, tsa)), c, okSig, capsule.VerdictSealUnsupported) + add("seal: without a context, as a reader of v0.10", sealed(tok(subject[:], vecSigned, cmstest.TokenOptions{}, tsa)), nil, capsule.VerdictSignatureUnchecked, capsule.VerdictSealUnsupported) + noSig := capsule.SealSubject(c.ControlCommit, c.HeadDigest, capsule.SigPart(nil)) + add("seal: over a capsule without a signature", must(capsule.EncodeSecurityWith(nil, must(capsule.EncodeSeal(capsule.SealTypeRFC3161, tok(noSig[:], vecSigned, cmstest.TokenOptions{}, tsa))))), + c, capsule.VerdictNoSignature, capsule.VerdictSealed) + if err := errors.Join(errs...); err != nil { + return nil, err + } + return f, nil +} + +// locatorVectors makes the vector of the extension datekeys.capsule: a .dkc of +// patterned bytes in an envelope, hidden in a host, its locator sealed with +// tlock for round 1000, and the data of the extension with a note. +func locatorVectors() (any, error) { + p := profile.Quicknet() + dkc := patterned("locator dkc", 5000) + loc, rest, err := locator.NewEnvelope(dkc) + if err != nil { + return nil, err + } + host := patterned("host file", 3000) + file, offset := locator.Hide(host, rest) + const cid = "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi" + loc.Addresses = []locator.Address{{URI: "https://ejemplo.org/foto.jpg", Offset: offset}, {URI: "ipfs://" + cid}} + plain, err := loc.Marshal() + if err != nil { + return nil, err + } + const round = 1000 + sealed, err := locator.Seal(p, round, loc) + if err != nil { + return nil, err + } + dk, err := datekey.Resolve(p, mustRoundTime(p, round)) + if err != nil { + return nil, err + } + const note = "Cartas del viaje a Lisboa" + x, err := (&locator.Info{Note: note, DateKey: dk, Sealed: sealed}).Extension() + if err != nil { + return nil, err + } + if x.ID != extension.CapsuleID { + return nil, errors.New("not datekeys.capsule") + } + v := testkit.LocatorVectorFile{ + Spec: testkit.SpecVersion, + Description: "The extension datekeys.capsule of a .dkk and what it points to (spec v0.11, 44.1): an envelope of age with its header apart from its rest, " + + "the rest hidden in a host file, the locator sealed with tlock for round 1000, and the data of the extension. Frozen. See testdata/README.md.", + Round: round, DateKey: dk.Compact(), Note: note, DKC: hex.EncodeToString(dkc), Rest: hex.EncodeToString(rest), Header: hex.EncodeToString(loc.EnvelopeHeader), + Host: hex.EncodeToString(file), HostOffset: offset, Plaintext: hex.EncodeToString(plain), Sealed: hex.EncodeToString(sealed), Extension: hex.EncodeToString(x.Data), + EnvelopeKey: hex.EncodeToString(loc.EnvelopeKey[:]), RestDigest: hex32(loc.RestDigest), RestSize: loc.RestSize, CapsuleDigest: hex32(loc.CapsuleDigest), + } + for _, a := range loc.Addresses { + v.Addresses = append(v.Addresses, testkit.LocatorVectorAddress{URI: a.URI, Offset: a.Offset, Host: a.Host()}) + } + for _, base := range []int{100, 3000, 4000, 4060, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4090, 4094, 4095, 4096, 4097, 4100, 8160, 8190, 8192, 8193, 12000} { + v.PaddingCases = append(v.PaddingCases, testkit.LocatorPaddingCase{Base: base, Total: locator.PlaintextLength(base)}) + } + for _, c := range []struct { + uri string + ok bool + }{ + {"https://ejemplo.org/a.bin", true}, {"https://ejemplo.org:8443/x?y=1", true}, {"ipfs://" + cid, true}, {"ipfs://" + cid + "/ruta", true}, + {"", false}, {"http://ejemplo.org/a", false}, {"file:///etc/passwd", false}, {"ftp://x/y", false}, {"https://user:pass@ejemplo.org/", false}, + {"https://", false}, {"ipfs://notacid", false}, {"https://ejemplo.org/ñ", false}, {"https://ejemplo.org/a b", false}, + {"https://%D0%B0pple.com/x", false}, {"https://ejemplo.org%E2%80%AEtxt.exe/", false}, {"https://127.0.0.1/", false}, {"https://[::1]/", false}, + {"https://0x7f000001/", false}, {"https://a.com:99999999/", false}, {"https://a.com:0/", false}, {"https://xn--pple-43d.com/", true}, + } { + if (locator.CheckURI(c.uri) == nil) != c.ok { + return nil, fmt.Errorf("the address %q: accepted %v, want %v", c.uri, !c.ok, c.ok) + } + v.URICases = append(v.URICases, testkit.LocatorURICase{URI: c.uri, OK: c.ok}) + } + return v, nil +} + +func mustRoundTime(p *profile.Profile, round uint64) time.Time { + t, err := datekey.RoundTime(p, round) + if err != nil { + panic(err) + } + return t +} diff --git a/internal/testkit/genfixtures/format3.go b/internal/testkit/genfixtures/format3.go index a5e6f32..51d5d27 100644 --- a/internal/testkit/genfixtures/format3.go +++ b/internal/testkit/genfixtures/format3.go @@ -16,6 +16,7 @@ import ( "g.activething.com/go/DateKeys/capsule" "g.activething.com/go/DateKeys/codec" "g.activething.com/go/DateKeys/codec/bech32" + "g.activething.com/go/DateKeys/internal/cms" "g.activething.com/go/DateKeys/internal/testkit" ) @@ -163,50 +164,118 @@ func record3(f *testkit.DKCFixture, body []byte, verdicts *capsule.Verdicts) err if f.Signature != nil { f.Verdicts.AuthorKey = f.Signature.AuthorKey } - return nil + f.Seal, err = recordSeal(f, security, hb, v) + return err } -// recordSignature returns what the record of a fixture says about its -// signature of alg 1: the seed of its test key, which the generator wrote and -// this keeps, and the commitments and the message, which it computes from the -// control of the fixture, its head and its security (spec v0.11, §29.8). Nil -// when the fixture has no valid signature. -func recordSignature(f *testkit.DKCFixture, security, head []byte, v capsule.Verdicts) (*testkit.FixtureSignature, error) { - if v.Signature != capsule.VerdictSignedOther && v.Signature != capsule.VerdictSignedSaved { - return nil, nil - } - if f.Signature == nil { - return nil, errors.New("the fixture has a valid signature and its record no seed of the key") - } +// commitmentsOf returns control_commit and head_digest of the fixture f, from +// its control and its head (spec v0.11, §29.8). +func commitmentsOf(f *testkit.DKCFixture, head []byte) (cc, hd [32]byte, err error) { cb, err := hex.DecodeString(f.ControlCBOR) if err != nil { - return nil, err + return cc, hd, err } c, err := capsule.DecodeControl(cb, capsule.Format(f.Format)) if err != nil { - return nil, err + return cc, hd, err } defer clear(c.PayloadIdentity[:]) - cc, err := capsule.ControlCommit(c, capsule.Format(f.Format)) + if cc, err = capsule.ControlCommit(c, capsule.Format(f.Format)); err != nil { + return cc, hd, err + } + return cc, capsule.HeadDigest(head), nil +} + +func signerResults(lines []capsule.SignerLine) []testkit.FixtureSignerResult { + var out []testkit.FixtureSignerResult + for _, l := range lines { + r := testkit.FixtureSignerResult{Holder: l.Holder, Issuer: l.Issuer, Result: l.Result, Before: l.Before} + if !l.SealTime.IsZero() { + r.SealTime = l.SealTime.UTC().Format(time.RFC3339) + } + out = append(out, r) + } + return out +} + +// recordSignature returns what the record of a fixture says about its +// signature: with alg 1, the seed of its test key, which the generator wrote +// and this keeps, and the commitments and the message, which it computes from +// the control of the fixture, its head and its security (spec v0.11, §29.8); +// with alg 2, the same without a seed, and the certificates, SIGNERS and the +// result of each signer that Open gave. Nil when the fixture has no valid +// signature of alg 1 and no signature of alg 2 that Open judged. +func recordSignature(f *testkit.DKCFixture, security, head []byte, v capsule.Verdicts) (*testkit.FixtureSignature, error) { + content, value, err := capsule.SecurityKey2(security) + if err != nil { + return nil, nil // no signature + } + alg, key, _, err := capsule.DecodeAuthorSignature(content) + if err != nil { + return nil, nil + } + switch { + case alg == capsule.AlgEd25519 && (v.Signature == capsule.VerdictSignedOther || v.Signature == capsule.VerdictSignedSaved): + if f.Signature == nil { + return nil, errors.New("the fixture has a valid signature and its record no seed of the key") + } + case alg == capsule.AlgCMS && v.Detail != nil: + default: + return nil, nil + } + cc, hd, err := commitmentsOf(f, head) if err != nil { return nil, err } - hd := capsule.HeadDigest(head) - sd := capsule.SignersDigest(capsule.AlgEd25519, nil) + var sd [32]byte + sig := &testkit.FixtureSignature{Alg: int(alg), SignatureValue: hex.EncodeToString(value), SecurityKey2: hex.EncodeToString(content)} + if alg == capsule.AlgEd25519 { + sd = capsule.SignersDigest(capsule.AlgEd25519, nil) + sig.SecretSeed = f.Signature.SecretSeed + if sig.AuthorKey, err = bech32.Encode("dkauthor", v.AuthorKey[:]); err != nil { + return nil, err + } + } else { + sd = capsule.SignersDigest(capsule.AlgCMS, key) + sig.Signers = hex.EncodeToString(key) + parsed, err := cms.ParseSignature(value) + if err != nil { + return nil, err + } + for _, c := range parsed.Certs { + sig.Certificates = append(sig.Certificates, hex.EncodeToString(c.Raw)) + } + sig.Results, sig.Foreign = signerResults(v.Detail.Signers), signerResults(v.Detail.Foreign) + } msg := capsule.AuthorMessage(cc, hd, sd) - content, value, err := capsule.SecurityKey2(security) + sig.ControlCommit, sig.HeadDigest, sig.SignersDigest = hex.EncodeToString(cc[:]), hex.EncodeToString(hd[:]), hex.EncodeToString(sd[:]) + sig.AuthorMessage, sig.AuthorCode = string(msg), capsule.AuthorCode(msg) + return sig, nil +} + +// recordSeal returns what the record of a fixture says about its seal of +// seal_type 2 when Open found it valid (S4 or S5): SEAL_SUBJECT, the token +// and the authority and the time that the verdict names. +func recordSeal(f *testkit.DKCFixture, security, head []byte, v capsule.Verdicts) (*testkit.FixtureSeal, error) { + if (v.Seal != capsule.VerdictSealed && v.Seal != capsule.VerdictSealedLate) || v.Detail == nil { + return nil, nil + } + typ, token, err := capsule.SecurityKey3(security) if err != nil { return nil, err } - key, err := bech32.Encode("dkauthor", v.AuthorKey[:]) + cc, hd, err := commitmentsOf(f, head) if err != nil { return nil, err } - return &testkit.FixtureSignature{ - Alg: capsule.AlgEd25519, SecretSeed: f.Signature.SecretSeed, AuthorKey: key, - ControlCommit: hex.EncodeToString(cc[:]), HeadDigest: hex.EncodeToString(hd[:]), SignersDigest: hex.EncodeToString(sd[:]), - AuthorMessage: string(msg), AuthorCode: capsule.AuthorCode(msg), - SignatureValue: hex.EncodeToString(value), SecurityKey2: hex.EncodeToString(content), + var part []byte + if content, _, err := capsule.SecurityKey2(security); err == nil { + part = content + } + subject := capsule.SealSubject(cc, hd, capsule.SigPart(part)) + return &testkit.FixtureSeal{ + SealType: int(typ), SealSubject: hex.EncodeToString(subject[:]), Token: hex.EncodeToString(token), + Holder: v.Detail.SealHolder, Time: v.Detail.SealTime.UTC().Format(time.RFC3339), }, nil } diff --git a/internal/testkit/genfixtures/main.go b/internal/testkit/genfixtures/main.go index 6cfd4f7..7c7699a 100644 --- a/internal/testkit/genfixtures/main.go +++ b/internal/testkit/genfixtures/main.go @@ -188,7 +188,7 @@ func format3Vectors(dir string) error { return err } } - return nil + return frozenVectors(dir) } // mutationsName is the -only name that rebuilds the capsules of the @@ -372,7 +372,10 @@ type spec struct { // signer, when not nil, is the 32-byte seed of the author key that signs // a format 3 fixture written by EncryptFiles (spec v0.11, §29.9). signer []byte - body func() ([]byte, error) + // configure, when not nil, sets what only this fixture needs in the + // options of EncryptFiles: a signer with certificates, or a sealer. + configure func(o *capsule.EncryptOptions) error + body func() ([]byte, error) } // Extension data of the fixtures (spec §54, §72): the header carries the raw @@ -482,6 +485,8 @@ func specs() []spec { return body3(capsule.AreaUnit, s, "", "", note) }}, {name: "format3_signed", format: f3, description: "format 3 time_only capsule with a single file, nota.txt, signed with alg 1 by a test key whose seed the record gives: verdict F4, and the commitments and the message of the signature", round: 1000, policy: capsule.TimeOnly, padding: capsule.Reforzado, files: note, signer: signerSeed}, + {name: "format3_signed_cms", format: f3, description: "format 3 time_only capsule with a single file, nota.txt, signed with alg 2 by two test certificates, an ECDSA P-256 one and an RSA 2048 one, each sealed by a test time-stamping authority before the round time: verdict F6, with the certificates, the commitments, SIGNERS and the result of each signer in the record", round: 1000, policy: capsule.TimeOnly, padding: capsule.Reforzado, files: note, configure: configureCMS}, + {name: "format3_sealed", format: f3, description: "format 3 time_only capsule with a single file, nota.txt, signed with alg 1 by the test key of format3_signed and sealed with seal_type 2 by a test time-stamping authority before the round time: verdicts F4 and S4, with SEAL_SUBJECT and the token in the record", round: 1000, policy: capsule.TimeOnly, padding: capsule.Reforzado, files: note, signer: signerSeed, configure: configureSeal}, } } @@ -629,6 +634,11 @@ func write(s spec) (*written, error) { var res *capsule.Result if s.format == capsule.Format3 { opts.Comment, opts.Author = s.comment, s.author + if s.configure != nil { + if err := s.configure(&opts); err != nil { + return nil, err + } + } if s.signer != nil { k, err := authorkey.NewFromSeed(s.signer) if err != nil { diff --git a/locator/locator.go b/locator/locator.go index 2e9881d..665ab27 100644 --- a/locator/locator.go +++ b/locator/locator.go @@ -441,6 +441,17 @@ func padFor(n0 int) int { } } +// PlaintextLength returns the length of the plaintext of a locator whose CBOR +// without key 6 measures base bytes: base when it already is a multiple of +// Block, and otherwise the least multiple that key 6 can fill exactly. +func PlaintextLength(base int) int { + pad := padFor(base) + if pad < 0 { + return base + } + return base + 1 + bstrHeadLen(pad) + pad +} + // Marshal returns the plaintext of the locator: CBOR with the profile of // spec §58, completed with zeros in key 6 up to the least multiple of 4096 // bytes that holds it, so that its length does not tell how many addresses diff --git a/locator/vectors_test.go b/locator/vectors_test.go new file mode 100644 index 0000000..5d34701 --- /dev/null +++ b/locator/vectors_test.go @@ -0,0 +1,76 @@ +package locator_test + +import ( + "bytes" + "encoding/hex" + "path/filepath" + "testing" + + "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 +// of the addresses and of the padding give what the file says (spec v0.11, +// §44.1). +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) + } + } +} diff --git a/testdata/README.md b/testdata/README.md index 9d793a7..bf27b4c 100644 --- a/testdata/README.md +++ b/testdata/README.md @@ -73,7 +73,7 @@ extension and a noncritical CONTROL_CBOR extension. The release that opens each capsule, a published Quicknet signature, is in its `.json`, so they all decrypt offline. -Nine are in format 3. Their plaintext file is BODY, L bytes: the frame, the +Twelve are in format 3. Their plaintext file is BODY, L bytes: the frame, the security area, the head and the files (spec §29.2). | Fixture | Policy | Files | Comment | L | Padding code | P | Area | Verdicts | @@ -87,14 +87,45 @@ security area, the head and the files (spec §29.2). | `format3_security_v2` | `time_only` | 1 | — | 659 | 2 | 768 | 512 | X | | `format3_signature_unsupported` | `time_only` | 1 | — | 659 | 2 | 768 | 512 | F1, S0 | | `format3_seal_unsupported` | `time_only` | 1 | — | 659 | 2 | 768 | 512 | F1, S1 | +| `format3_signed` | `time_only` | 1, `nota.txt`, with mtime | — | 32915 | 2 | 34816 | 32768 | F4, S0 | +| `format3_signed_cms` | `time_only` | 1, `nota.txt`, with mtime | — | 32915 | 2 | 34816 | 32768 | F6, S0 | +| `format3_sealed` | `time_only` | 1, `nota.txt`, with mtime | — | 32915 | 2 | 34816 | 32768 | F4, S4 | -The first five are what `capsule.EncryptFiles` writes. The other four only a +The first five were written by a writer of v0.10, with the area of 512 bytes; +a writer of v0.11 writes the area of 32768 bytes, as in the last three, which +`capsule.EncryptFiles` writes with a signer and a sealer. The next four only a generator of test vectors may write (spec §62.1 rule 13): an area larger than -the 512 bytes of this version, which a reader accepts, a security map of -version 2, which a reader of this version cannot read, an author signature of -`alg` 1 with a random key of 32 bytes and a random signature of 64, and that +512 bytes, a security map of version 2, which a reader of this version cannot +read, an author signature of `alg` 4294967295, an `alg` that no version +defines, with a random key of 32 bytes and a random signature of 64, and that with a seal of `seal_type` 1 and a random token of 32 bytes. None of them has -a verdict that stops the opening. The BODY of `format3_tree` is over two STREAM +a verdict that stops the opening. + +The last three are signed and sealed with test keys (spec v0.11, §29.8 to +§29.11), and their record has a `signature` object, and `seal` in the third: + +- `format3_signed`: `alg` 1. The seed of the test key, which is not a secret, + is in `secret_seed`: Ed25519 is deterministic, so signing `author_message` + with it gives `signature` again. Opening it gives F4 and the key `author_key`, + `dkauthor1…`; with that key among the saved ones, F3. +- `format3_signed_cms`: `alg` 2, two certificates, an ECDSA P-256 one and an + RSA 2048 one, each with a seal CAdES-T from a test authority, dated before + the round time. The record has `signers` (SIGNERS in hexadecimal), + `certificates` (the DER of each), `signature` (the DER of the CMS signature) + and `signer_results`, one for each required signer in the order of SIGNERS: + holder, issuer that the certificate says, result, seal time, and whether the + seal, with its accuracy, precedes the round time. The private keys are not + kept: ECDSA and RSA-PSS are not deterministic, and a reader only verifies. +- `format3_sealed`: `alg` 1 as the first, and a seal of `seal_type` 2 over + `SEAL_SUBJECT`. The record has `seal`: `seal_subject`, the `token` in + hexadecimal, the `holder` of the authority as §29.7 shows it, and the time. + +In the three, the record gives the commitments `control_commit`, `head_digest` +and `signers_digest`, the text `author_message` and its `author_code`, and the +exact content of key 2 of `SECURITY_CBOR`. An implementation checks them from +the control, the head and the security area of the fixture, and the verdicts +from `verdicts`. The certificates and the tokens are random, so these fixtures +are frozen once written like the others. The BODY of `format3_tree` is over two STREAM chunks, with its head in the first. ## Edited files @@ -381,6 +412,58 @@ signature and the seal are evaluated apart, and the first row of the table of give F1 with the seal intact, and a seal that breaks its schema gives S2 even with an unknown `seal_type`, which is read only from a seal that meets it. +## `vectors/security_cms.json` + +Security areas with an author signature of `alg` 2, a CMS signature with +certificates, or a time seal of `seal_type` 2, an RFC 3161 token, each with +the context of its capsule and the verdicts of spec v0.11 §29.7, §29.10 and +§29.11. They complete `security.json`, whose areas have no valid signature or +seal. The file is frozen: the certificates and the tokens are made once, with +test keys, so a second implementation reads them and must reach the same +verdicts. Delete the file to make it again. + +```json +{ "name": "alg 2: a required signer is absent", "security_cbor": "a4…", + "context": { "control_commit": "…", "head_digest": "…", "round_time": "2030-01-01T00:00:00Z" }, + "signature": "F5", "seal": "S0", "signers": [ { "holder": "Ana López", "result": "valid", … }, { "holder": "", "result": "absent", … } ] } +``` + +`context` is what a verdict needs besides `SECURITY_CBOR`; with `no_context` +the area is read as a reader of v0.10 does, without a capsule, and any +signature is F1 and any seal S1. `signers` are the results of the required +signers in the order of SIGNERS, and `foreign_signers` those that are not +required and never count. A valid seal gives `seal_holder` and `seal_time`. +The cases cover F6 with two signers, with a seal after the round time and +with a signer who is not required; F5 for an absent signer, no seal, a seal +from before the certificate was valid and a key 3 beside the signature; F2 in +the context of another head; F1 for SIGNERS out of order or empty, a signature +that is not a CMS, and the lack of a context; and, over an `alg` 1 signature, +the seals S4, S5 (also when the accuracy reaches the round time), S3 (another +subject, an authority expired at its time), S2 (a TSTInfo of version 2, not +DER), S1 (a SHA-384 imprint) and a seal over a capsule without a signature. + +## `vectors/locator.json` + +The extension `datekeys.capsule` of a `.dkk` and what it points to (spec +v0.11, §44.1): a `.dkc` of patterned bytes in an envelope of age whose header +(`envelope_header`) goes in the locator and whose `rest`, without a mark, is +hidden in a `host` file at `host_offset`; the locator sealed with tlock for +round 1000 (`locator_sealed`), with its plaintext of 4096 bytes +(`locator_plaintext`) and its fields; and the data of the extension +(`extension_data`), with the note `note` and the DateKey `datekey`. A reader +opens the locator with the release of round 1000 (`quicknet_rounds.json`), +finds the rest in the host, checks `rest_size`, `rest_digest` and +`capsule_digest`, and gets the `.dkc` back. The file is frozen: the envelope +and the locator hold randomness. + +`padding_cases` give the length of the plaintext of the locator for the length +of its CBOR without the padding of key 6: the least multiple of 4096 that key 6 +can fill exactly, which skips a multiple where the CBOR length of key 6 jumps +(a base of 4070 gives 8192). `uri_cases` give the verdict of the rules of §44.1 +on an address: the scheme `https` or `ipfs`, the raw ASCII authority with no +percent sign or userinfo, a host of letters, digits and hyphens or a public IP +literal, and a port from 1 to 65535. + ## `vectors/ed25519_strict.json` Ed25519 signatures, in hexadecimal, and whether the strict profile of the diff --git a/testdata/fixtures/format3_sealed.dkc b/testdata/fixtures/format3_sealed.dkc new file mode 100644 index 0000000..7d3f26a Binary files /dev/null and b/testdata/fixtures/format3_sealed.dkc differ diff --git a/testdata/fixtures/format3_sealed.inspect.json b/testdata/fixtures/format3_sealed.inspect.json new file mode 100644 index 0000000..b20ea4d --- /dev/null +++ b/testdata/fixtures/format3_sealed.inspect.json @@ -0,0 +1,61 @@ +{ + "file": "format3_sealed.dkc", + "format": 3, + "capsule_id": "b3d25bb6c74cda4e014c65e3d2f43a69", + "datekey": "dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0", + "profile": "datekeys:quicknet:v1", + "round": 1000, + "unlock_at": "2023-08-23T15:59:24Z", + "access_policy": "time_only", + "valid": true, + "checks": [ + { + "step": 1, + "name": "parse DKC1", + "ok": true, + "detail": "magic DKC1" + }, + { + "step": 2, + "name": "prelude", + "ok": true, + "detail": "DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458" + }, + { + "step": 3, + "name": "public header", + "ok": true, + "detail": "121 bytes" + }, + { + "step": 4, + "name": "header validation", + "ok": true, + "detail": "capsule_id=b3d25bb6c74cda4e014c65e3d2f43a69 datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1" + }, + { + "step": 5, + "name": "sealed control structure", + "ok": true, + "detail": "one tlock stanza" + }, + { + "step": 6, + "name": "payload structure", + "ok": true, + "detail": "one X25519 stanza" + }, + { + "step": 7, + "name": "condition", + "ok": true, + "detail": "round 1000, unlock at 2023-08-23T15:59:24Z" + }, + { + "step": 8, + "name": "tlock stanza", + "ok": true, + "detail": "round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971" + } + ] +} diff --git a/testdata/fixtures/format3_sealed.json b/testdata/fixtures/format3_sealed.json new file mode 100644 index 0000000..50a3d5f --- /dev/null +++ b/testdata/fixtures/format3_sealed.json @@ -0,0 +1,173 @@ +{ + "description": "format 3 time_only capsule with a single file, nota.txt, signed with alg 1 by the test key of format3_signed and sealed with seal_type 2 by a test time-stamping authority before the round time: verdicts F4 and S4, with SEAL_SUBJECT and the token in the record", + "spec": "0.10", + "format": 3, + "file": "format3_sealed.dkc", + "sha256": "dde5a072d8783227d28279d06d3d226a1fb967c766da626f889d1c6fd76ac9c7", + "release": { + "round": 1000, + "signature": "b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39" + }, + "prelude": "444b43310300000000000079000001ca", + "public_header": "a5006a646174656b657963617001010250b3d25bb6c74cda4e014c65e3d2f43a69037853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d48300400", + "datekey": "dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0", + "capsule_id": "b3d25bb6c74cda4e014c65e3d2f43a69", + "access_policy": "time_only", + "structure": "time_only", + "unlock_at": "2023-08-23T15:59:24Z", + "header_binding": "c108d8b34eb0a4237e6aff192364a28d544cb79c84ac5c80d88c26f8bd5560d8", + "outer_stanzas": [ + { + "type": "tlock", + "args": [ + "1000", + "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971" + ] + } + ], + "payload_stanzas": [ + { + "type": "X25519", + "args": [ + "PQPwIpsXx8ZNHf1Xpr7gnPamVYWLPgD8zIGmXqvSkjY" + ] + } + ], + "control_cbor": "a60070646174656b6579732d636f6e74726f6c0103025820c108d8b34eb0a4237e6aff192364a28d544cb79c84ac5c80d88c26f8bd5560d803582087351091f87f94f2c1155e5bde726116123e321f6cc2c3f2bb934298e0d02ea8064800000000000080930702", + "payload_identity": "87351091f87f94f2c1155e5bde726116123e321f6cc2c3f2bb934298e0d02ea8", + "payload_length": 32915, + "padding": 2, + "padded_length": 34816, + "plaintext_file": "format3_sealed.plaintext", + "plaintext_sha256": "aea0f5feb40acd81ca3b02dd21ea15510234da3ab52b374322f3206e7632d47b", + "area_len": 32768, + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a3000101582092d3a82b1e2387a860d57cae4cc55091d43904fdd625e4d2b285e3a1b4ba674002584024c8a0fd4ef7338a2607c1489e33eb32b2d2c6a9438e8d01d5beb04911acd5bdf7eb4bd958141293e5fe4074276097cd0df21d8ca12b9c2e6cb5164304666c060359038ba20002015903843082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104201ce5a87549e8bed1af2238888c5a4e942b3b3de1fa8d757c70941cd21522638d02012a180f32303233303832333135303932375a3003020101a08201b8308201b430820159a0030201020208074ecca73c287e79300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d03010703420004aa2eb21e68c810b6271dadcc25575401ceccac2461de40cb2bfde25bceaa384abbbba098880bf14316b62769b3596d701d60c8dd1f1313f257d93c4d5f213a53a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100a05f22801b8432108d6330dd777a25bcfdd1b32db72bc8feb9be522291559e11022100cfd71b1445e68079aa98af90ac7037ab938eb7e4f11279f1476a93ce0b693aff3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562610208074ecca73c287e79300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a30183016041426e0465376bf0d652c266e5940c9d01ba8cea5e9302f06092a864886f70d01090431220420545889d11d3289646f8156538dbcc608e8cc543fa052056a56a85eb7356523f1300a06082a8648ce3d04030204473045022100883cfcc51038245652e767fdfecea1b7153b9158df02d95f3fcfc2b58e575cb1022029b9727ead61a3022bcddd62d704ee26f71de738556d97796de3ce1c408c7419", + "head_cbor": "a4006d646174656b6579732d686561640101025820990d6781941d508558b06652f4c4db8fc56da5a443811b723adfe4370ea139710581a600686e6f74612e7478740116020003160458205d596d5f49c179f0ec337f4610155fc237e727f9dee85377a5fce67a3c853510051a6abcf9c0", + "salt": "990d6781941d508558b06652f4c4db8fc56da5a443811b723adfe4370ea13971", + "content_offset": 32893, + "files": [ + { + "path": "nota.txt", + "size": 22, + "start": 0, + "end": 22, + "sha256": "5d596d5f49c179f0ec337f4610155fc237e727f9dee85377a5fce67a3c853510", + "mtime": 1790769600 + } + ], + "verdicts": { + "signature": "F4", + "seal": "S4", + "lines": [ + "Firmado con la clave dkauthor1jtf6s2c7ywr6scx40jhye32sj82rjp8a6cj7f54jsh36rd96vaqqcg54xg. No prueba quién la tiene.", + "Según un sello a nombre de Autoridad de Sellado de prueba, existía el 2023-08-23T15:09:27Z, antes de que la cápsula pudiera abrirse. DateKeys no comprueba quién emitió el sello." + ], + "author_key": "dkauthor1jtf6s2c7ywr6scx40jhye32sj82rjp8a6cj7f54jsh36rd96vaqqcg54xg" + }, + "signature": { + "alg": 1, + "secret_seed": "294b60d256e79fc4c18b4bcc0a156810b44144619969dadedcbf01d3b37c1054", + "author_key": "dkauthor1jtf6s2c7ywr6scx40jhye32sj82rjp8a6cj7f54jsh36rd96vaqqcg54xg", + "control_commit": "1793cc0adaba31bdbf18cb4c97ba86dcff05bec498c8ecf11668a74bfd71718a", + "head_digest": "a5537946c281a8e22ca9d3a4deb1aebcddf0d299abe47bded31c90157dd72d3a", + "signers_digest": "1665c6f3f1afb37b1a87d87e4265f156d7108c3c1762972d2a4241e6e5ab824e", + "author_message": "datekeys:dkc3:author-signature:v1\n111b174e204e0eaa73b87601e1e1d9b3d60799b5a0a5c0e371a9dc65d1d39f38\n", + "author_code": "111b-174e", + "signature": "24c8a0fd4ef7338a2607c1489e33eb32b2d2c6a9438e8d01d5beb04911acd5bdf7eb4bd958141293e5fe4074276097cd0df21d8ca12b9c2e6cb5164304666c06", + "security_key_2": "a3000101582092d3a82b1e2387a860d57cae4cc55091d43904fdd625e4d2b285e3a1b4ba674002584024c8a0fd4ef7338a2607c1489e33eb32b2d2c6a9438e8d01d5beb04911acd5bdf7eb4bd958141293e5fe4074276097cd0df21d8ca12b9c2e6cb5164304666c06" + }, + "seal": { + "seal_type": 2, + "seal_subject": "8e60fd12a9475d95f77adacf81772774f4a8f508ffc7edda2e15df9ccebf163e", + "token": "3082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104201ce5a87549e8bed1af2238888c5a4e942b3b3de1fa8d757c70941cd21522638d02012a180f32303233303832333135303932375a3003020101a08201b8308201b430820159a0030201020208074ecca73c287e79300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d03010703420004aa2eb21e68c810b6271dadcc25575401ceccac2461de40cb2bfde25bceaa384abbbba098880bf14316b62769b3596d701d60c8dd1f1313f257d93c4d5f213a53a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100a05f22801b8432108d6330dd777a25bcfdd1b32db72bc8feb9be522291559e11022100cfd71b1445e68079aa98af90ac7037ab938eb7e4f11279f1476a93ce0b693aff3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562610208074ecca73c287e79300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a30183016041426e0465376bf0d652c266e5940c9d01ba8cea5e9302f06092a864886f70d01090431220420545889d11d3289646f8156538dbcc608e8cc543fa052056a56a85eb7356523f1300a06082a8648ce3d04030204473045022100883cfcc51038245652e767fdfecea1b7153b9158df02d95f3fcfc2b58e575cb1022029b9727ead61a3022bcddd62d704ee26f71de738556d97796de3ce1c408c7419", + "holder": "Autoridad de Sellado de prueba", + "time": "2023-08-23T15:09:27Z" + }, + "stages": [ + { + "step": 1, + "name": "parse DKC1", + "ok": true + }, + { + "step": 2, + "name": "prelude", + "ok": true + }, + { + "step": 3, + "name": "public header", + "ok": true + }, + { + "step": 4, + "name": "header validation", + "ok": true + }, + { + "step": 5, + "name": "sealed control structure", + "ok": true + }, + { + "step": 6, + "name": "payload structure", + "ok": true + }, + { + "step": 7, + "name": "condition", + "ok": true + }, + { + "step": 8, + "name": "tlock stanza", + "ok": true + }, + { + "step": 9, + "name": "release", + "ok": true + }, + { + "step": 10, + "name": "release verification", + "ok": true + }, + { + "step": 11, + "name": "open sealed control", + "ok": true + }, + { + "step": 12, + "name": "policy structure", + "ok": true + }, + { + "step": 14, + "name": "control", + "ok": true + }, + { + "step": 15, + "name": "header binding", + "ok": true + }, + { + "step": 16, + "name": "payload identity", + "ok": true + }, + { + "step": 17, + "name": "open payload", + "ok": true + }, + { + "step": 18, + "name": "commit", + "ok": true + } + ] +} diff --git a/testdata/fixtures/format3_sealed.plaintext b/testdata/fixtures/format3_sealed.plaintext new file mode 100644 index 0000000..8f5ebf0 Binary files /dev/null and b/testdata/fixtures/format3_sealed.plaintext differ diff --git a/testdata/fixtures/format3_signed_cms.dkc b/testdata/fixtures/format3_signed_cms.dkc new file mode 100644 index 0000000..551b473 Binary files /dev/null and b/testdata/fixtures/format3_signed_cms.dkc differ diff --git a/testdata/fixtures/format3_signed_cms.inspect.json b/testdata/fixtures/format3_signed_cms.inspect.json new file mode 100644 index 0000000..632cda7 --- /dev/null +++ b/testdata/fixtures/format3_signed_cms.inspect.json @@ -0,0 +1,61 @@ +{ + "file": "format3_signed_cms.dkc", + "format": 3, + "capsule_id": "fb1b4917149f996c9c9561997593d37d", + "datekey": "dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0", + "profile": "datekeys:quicknet:v1", + "round": 1000, + "unlock_at": "2023-08-23T15:59:24Z", + "access_policy": "time_only", + "valid": true, + "checks": [ + { + "step": 1, + "name": "parse DKC1", + "ok": true, + "detail": "magic DKC1" + }, + { + "step": 2, + "name": "prelude", + "ok": true, + "detail": "DKC1 v3, PUBLIC_HEADER_LEN=121, SEALED_CONTROL_LEN=458" + }, + { + "step": 3, + "name": "public header", + "ok": true, + "detail": "121 bytes" + }, + { + "step": 4, + "name": "header validation", + "ok": true, + "detail": "capsule_id=fb1b4917149f996c9c9561997593d37d datekey=dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0 policy=time_only profile=datekeys:quicknet:v1" + }, + { + "step": 5, + "name": "sealed control structure", + "ok": true, + "detail": "one tlock stanza" + }, + { + "step": 6, + "name": "payload structure", + "ok": true, + "detail": "one X25519 stanza" + }, + { + "step": 7, + "name": "condition", + "ok": true, + "detail": "round 1000, unlock at 2023-08-23T15:59:24Z" + }, + { + "step": 8, + "name": "tlock stanza", + "ok": true, + "detail": "round 1000, chain 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971" + } + ] +} diff --git a/testdata/fixtures/format3_signed_cms.json b/testdata/fixtures/format3_signed_cms.json new file mode 100644 index 0000000..085d773 --- /dev/null +++ b/testdata/fixtures/format3_signed_cms.json @@ -0,0 +1,185 @@ +{ + "description": "format 3 time_only capsule with a single file, nota.txt, signed with alg 2 by two test certificates, an ECDSA P-256 one and an RSA 2048 one, each sealed by a test time-stamping authority before the round time: verdict F6, with the certificates, the commitments, SIGNERS and the result of each signer in the record", + "spec": "0.10", + "format": 3, + "file": "format3_signed_cms.dkc", + "sha256": "d658f8d5ac2c5550c07b8f8fd6883b2f6dc02ceafc47d436ea02d8950b2548d2", + "release": { + "round": 1000, + "signature": "b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39" + }, + "prelude": "444b43310300000000000079000001ca", + "public_header": "a5006a646174656b657963617001010250fb1b4917149f996c9c9561997593d37d037853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d48300400", + "datekey": "dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0", + "capsule_id": "fb1b4917149f996c9c9561997593d37d", + "access_policy": "time_only", + "structure": "time_only", + "unlock_at": "2023-08-23T15:59:24Z", + "header_binding": "2e91168b24ae6fa37bbf6c4514b30cb5961779fb50e5a6cd49622969b9d291e5", + "outer_stanzas": [ + { + "type": "tlock", + "args": [ + "1000", + "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971" + ] + } + ], + "payload_stanzas": [ + { + "type": "X25519", + "args": [ + "NRzdmZvmKaB9wip9mMxWA1L384Kl1kIsoEO7eAgBVAg" + ] + } + ], + "control_cbor": "a60070646174656b6579732d636f6e74726f6c01030258202e91168b24ae6fa37bbf6c4514b30cb5961779fb50e5a6cd49622969b9d291e50358208d26d67eb6ffa0d2aed0a32ecfbddd6e48ab6f2b6e73dc36cff0a74a36f87e82064800000000000080930702", + "payload_identity": "8d26d67eb6ffa0d2aed0a32ecfbddd6e48ab6f2b6e73dc36cff0a74a36f87e82", + "payload_length": 32915, + "padding": 2, + "padded_length": 34816, + "plaintext_file": "format3_signed_cms.plaintext", + "plaintext_sha256": "31c35eeeee856277b605fe44203a8f4786bb8f591eda3b6ee58252df5b3cf2f0", + "area_len": 32768, + "security_cbor": "a30071646174656b6579732d7365637572697479010102590f5aa300020158458258204692ef5fb3ea8320c1cdce7bbdd31003aed069bb04cc1a5cde9b15625dbd4fc35820aa2c7e3a8cfa6a6ec5374a1bf0d427bd9e833352e825984298190fa96b543cfb02590f0b30820f0706092a864886f70d010702a0820ef830820ef4020101310d300b0609608648016503040201300b06092a864886f70d010701a0820483308201763082011da003020102020801cafe20c83b2715300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d03010703420004b2103f0f0a2654afa291a4a435f2bfff8ed018e1c6892281ae497bd9aa2686dbc9fd7254c94f2ef6701d1a2777613878a053c827e6ae105f9d8b1145af7753eca3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d040302034700304402206de47fe26d900dae4860e57d29af0c9e3aba7421aebc91219e2e5697071092e6022020e6fad2707773e75a7c747ffeb2704f12db27898ccf75a5483f0a87c5fffda930820305308201eda0030201020207277dda070cc49c300d06092a864886f70d01010b0500302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a301e170d3230303130313030303030305a170d3430303130313030303030305a302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a30820122300d06092a864886f70d01010105000382010f003082010a0282010100b3316a351ac48d907aae9631ebc67182edab8c7f2f23a30d503060148fc475eba1e2d9cee063638849dc234e271bde03c28ef8afe53082abd4728aa74ad46aa220304a291058c20ec982bec051fa211243999dde73797e209ee554fcef9d03deab323fa39067883bcdd2c45f563a746ba954536d97b0f2fc5e108ebc293a94dfd566529d01b23096326a31e92199418490c4f76943a08fafa5069406a298db95d88c2f1678573d109ddd72af723dcdc5ae2df62cb09002e30b286256ae7bc1c8690e03dcea5936829f5a549e7ac090bb54602c82637414d71d60818b1f15f54144718e9384fe12c692d709f560d90bf7f090b344a0e13c24ccf32a6f13bd804d0203010001a3283026300e0603551d0f0101ff04040302078030140603551d0e040d040b4c7569732047c3b36d657a300d06092a864886f70d01010b050003820101008259b9cabd6f8e59d97bbbc3456f4d325d2dc37ae42feca2e46bb6b21140a59b823b3192b87f59c9f63c17dcce2192aa5682e37183cb47325e5e7f5bcbc9000b083177f0ba29b6735830f22bab56a872f126a41afde0d50952c3cd39d935751b260eef0368f23209e55a26beb5f93af3782637cf4a1d683eb942fbc008f1ccc339566e761a3269b9fe8277f970736699141caa5c3382020c9efc53fe798ed303f7bd97ad4fc41ec941489f7efa474afb89281178fa94c43ca4a3398edad9cc113c9206a503195922fae3505899206434f89186ee1f9314dd5454e96163ece8f358dc1a07482cd81ce02ec5b778c8e612458a2e540b1cfd90a1965c51c3b75e4a31820a4a308204c20201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a020801cafe20c83b2715300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e875ea68e624cbb640b846729f3693dc54ae38de3e7fb0e10a8a5a879fe2df783037060b2a864886f70d010910022f31283026302430220420aa2c7e3a8cfa6a6ec5374a1bf0d427bd9e833352e825984298190fa96b543cfb300a06082a8648ce3d0403020447304502206225e91f9358d8605076090d4f274400ea4563cf31d998ed23ff42f731927d65022100fac4c2ec5a8d50c24aa0b426fd15a833a70b55d95bc373d8352383c2f06b5826a182039730820393060b2a864886f70d010910020e318203823082037e06092a864886f70d010702a082036f3082036b020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420c86ee56a958ac3033f9df8c204eadd19324a66bd8d00aaf069b872c4e204293d02012a180f32303233303832333135303932375a3003020101a08201b7308201b330820159a003020102020820fea3aef45f161b300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200041abc8a59e7def8a3cff4c99a08c30f7028c3af6b389cec3632cb34db5f206ad8a3931bb2c886e536e01efee7ad5817b029ddc29863228531735da0da9ddc2572a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020348003045022100b1a985b9b6c2831f174648a19b4900cd0bb3fcd3f67cc04b2494131d6a00426502204577ebcd3b8a14c252ef528b2e77b20369507753ba5ca543253dd9fed3238ce2318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020820fea3aef45f161b300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a3018301604141e1ab18975babe77d30e68003c717b89935b9dfe302f06092a864886f70d01090431220420ae2f3d372b417904643ba5da53b50e5eb317c274794d31bae41428a064c20866300a06082a8648ce3d0403020446304402204174c537862c0d25e8ff825d41855cd7c712a2c2d7bbf3526646ece0702ed221022000d464e2059934132ec5e7c457771ab7d9074db018ff9fae12dc632446e7b988308205800201013039302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a0207277dda070cc49c300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e875ea68e624cbb640b846729f3693dc54ae38de3e7fb0e10a8a5a879fe2df783037060b2a864886f70d010910022f312830263024302204204692ef5fb3ea8320c1cdce7bbdd31003aed069bb04cc1a5cde9b15625dbd4fc3300d06092a864886f70d0101010500048201004a82ea15c88391de20c5a8cc23ef3dcd9211505d29e989e4465a1bd9d6d98d538e7338b23fa3bcb352ac4150b63f4266e757a9237a94ab618c33e8d9327f37cc2ebdf0ef2a5293bba592631a653f334b18f66947d4af56f5f3c2eee2ca8788310b686e3035002d73807c8a64528dc2ff5b0665337c8252dcbc893bf177d424cea09648043a7bf995a33303d1c65064f77a2274993e4b5bc6b0d9c99d1f4c5bd07de2b69c83e158847aebaedfaffd68c1b8bc2fe39c8afb5c90d778061c7a6bbd0e73275dc04eb58c91aa17570acd51cc6b1cd29aa03a830242eb3b708e52cdbf8777766a35d7bae992fdfb5e44ba40ee72e859dd0c2f8ed893f7f56203e3fd12a182039730820393060b2a864886f70d010910020e318203823082037e06092a864886f70d010702a082036f3082036b020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420037fb73e4818e6577882813a718130f0d686ec9f3412477d89183f9f4c56210902012a180f32303233303832333135303932375a3003020101a08201b7308201b330820159a003020102020820fea3aef45f161b300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200041abc8a59e7def8a3cff4c99a08c30f7028c3af6b389cec3632cb34db5f206ad8a3931bb2c886e536e01efee7ad5817b029ddc29863228531735da0da9ddc2572a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020348003045022100b1a985b9b6c2831f174648a19b4900cd0bb3fcd3f67cc04b2494131d6a00426502204577ebcd3b8a14c252ef528b2e77b20369507753ba5ca543253dd9fed3238ce2318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020820fea3aef45f161b300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a3018301604141e1ab18975babe77d30e68003c717b89935b9dfe302f06092a864886f70d010904312204204214a1d3804eba0b407ebaaf0fb82ca0358a7c57384c677fe45ec01375ad842c300a06082a8648ce3d04030204463044022053e8abc782e01746c6a890eb397f591386e53f5dce014f0f1c6c1a5bbaca5a5e022045b17f83760fe6453244663fe8c52a9a49e33637652f3bacb7aee4524c37ad89", + "head_cbor": "a4006d646174656b6579732d68656164010102582067dab55c558d5de166ecaa2fbb9e74f85aa83e5505f14c8c1b7e821bcf92a9a00581a600686e6f74612e7478740116020003160458205d596d5f49c179f0ec337f4610155fc237e727f9dee85377a5fce67a3c853510051a6abcf9c0", + "salt": "67dab55c558d5de166ecaa2fbb9e74f85aa83e5505f14c8c1b7e821bcf92a9a0", + "content_offset": 32893, + "files": [ + { + "path": "nota.txt", + "size": 22, + "start": 0, + "end": 22, + "sha256": "5d596d5f49c179f0ec337f4610155fc237e727f9dee85377a5fce67a3c853510", + "mtime": 1790769600 + } + ], + "verdicts": { + "signature": "F6", + "seal": "S0", + "lines": [ + "Firmado con un certificado a nombre de Luis Gómez, Ana López. DateKeys no comprueba quién lo emitió: para eso, exporta la firma a un validador oficial.", + " Luis Gómez (emisor según su certificado: Luis Gómez), sellado el 2023-08-23T15:09:27Z, antes de la fecha de apertura.", + " Ana López (emisor según su certificado: Ana López), sellado el 2023-08-23T15:09:27Z, antes de la fecha de apertura." + ] + }, + "signature": { + "alg": 2, + "control_commit": "8405238a907ff83b4e3166ac25a4199d39d8d2af760670a7c2b25f75b6ef3e12", + "head_digest": "56c0fa647bffd5f97a30496ab396c39065c5c84707decc9d910716e43403926d", + "signers_digest": "95ca5c19d30dc0750e13f0ad621a789ba326498a7ea570fd0b7e76d49f4d578d", + "author_message": "datekeys:dkc3:author-signature:v1\n0e0f0eef6ce290deeb1d6de071eb65ca566331c5b1f07be40b906d655b9a72f3\n", + "author_code": "0e0f-0eef", + "signature": "30820f0706092a864886f70d010702a0820ef830820ef4020101310d300b0609608648016503040201300b06092a864886f70d010701a0820483308201763082011da003020102020801cafe20c83b2715300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d03010703420004b2103f0f0a2654afa291a4a435f2bfff8ed018e1c6892281ae497bd9aa2686dbc9fd7254c94f2ef6701d1a2777613878a053c827e6ae105f9d8b1145af7753eca3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d040302034700304402206de47fe26d900dae4860e57d29af0c9e3aba7421aebc91219e2e5697071092e6022020e6fad2707773e75a7c747ffeb2704f12db27898ccf75a5483f0a87c5fffda930820305308201eda0030201020207277dda070cc49c300d06092a864886f70d01010b0500302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a301e170d3230303130313030303030305a170d3430303130313030303030305a302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a30820122300d06092a864886f70d01010105000382010f003082010a0282010100b3316a351ac48d907aae9631ebc67182edab8c7f2f23a30d503060148fc475eba1e2d9cee063638849dc234e271bde03c28ef8afe53082abd4728aa74ad46aa220304a291058c20ec982bec051fa211243999dde73797e209ee554fcef9d03deab323fa39067883bcdd2c45f563a746ba954536d97b0f2fc5e108ebc293a94dfd566529d01b23096326a31e92199418490c4f76943a08fafa5069406a298db95d88c2f1678573d109ddd72af723dcdc5ae2df62cb09002e30b286256ae7bc1c8690e03dcea5936829f5a549e7ac090bb54602c82637414d71d60818b1f15f54144718e9384fe12c692d709f560d90bf7f090b344a0e13c24ccf32a6f13bd804d0203010001a3283026300e0603551d0f0101ff04040302078030140603551d0e040d040b4c7569732047c3b36d657a300d06092a864886f70d01010b050003820101008259b9cabd6f8e59d97bbbc3456f4d325d2dc37ae42feca2e46bb6b21140a59b823b3192b87f59c9f63c17dcce2192aa5682e37183cb47325e5e7f5bcbc9000b083177f0ba29b6735830f22bab56a872f126a41afde0d50952c3cd39d935751b260eef0368f23209e55a26beb5f93af3782637cf4a1d683eb942fbc008f1ccc339566e761a3269b9fe8277f970736699141caa5c3382020c9efc53fe798ed303f7bd97ad4fc41ec941489f7efa474afb89281178fa94c43ca4a3398edad9cc113c9206a503195922fae3505899206434f89186ee1f9314dd5454e96163ece8f358dc1a07482cd81ce02ec5b778c8e612458a2e540b1cfd90a1965c51c3b75e4a31820a4a308204c20201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a020801cafe20c83b2715300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e875ea68e624cbb640b846729f3693dc54ae38de3e7fb0e10a8a5a879fe2df783037060b2a864886f70d010910022f31283026302430220420aa2c7e3a8cfa6a6ec5374a1bf0d427bd9e833352e825984298190fa96b543cfb300a06082a8648ce3d0403020447304502206225e91f9358d8605076090d4f274400ea4563cf31d998ed23ff42f731927d65022100fac4c2ec5a8d50c24aa0b426fd15a833a70b55d95bc373d8352383c2f06b5826a182039730820393060b2a864886f70d010910020e318203823082037e06092a864886f70d010702a082036f3082036b020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420c86ee56a958ac3033f9df8c204eadd19324a66bd8d00aaf069b872c4e204293d02012a180f32303233303832333135303932375a3003020101a08201b7308201b330820159a003020102020820fea3aef45f161b300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200041abc8a59e7def8a3cff4c99a08c30f7028c3af6b389cec3632cb34db5f206ad8a3931bb2c886e536e01efee7ad5817b029ddc29863228531735da0da9ddc2572a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020348003045022100b1a985b9b6c2831f174648a19b4900cd0bb3fcd3f67cc04b2494131d6a00426502204577ebcd3b8a14c252ef528b2e77b20369507753ba5ca543253dd9fed3238ce2318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020820fea3aef45f161b300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a3018301604141e1ab18975babe77d30e68003c717b89935b9dfe302f06092a864886f70d01090431220420ae2f3d372b417904643ba5da53b50e5eb317c274794d31bae41428a064c20866300a06082a8648ce3d0403020446304402204174c537862c0d25e8ff825d41855cd7c712a2c2d7bbf3526646ece0702ed221022000d464e2059934132ec5e7c457771ab7d9074db018ff9fae12dc632446e7b988308205800201013039302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a0207277dda070cc49c300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e875ea68e624cbb640b846729f3693dc54ae38de3e7fb0e10a8a5a879fe2df783037060b2a864886f70d010910022f312830263024302204204692ef5fb3ea8320c1cdce7bbdd31003aed069bb04cc1a5cde9b15625dbd4fc3300d06092a864886f70d0101010500048201004a82ea15c88391de20c5a8cc23ef3dcd9211505d29e989e4465a1bd9d6d98d538e7338b23fa3bcb352ac4150b63f4266e757a9237a94ab618c33e8d9327f37cc2ebdf0ef2a5293bba592631a653f334b18f66947d4af56f5f3c2eee2ca8788310b686e3035002d73807c8a64528dc2ff5b0665337c8252dcbc893bf177d424cea09648043a7bf995a33303d1c65064f77a2274993e4b5bc6b0d9c99d1f4c5bd07de2b69c83e158847aebaedfaffd68c1b8bc2fe39c8afb5c90d778061c7a6bbd0e73275dc04eb58c91aa17570acd51cc6b1cd29aa03a830242eb3b708e52cdbf8777766a35d7bae992fdfb5e44ba40ee72e859dd0c2f8ed893f7f56203e3fd12a182039730820393060b2a864886f70d010910020e318203823082037e06092a864886f70d010702a082036f3082036b020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420037fb73e4818e6577882813a718130f0d686ec9f3412477d89183f9f4c56210902012a180f32303233303832333135303932375a3003020101a08201b7308201b330820159a003020102020820fea3aef45f161b300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200041abc8a59e7def8a3cff4c99a08c30f7028c3af6b389cec3632cb34db5f206ad8a3931bb2c886e536e01efee7ad5817b029ddc29863228531735da0da9ddc2572a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020348003045022100b1a985b9b6c2831f174648a19b4900cd0bb3fcd3f67cc04b2494131d6a00426502204577ebcd3b8a14c252ef528b2e77b20369507753ba5ca543253dd9fed3238ce2318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020820fea3aef45f161b300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a3018301604141e1ab18975babe77d30e68003c717b89935b9dfe302f06092a864886f70d010904312204204214a1d3804eba0b407ebaaf0fb82ca0358a7c57384c677fe45ec01375ad842c300a06082a8648ce3d04030204463044022053e8abc782e01746c6a890eb397f591386e53f5dce014f0f1c6c1a5bbaca5a5e022045b17f83760fe6453244663fe8c52a9a49e33637652f3bacb7aee4524c37ad89", + "security_key_2": "a300020158458258204692ef5fb3ea8320c1cdce7bbdd31003aed069bb04cc1a5cde9b15625dbd4fc35820aa2c7e3a8cfa6a6ec5374a1bf0d427bd9e833352e825984298190fa96b543cfb02590f0b30820f0706092a864886f70d010702a0820ef830820ef4020101310d300b0609608648016503040201300b06092a864886f70d010701a0820483308201763082011da003020102020801cafe20c83b2715300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d03010703420004b2103f0f0a2654afa291a4a435f2bfff8ed018e1c6892281ae497bd9aa2686dbc9fd7254c94f2ef6701d1a2777613878a053c827e6ae105f9d8b1145af7753eca3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d040302034700304402206de47fe26d900dae4860e57d29af0c9e3aba7421aebc91219e2e5697071092e6022020e6fad2707773e75a7c747ffeb2704f12db27898ccf75a5483f0a87c5fffda930820305308201eda0030201020207277dda070cc49c300d06092a864886f70d01010b0500302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a301e170d3230303130313030303030305a170d3430303130313030303030305a302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a30820122300d06092a864886f70d01010105000382010f003082010a0282010100b3316a351ac48d907aae9631ebc67182edab8c7f2f23a30d503060148fc475eba1e2d9cee063638849dc234e271bde03c28ef8afe53082abd4728aa74ad46aa220304a291058c20ec982bec051fa211243999dde73797e209ee554fcef9d03deab323fa39067883bcdd2c45f563a746ba954536d97b0f2fc5e108ebc293a94dfd566529d01b23096326a31e92199418490c4f76943a08fafa5069406a298db95d88c2f1678573d109ddd72af723dcdc5ae2df62cb09002e30b286256ae7bc1c8690e03dcea5936829f5a549e7ac090bb54602c82637414d71d60818b1f15f54144718e9384fe12c692d709f560d90bf7f090b344a0e13c24ccf32a6f13bd804d0203010001a3283026300e0603551d0f0101ff04040302078030140603551d0e040d040b4c7569732047c3b36d657a300d06092a864886f70d01010b050003820101008259b9cabd6f8e59d97bbbc3456f4d325d2dc37ae42feca2e46bb6b21140a59b823b3192b87f59c9f63c17dcce2192aa5682e37183cb47325e5e7f5bcbc9000b083177f0ba29b6735830f22bab56a872f126a41afde0d50952c3cd39d935751b260eef0368f23209e55a26beb5f93af3782637cf4a1d683eb942fbc008f1ccc339566e761a3269b9fe8277f970736699141caa5c3382020c9efc53fe798ed303f7bd97ad4fc41ec941489f7efa474afb89281178fa94c43ca4a3398edad9cc113c9206a503195922fae3505899206434f89186ee1f9314dd5454e96163ece8f358dc1a07482cd81ce02ec5b778c8e612458a2e540b1cfd90a1965c51c3b75e4a31820a4a308204c20201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a020801cafe20c83b2715300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e875ea68e624cbb640b846729f3693dc54ae38de3e7fb0e10a8a5a879fe2df783037060b2a864886f70d010910022f31283026302430220420aa2c7e3a8cfa6a6ec5374a1bf0d427bd9e833352e825984298190fa96b543cfb300a06082a8648ce3d0403020447304502206225e91f9358d8605076090d4f274400ea4563cf31d998ed23ff42f731927d65022100fac4c2ec5a8d50c24aa0b426fd15a833a70b55d95bc373d8352383c2f06b5826a182039730820393060b2a864886f70d010910020e318203823082037e06092a864886f70d010702a082036f3082036b020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420c86ee56a958ac3033f9df8c204eadd19324a66bd8d00aaf069b872c4e204293d02012a180f32303233303832333135303932375a3003020101a08201b7308201b330820159a003020102020820fea3aef45f161b300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200041abc8a59e7def8a3cff4c99a08c30f7028c3af6b389cec3632cb34db5f206ad8a3931bb2c886e536e01efee7ad5817b029ddc29863228531735da0da9ddc2572a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020348003045022100b1a985b9b6c2831f174648a19b4900cd0bb3fcd3f67cc04b2494131d6a00426502204577ebcd3b8a14c252ef528b2e77b20369507753ba5ca543253dd9fed3238ce2318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020820fea3aef45f161b300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a3018301604141e1ab18975babe77d30e68003c717b89935b9dfe302f06092a864886f70d01090431220420ae2f3d372b417904643ba5da53b50e5eb317c274794d31bae41428a064c20866300a06082a8648ce3d0403020446304402204174c537862c0d25e8ff825d41855cd7c712a2c2d7bbf3526646ece0702ed221022000d464e2059934132ec5e7c457771ab7d9074db018ff9fae12dc632446e7b988308205800201013039302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a0207277dda070cc49c300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e875ea68e624cbb640b846729f3693dc54ae38de3e7fb0e10a8a5a879fe2df783037060b2a864886f70d010910022f312830263024302204204692ef5fb3ea8320c1cdce7bbdd31003aed069bb04cc1a5cde9b15625dbd4fc3300d06092a864886f70d0101010500048201004a82ea15c88391de20c5a8cc23ef3dcd9211505d29e989e4465a1bd9d6d98d538e7338b23fa3bcb352ac4150b63f4266e757a9237a94ab618c33e8d9327f37cc2ebdf0ef2a5293bba592631a653f334b18f66947d4af56f5f3c2eee2ca8788310b686e3035002d73807c8a64528dc2ff5b0665337c8252dcbc893bf177d424cea09648043a7bf995a33303d1c65064f77a2274993e4b5bc6b0d9c99d1f4c5bd07de2b69c83e158847aebaedfaffd68c1b8bc2fe39c8afb5c90d778061c7a6bbd0e73275dc04eb58c91aa17570acd51cc6b1cd29aa03a830242eb3b708e52cdbf8777766a35d7bae992fdfb5e44ba40ee72e859dd0c2f8ed893f7f56203e3fd12a182039730820393060b2a864886f70d010910020e318203823082037e06092a864886f70d010702a082036f3082036b020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420037fb73e4818e6577882813a718130f0d686ec9f3412477d89183f9f4c56210902012a180f32303233303832333135303932375a3003020101a08201b7308201b330820159a003020102020820fea3aef45f161b300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200041abc8a59e7def8a3cff4c99a08c30f7028c3af6b389cec3632cb34db5f206ad8a3931bb2c886e536e01efee7ad5817b029ddc29863228531735da0da9ddc2572a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020348003045022100b1a985b9b6c2831f174648a19b4900cd0bb3fcd3f67cc04b2494131d6a00426502204577ebcd3b8a14c252ef528b2e77b20369507753ba5ca543253dd9fed3238ce2318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020820fea3aef45f161b300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a3018301604141e1ab18975babe77d30e68003c717b89935b9dfe302f06092a864886f70d010904312204204214a1d3804eba0b407ebaaf0fb82ca0358a7c57384c677fe45ec01375ad842c300a06082a8648ce3d04030204463044022053e8abc782e01746c6a890eb397f591386e53f5dce014f0f1c6c1a5bbaca5a5e022045b17f83760fe6453244663fe8c52a9a49e33637652f3bacb7aee4524c37ad89", + "signers": "8258204692ef5fb3ea8320c1cdce7bbdd31003aed069bb04cc1a5cde9b15625dbd4fc35820aa2c7e3a8cfa6a6ec5374a1bf0d427bd9e833352e825984298190fa96b543cfb", + "certificates": [ + "308201763082011da003020102020801cafe20c83b2715300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d03010703420004b2103f0f0a2654afa291a4a435f2bfff8ed018e1c6892281ae497bd9aa2686dbc9fd7254c94f2ef6701d1a2777613878a053c827e6ae105f9d8b1145af7753eca3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d040302034700304402206de47fe26d900dae4860e57d29af0c9e3aba7421aebc91219e2e5697071092e6022020e6fad2707773e75a7c747ffeb2704f12db27898ccf75a5483f0a87c5fffda9", + "30820305308201eda0030201020207277dda070cc49c300d06092a864886f70d01010b0500302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a301e170d3230303130313030303030305a170d3430303130313030303030305a302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a30820122300d06092a864886f70d01010105000382010f003082010a0282010100b3316a351ac48d907aae9631ebc67182edab8c7f2f23a30d503060148fc475eba1e2d9cee063638849dc234e271bde03c28ef8afe53082abd4728aa74ad46aa220304a291058c20ec982bec051fa211243999dde73797e209ee554fcef9d03deab323fa39067883bcdd2c45f563a746ba954536d97b0f2fc5e108ebc293a94dfd566529d01b23096326a31e92199418490c4f76943a08fafa5069406a298db95d88c2f1678573d109ddd72af723dcdc5ae2df62cb09002e30b286256ae7bc1c8690e03dcea5936829f5a549e7ac090bb54602c82637414d71d60818b1f15f54144718e9384fe12c692d709f560d90bf7f090b344a0e13c24ccf32a6f13bd804d0203010001a3283026300e0603551d0f0101ff04040302078030140603551d0e040d040b4c7569732047c3b36d657a300d06092a864886f70d01010b050003820101008259b9cabd6f8e59d97bbbc3456f4d325d2dc37ae42feca2e46bb6b21140a59b823b3192b87f59c9f63c17dcce2192aa5682e37183cb47325e5e7f5bcbc9000b083177f0ba29b6735830f22bab56a872f126a41afde0d50952c3cd39d935751b260eef0368f23209e55a26beb5f93af3782637cf4a1d683eb942fbc008f1ccc339566e761a3269b9fe8277f970736699141caa5c3382020c9efc53fe798ed303f7bd97ad4fc41ec941489f7efa474afb89281178fa94c43ca4a3398edad9cc113c9206a503195922fae3505899206434f89186ee1f9314dd5454e96163ece8f358dc1a07482cd81ce02ec5b778c8e612458a2e540b1cfd90a1965c51c3b75e4a" + ], + "signer_results": [ + { + "holder": "Luis Gómez", + "issuer": "Luis Gómez", + "result": "valid", + "seal_time": "2023-08-23T15:09:27Z", + "before_round_time": true + }, + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "valid", + "seal_time": "2023-08-23T15:09:27Z", + "before_round_time": true + } + ] + }, + "stages": [ + { + "step": 1, + "name": "parse DKC1", + "ok": true + }, + { + "step": 2, + "name": "prelude", + "ok": true + }, + { + "step": 3, + "name": "public header", + "ok": true + }, + { + "step": 4, + "name": "header validation", + "ok": true + }, + { + "step": 5, + "name": "sealed control structure", + "ok": true + }, + { + "step": 6, + "name": "payload structure", + "ok": true + }, + { + "step": 7, + "name": "condition", + "ok": true + }, + { + "step": 8, + "name": "tlock stanza", + "ok": true + }, + { + "step": 9, + "name": "release", + "ok": true + }, + { + "step": 10, + "name": "release verification", + "ok": true + }, + { + "step": 11, + "name": "open sealed control", + "ok": true + }, + { + "step": 12, + "name": "policy structure", + "ok": true + }, + { + "step": 14, + "name": "control", + "ok": true + }, + { + "step": 15, + "name": "header binding", + "ok": true + }, + { + "step": 16, + "name": "payload identity", + "ok": true + }, + { + "step": 17, + "name": "open payload", + "ok": true + }, + { + "step": 18, + "name": "commit", + "ok": true + } + ] +} diff --git a/testdata/fixtures/format3_signed_cms.plaintext b/testdata/fixtures/format3_signed_cms.plaintext new file mode 100644 index 0000000..379469e Binary files /dev/null and b/testdata/fixtures/format3_signed_cms.plaintext differ diff --git a/testdata/vectors/locator.json b/testdata/vectors/locator.json new file mode 100644 index 0000000..f124ade --- /dev/null +++ b/testdata/vectors/locator.json @@ -0,0 +1,207 @@ +{ + "description": "The extension datekeys.capsule of a .dkk and what it points to (spec v0.11, 44.1): an envelope of age with its header apart from its rest, the rest hidden in a host file, the locator sealed with tlock for round 1000, and the data of the extension. Frozen. See testdata/README.md.", + "spec": "0.10", + "round": 1000, + "datekey": "dk1_eyJ2ZXJzaW9uIjoxLCJuZXR3b3JrIjoiZGF0ZWtleXM6cXVpY2tuZXQ6djEiLCJyb3VuZCI6MTAwMH0", + "note": "Cartas del viaje a Lisboa", + "dkc": "ee03814d73b55af618455bc90321bd0c27b16b8b440f1b954664218ecddcf4f33d3838f839d7549fcacc8ab912af943afead15c99524c0bf9a637099db4164c0c010e8201b3ca44f1c2563670910c5dc76aacad8d31a939be742afb6f985971cbc3167a73f7b5700213f35758b8981f210dcab1252433673930e4f7fe2cfc048270c2af4f9e22b8ff2cb2e09c6cc964b02b21b83a0fd293c446c55e1a2ebdd2cbcf997c264602c92d42524b1cd712a506634090180608822f4360d733be5b47bb4ea4018bc3eefe429c1745c809e2a08aeeb897563ab46c9d2fdf834e57d7f1fd5d76f2e583d571ce055a52e2fa15000a0cc387f088767f1177c68af7141f338b71499c05488e90f0c5440c775eff25469a30bee7568b1a1faf998d865f7894bf8b677739e191612774ae8dccc30c8ebc0983edccbfc817cda3b74438bf6f7d761377592db4f52100a19e3b0bbc69273b01d54e2bcd843b5936841cebab1a20d8986b6ba3c23248ce762ac072032cf85a36a3f9cf4059b41f0b0fc2ccf96723552f2a20f6baafa661d1a202bdab2c22028020152d3c5118387ca32b8da9928d303bd2f2a1d1845c01c679d47c31bcbf823dbca5556c7e66315751ddf0e1f97dee3c703b7545cd84217d680470b01f0d57c7a902eacce78e25374fe13b4d7a001e660df9f0a5eaa1499483d08554ab314e6222288e55e1f1c3ed93d897fa3424fee8e13140407950dfc68ba1db731b72028fefd21d8c368fac10a186a73a1310b9d9a65637d54ec9f0a022fe0cca3a2cc81818510568b94c4531ce6c00017b9303c202ff40dc3dd70fb9a8e221773fd57c77b82ae7f4bcaa71fce11edc7e6bed299f5d8b306e2f3ab0f6952f62fe7b61f2358966eaf9f933b538e960ba7536a87ceba023881f1ee66fd9c5c4a7a05548ef93916a32f0d735dc517fde4e787b85c430a1eaf7442f0b71dad8f46c097f624c64b6d3c8bba7824e1d5cda3c43376f0125638b905abc0e0a6be8c3637095c6664df17d234c077a78e6a588c259db83ef42df60744df33c6c7f184092d169a3b4eb703d5936fee55ddf83be09944a6af840ad6d1507c5888111288cd898d6e3a2fb9746c0b62d7ffd7b486e6a507a9cabd14f47b431f26de3470be86021f5a16ea48b7740f9745d29f1cf0bde23a4b639464ceee378bfd3b45040609b27cfd57c31334ef011d94d971b9a5395384d3fb15ead0d7a0e7c01155f0a142b77d85f8196056a55aeac01fa01bc9c33632f242eca3413af62e105448d60c63b84d83f13ce52875c205c8a680f588e6971ac0bc70650a2126e8c105d66b8fd8c812c10f8513238c140bd5c91532e45341b77df32f5f3370f813408f7c3ead91dc17db1d93a722e992fc9539d5a6186d4ccbeca31478286b9891fb9513a961127546c55f3255168fc3cebdd6266837d2bc41e2e5f015f4f7686b6c3fb213e856b47946f6d9f682c4fceb30485dca116067a37090b8c01c45db406fbb920e6825d5cbfe8bad8f965630bb645146d966e8d326d0e24cd330b8d9774ad36a8204e427c6b0ba20db20d03b80d9b94b9e72305a0ee69ca6339df880f329a2a628b1dddf2e90c344c2db01e559332916533a4ef4f4c7d9404da29436b31b81280739fe15eab10d1b4dca7f28b342a25e15f9c21a1bee2b9a10264a2de383a9f1e9aa2bad94366a7eca3764d7fca5bb21a772a70af20a9b8fa02da25a0061fcb7d70b1e819a617b26811a657d9be611c36ea1f9cf15957b50cc4d215db052809e9796f089f4c94e94e852313c7a36b6aaca542090e1d64eeca08b42b266974053a85cc955c0cbe326a5d862ad4a5de60b51957a71c5c49633c7c838c8f5846d85a6f76ad8087c27df203c39997e4efee96a240fefe5900405d91a400d98392cd45079af48b149ec7c95e99a22e8cf024f52f759d47595d6c90c0619a7c9f2001fbaf92a0d43655a3e62653c04c99d56b50503a9487c45e6eb019e926ae451e6eda6ec9f0d4184e0a5dcab7264aa3ccd3df08c482d00bc5b5effe623accd1516dffca98376b9fd596b3eb9e6af0d6d390fc16ec011192ae73d681ce540a19522c19a283d6ccb9906893a222f598d782bc7fa1069011d9e9c5225280c26572ef0e37554ad877d2b64cc8a6f86f06e6fae2009827be6111a88160c98b2980b5c4c16497de5a1e75a307ff9ac581c52e9508916b9138e9df24298d79f280e6003c174c8f88dbcfef977a6309f7db96c44e99b9f43268d2367ef12f879b2ea906c3a555bfb9c09e6e3d10d6b742adb6b4e90bca6572fb4ed3651acfd81642954936e7dc97f034b7e42c08e1838e9032e982e705dce629b00204bf862b7e254a8b49c7b940647f5cf27b5673d4eb1b723ebafaae178acdb5b2e2d4a4176a944e7922ea81f175c6ca09970f602782ed17f71635c4679fb19fe64d9896982575ba2e7ed4f5913dff51d0fdc99b25ef51c88cf3922b85b1615e1943b0d9b69599711e9f0a3664d1d1beeeb81648b579b8965104a0242ac4eebd2c20fb2756dbbe6358a09da0bd4dd543232aa54a92d2a4027b620b51eb80fe8e169061442fc742a70ba449575a3bb83c2a91bff8d249151d99712bc4c413a455ecfeaeaafe14e5ef8f02398d75c1ab697fb2a98c08ed58abe46808445528722b2cd532e08492826d6b9d13a3e564f51a99608d28d13a16a5082a7e20600fc229f7736b3f555f84a49499b15c812b2880842dd0b2cb9865ad9d9499d8304ce32ae6437bbc3dfcd53b7cbb3c07d4b719b48be8ab6848ab4cc7455c5a08c94fb48c003cb65231cf619cba729d9735acd842b3f5dd01809875dd287b6f4bf27f3e4a8e9a796eeb8b80709fed6ef83e598281e679294d32e77ea15927d8f777a8fee3e9e00fef8a4de04a58feb64fed01ca14ced9dea6ee4eea43a0960a5e9e5803b7c778e1125cc981b935099854696c874c7be4d63be2ba06b185b99c949a18b261a72ef52aaf371dd241391c920737ac1dfe17a200d1fcb9a1cc16ed72c5df1b7af3b5ed4f7b3f718d28fb4b6f27bd49175d2a6946b5940cb8bf1dbd0d786cc0a968c0044ff3c172d5841a28c14bdd611fad3029b7601206404594b29adf1efb0d5640fb7422a7ea2d3db8c2c65a3e8bcc65cb2fe7ef724f9cf82159ea6984ec85a4a172d689f614e9a0a0c5893b019fa0701ef339de724395b9f9fce48402f2bf069e2ae51fb23c6cacf58ce3f0dbf927f3ebe888f63b7f3dd10895c99dda8fe60820e8beb18b3490797575fc2ed009f777f9f205b7001cc47fe03d45d022f726376fc9908e66b4659a218e7106929c0443c0deb51c1d36b8783bd4fb91956d80ef2820d6806c2594fdebe33ae620e5e9e816649a6f3ded5943ad676b57d2e8180444d23fdc94c1245008c26e7c726fe1c35d7c33b9a48e3f456317006ed0c8651331b50797f85e22c49e5e3fa34dec19ac7efa9bbd4fe6d529c5e59213c2b1b51657ddb051fc52eb1c6eb24a718d7053a7ddedad40822adff1bdd7957e85b7170eb743fc579aea19daad4f7a6388273916cb66c69e90c9ede83ac8f88fe097d2b752da0c3b2b5d3ca98d4498aca32169b3e7fbe5d8d14a51983a5cfe8f9b775654b244243584278213ee6c5807c67e845213049ceb02ab4b9a52ec1cff8f69ee53794f637aefa865a1f0f3649a14eacf03edb19c777876cbf8c959cb41f86ccb6d5451a1a1c4b3159d89127c6d1f04a1c751c2aba4289d629112e54e2bb119110cc180f6d4ad9857620081813268c50fbf850437e5940843c62c3efaa210a2a318c4e6b4cf89dff2c886d1495043cc9fa1eadf7c852114817f3df7cd1adc0915777e8f83f1bfdfa056f2dcf3d4cebedd888bc70e4f762399ae8979288333be650d00349ebaab3da70e2b48b3a42d9225ed0dec5ccb24e6f73028032763cce6b645abc50af5588c052539ccbae09159b9d5ce17abd7d491aafa904f5c2b4f284f7b19be9a91ab6bb9542cdef9bbb217767e65d38769602e3a6a355889fbda04679e78cb1b4e7b880014f81b623c4c38e19c7b013c8992a0c103dcddb68c0a6d35376d132550a1e06d590e55f4e7bfbc7b8eba4d5d7c923e428551cbafa3d5e31f94ccb38d2b40fbb07cfe35ae7d1538871707a1aff5b91c33e1420a4632d91c5c2cca2838f30768c60ab6a26261d3d74b59b7173a38917b06f866d11b89ef999a2df8b3592f5ce42fb230a095626be28a46015d4106b78a41829f8455fe4e36d473c78bab24cfbbcdc7e11ee6cab0703abd82d86fe0ee1e7c07b82515f453a7bc5cccf67240456b00305908fa926945718b9bedb8c007d59b103e8dcdcc42e2941489e6ce51bde77cc5e556337f08be392181e9325b60e32bb3bac79c1cde2a6bb671ae5bb35d108f676f963feca6aa0eb47de54903ecedbbd46bca7fda54d6854bad92b98e66fafbdaad17c23f9e1b2998b6760cadd57b91182a4e43735a47de9006905a29dd73347592ccb5c4a5230b5e2d4059ed055eb3034f3bfc018360f0549b1a6b2367d6323af05038dfab8db4b35acbec3297ff5e9751185641fc6d772a1e617a615be2d18ba1ee9499851d63b0b921a7ac15e04c4a2507ef25775510fee6b051b5d0c2d210309b1ead2d3f91bbe319032b647dcd7b0ba9563c2800b49c5c5b91a1ac8a2f9032e52f1edbaf2a5ae492b34011e58870d712eb29bfa6b1562cefda3fa1fc0edf17c518446b1b120ce11b416a596cd381eb0be752a5b7ce1d23cea27ad1792667d182bdd11281e80ed8ed9dccc94ba98fd2e6c3895a4f21cf99c11ae36e40ce03c37496ebc2cab7b808b394557266d3ab1d8386abc04ff79bfb38d7fdb4a0e5dd32308475e9860d1a9d73d282c377f35ca76a0a99edcc3140d990cc85dc9a40be0920913ed67e4c4957d728ba038e4b43f983b727e7be0ca5b866bc403f4395e3eed91f224f7cbc0cefda0fcab8681489e56be77bd61ab269805b07d025806c5d74f8c858597960150442688bf97565826146dfbc6a2932580caf1a8a527d27cf8ecabaf9145862ca57f2a5a775cf6b534c186d5ae06ab1e5b82f91931eb07f163f23c04ec8230ba5d1a8930c31d3e622f2c83bd593489c56d6aef562d518a155e28ee6e2b5ac5577a44754b3bd631dc2a643af50cbb9eb6ad5bb21291980f64d7b91348f1aa2fcd8acafa1de5ae890d5143648a2d2bcea7053ea58d3a48d4b3222c36069cdadcba4bf94fca38b406138e4ba188602b286dd7222b86c15146f4e04bae67abcaf5c6cf802d0fade9190dd4aceb47f41e2177c2254a67f4c3fe5d30430d2385094d99da73d98b5c6adcce3b0b4091baa14f522115c145c31f7c9eabe4317d3dc335d2d472df9b250b2c9fc0d1fd1ee15155eca4de87397c5815329069d655d2974e5ef5737d1153a78ea1fcbedb03bcbca663d750e32365f3ed527738c66ac34b5d0fdd1f65afa77c2a322cecd27ceadd2559b1edc51eb44a529011955866d2ac01d3bfdeacb247e8e0fd219492ebc68287849370d5fadb9c1b71b7f4ff4c645ffb6c7ddacea49ab0e79f9c7c83311635593f6a9326877cefe284902e3de0f0d339af7692fe39aef0b3304e4dc45419ac816e61c6090dccec275b1efeed2debdc589a0e4923432469ac24cebe6a0a05fb7d9f0fac9a5f3f88f31cf4d3d725feb6c0066f6fc6c13464a0b2c22e48633dd1ef9c87b18609618fdc5ce4a78358fc82cd6182b286f7a3c915fd0d3732885769332af100f89359f6ce5e4611db542ecd2b9cb751e2e6cd8a5cb0c878886eb84c0d0702cae0a837d161de86aefef6089b2281d6986d478a6edd9a2873106ec42818d6bc2bc2c6de0b10f90354a0733dcaf1c1553cb5e49eed6f24dc15bca702c9502660404d249dc15eda4a854a60c08d4f6e51e291275a53ffb4be824036b3cccd792a67121dc6287ddd70f520447f274459b90d08151ff71ce9b81ce328970359aa7e9278ef85b7a4c8b73a6c9cf1bd8b64ecc8a5d6a5ae859bb8ac5599b20f55b201a389f01aaa7c9933bd79ea7f4cda9a6d0dd5fab81b5559cf9baa549aa74b22a458959b4a925399415693403a2d75e524b5465985cc05f856a7418bce674d642195cbd7d6d3bd5e2cd0ac57fbf293695a9f6d1dab534623665ea31a666cb633497fc597f6a51014ee58c0cca27c2ea8daacdc77770b16178092df935ce9616c95e5ba77e23662f79b6cab6af60c00096361bdd43c94005baf3a321ac3515f6858c60207305f6bd2e28e913354a20d7d5f98a09dba318899d2c9b553129ec2c0673dac849a05c086d6b9fe58b449000c198705cf982fb8ffde27b429ba51103c8d9cafa25b2d34f2a08b28f32d4f3bce6595c4cd9d8c6a482372b0b2c2544036dd43c8ceea748e1b92017a9a03db8719db6560a16e5d88b175fafce2d180c9516db3ed1c627dc3043e0a9aa3ce5bfab086d1bffb5e7efca18803fa0112cb281901e9a77bb7eeefc25169473b99049c06faa36c3306101689f4892bb5056513ce7e73dac906bcc0b721f34266470af08220737f7eb458403746cfc0571fd021e52a87ea03120ab19723a746805ccfa7a445ec25f4eb234a5f18856589012b86f7d3cce63c04faa1097c2e91c829d290dde41734f4cc11f0340423e1c9072348ba80a68846bf61b619a82b956ef6e7d41feb24ccf000a50a159beda6276cae4d18f98dd56fb7dd25e773ed147e7198663ba077382a6ebb9ff9aa07612ca04d0126de1dee66d3ba8c4e2019c6fda91a3b716dedf61f6db20c2a2a1183efd18e70cf584c0696c02e594bf43575c6f23f4383b42f05619853af66f769a756b59ad1f469a480924994cf514e5b6a5474ea5b642477f3a9f30214193a3e778988b98f7942cdc1212d718123a1f9b35af90c611e736dd1adeade640686502b69f9ae534e7c9df7f0fd03bb3eed5f81042c2df16ae1c26e302d8fb5c6caaecdbc8c1ff8ce2dcdac4325eddde37a8a0e060a0054e4be2b5e8cf589f458b69610a873369419b5d67aada89f77330d08b2f8b71f9fc7cce6597ee8f29088f5a89d8ae7611550f5dcca4674e4a7ed1743", + "rest": "8a2689c9bc0a0d9773da3d14f6ff6f14f730dd4a5462e5a47597997bbc6b96bff60fe1a55e2ba4089545184c0b0a973847130fc1324aa7dcdd29896f185fdd77b4800ef385de9d6a6259401f342400c314fc223a1bcbecded2dc7d0b7e34e0fd4c6d2c4d76a36a18cdd0b3f25e98707ed0c1c36859a635b5a09807fbb62edab178e17e42fb4fc7d415d0efde0e643b1cca0e10e05ae67fc93224aaa6287e068d12132f6c26ed78f756d566f83c833413cf9be11b74fabd3bbcfc5a09c346c656149b35ada313d71103862466e18abfece1b5de30d7d2da04ccbd68933cbffdfa3ef38317d0499bf04924582dc6f54edeef6b39df149eb3f386a602a812a01b998c2d54745feca7647c7ab6aba562dce1ce38aa499cad7c2c31bac32c5f2ccf512eb1bdfecc2949e44e9e8e0d718a9f11eb7d8226f8f6a0ca8d2ba55f76f5f52585aba2040797e4936af23bd8409dac6c2a9e72a25fd656889d2f85cb1ca61b4bc97eb4400c63a868af10fe6e0bba88260ec6f9631b6cf1f43c321e5a8507f2c9388173e113573737513dafc8b169bae1d3ad447e1f63d318d33f7c6a36008598aaf236f4cecb705e8925a140a53f4c935a269788b80c55d97571d2526f9fe7e1e88e3d76a2b9820f8ca6e590daec76c9e1d94b1e0e7d87f1160e3be70c3544e5620131fe3cde24da788b4f8e6c466a1525369829d563c21e6f38ea9ef40ee3a31a44bd11f48824dd6019c590ded7f60cde7d61dd36c122f187252f5af081090f14557ca930d061799beb24c67fbefcce03f21440f5d8631bac2419a5b3f56bd1bde054a8096bf16cfe0885d0ef33dc56fcfb951a371eaff0d5cf6e099e512d0d6e16afe5b753bfcb85e325262e2faf6e843478a060a64b5adf2c6038688c37e7e3a8a0bed370b3f8d847e77543413aed6cbec13ac64d6f751d18a3a805ef6741594111b068012a10e5ae943b821069c48efb76c9e9a57e6cfac6a1cf9bef28478d40cd259831aec9d088a2eb5c65ef2361df3e9f657dcd258af93d0780a0be390ebc532ffb45e5999c028f3e762849f9e20e9ecba400539c24ee9fcf5175868b6d876edeed19295640c2acc0852573a89f356ff43f0098439c81800dba4af9c666fd865790e73801ca4e010c12e65495cedfeb6669f7fc149b3b4e6da63b91ecd11bd8dabdd8fa15b2c885a1522a674e34aca1bdc9f5fd3551d0e20a49541d59b653d6a84a2e73289ba8506c1226d60a8c5aa3da866d1f88b75451a893a1e4d456712bfc53aac071dcaad92cfdce420d177a3405a7d89650c29a9040f6517cfdd93a10a6d7e40ce5cb131f0b1569d5a76fb6d51500dcb096d40faa5c04f7220b16f92e465a0de6e3f952e98a55250f02c9bee794825b9d2214f08839e65dd0a3a33af28258e53888926a18cf9168c24a6cece5932e7e114a1351949bead203b8a7912d5c6a5f2e00772ea18fca970e6d02b8113198ead9c36a73b2fe4d12cea0469cb28cbbe45f31e99608e18eca6ad113d12e2ef89e1f5ba3a6eca32288b1be7f951670c7d44f1017dd6f757fab16740c3c3622735a2d8ae90f0bdeca0c4c8e7ef203e2a08868f3755c21fa2fadd4121531344127022f046b34e1ad1c9066afc744fe1bfa5dbfa8c0ffef4ac6fe9960f06b4defad72ecf6efc39204a95f3d27aaf967d43543cf0b3e3dcc932bfdf6234f852b4817e6c21d0289445ace8c7749e314a8256e81c2a82cc414ab60948b1a9a60dab4b86e694689e4d160f2ed1c39971b27171bc7fd1928aa80404433eddad382f92e672c1b92578be6494bc13694be1c165bcbfddc4228957afceb5c867b85bd11c00d50e9c5722907f56dee6f3c45445be0283512aa65b0214ae2927823e941eae8ebfc215cf34e9b14bfc29645e2a63548f022deb49becdf344f1362890c1b3c39123e172c5092bc329a525d3386bea40c6a22d0bf8a8865387496126e63406d163a1f02944418fd8373afd863334ea510534e115e7f4999b4f4a4314ba43955a743a678d211b61b8a1e8619550bcb90816f18845989d80e9994b0ffc1c02236bc8651d5a1a520578df7368ac97715a8d88812944b4d97dfb57959722460388cd39d1d5e06a125653062ea6351943cff52fb7f6350538b80cdea1f3f2370385e87b9ec1aa6916174c4487036787ad62183706cf88b2b9eba7cff2a5a0eca6c1577fa2ed872c7f333e0e18e6479e8ae7060b7dad0a78ba89248c8db0412f251181ee6054c1e67ec4e5f3536610a8acb4cc03e8b06c378c294af6d58acbd8a5ba5629617b90b0fbf01b158d487d2d76d889268feabec421b222e30ab3fbd8cbe6be9ab2dad2b67e1c871d1ee7de65eb160b674262a57a6942e24e1a4210658183eba1dda62dab40c9811e34416ccb9bf977e1a3c5dbb51f0b1cd6d7e855cde268bcfd361a646b2cf65f5e7c6ae0f18001ca16a97ca11c60fbda5146e5574409d06d24a0892a0bde605f5ff0fc84354a2fcd38abe7a9da7049d8fdc966aebaa213cc8bd9e73b1773b6efbc51110865fe1c4464998d682ee08942f48dc01b376edfd42d6223c7dba44a9e5833d1484626072272915ce7f552e92e78d5552919adec3c5508c2084cdfca99228dee9e7e01f7fad976e2dcaced6c82c04f05aad40c7bf04ce6cbfb6f76ccf77cecaadf70f5bed8aa5e202c3dfc23c02174ae385d455d3fcc95df4d5ce5677c9c4e644d5a0384d33db5dbc670e2bb6dda99d1fa53dd7ce86e10eb8f49cb380931ae38a1fbc00b37503dbdbe66d93545b407cde600cf5e9b62c8494dec574b1826e4bed048fe406a96757e19080f8fc935ec05f626a6b3542048f3a678db1f684fb9471c388de7d3bfd3bac2e9dbbde3000c0745d7021b73cb1dc1bf60b91a9df32716819978f7a319d054baf47d2f2739c1ada3c52e228c45c648f3798915259e6ce30d737fe40cc33bb5883e2a2b65a5c97b8bfb4b83e1a8b145b8e3e47f9bf625cb4267268ed30565cf6f908c88a60dc709176fe5b61e32ec48db47a9746b507a7f43566e1a7decacf3e48a40c97c44f57a102df4aadc13a1ef52892a3ff39e59e9cf7cfca6165f09976171db6929b8c523164569c210c924392048b924a6940652b288cc4a40f49ee4b0cf5048e8ac88202582694c27ebd99f0498b07e15df6246444f180cb77936e69d41e6d1ea4a34a2177dd462d1ae229d4f26f07ff46cd673449e5066220c32a2ee1b6b19574b274ce19236b60154ba033a5060b6438f4d4e1508268d8d0a66d6bc465982a2652cb10c107fc676709d3ad2dbbd45c6761c224efe4f83b8a82524fbdedccfb1b47d5ac7d0de640e54068fc1cad6f115baed2e563506d2acdea6b7448263a62b929537f5fd0ae4a5201d5e62fc9e68280df3384ffe146de950c48b2343bab91a901988b1ed8ea9df2c336b404a6fa82010858bc6636ea4c179cd170cdf346a96a79c42ca8f2689d85e698309ab4f67e475a5e0c8bea103e65f885b109b1d9829ff01d36f8ff3e0af6967943ecd2d084bdeb46c808ab9f88d8b6a8305b5a4f42950ec953ec67acaccc0b556f2dbf43f00e2d57172cb81c4f45017af7f0889b981776dacda2c471832d3c82e359453f968f547c00831c5372f48ca9ed8f9be4389311c663522e6ac7d71c3dd048a8206e639f3dcbeb5956c33936da13711310b544d55c5cbedca0feeba63e6f8f334411c84695905046447705cd7ddf69e486475d78c2b342c00d55c18e9345c976196b3d2c4a15ecfa08a20ab0364e20ba311416ca4564a453294854d50cbd279d126e0fb3d0daf277d3dafe419167b9568289eb74f9d132af205c50b518444b11b579d05332d28bd00811e1a7182e436fc5403f0aae620e85ffee1dbcbb09f654fd89509e814d23319c31458ebf130bd31ce9c22cc00d512072dca567e499b2e533372329eb10064f353bfe2fd37be568a73e3687816c36bf3f8f5843d333a88ad81be636a1353950c2e22ebee07ea2b8d295061e7917789aeea9d1b5ecf4f7f9263d55d67d5f02ea35969fdb6a82def84fa43135c46fb9b1a06e744b80d85df2d235a23058802b6e8759a336e06a4d81594abba3c2f9affda78eac173d12c414a6647715c433f532d43bdae6325c8217765b5a152a5765baec0b285a5a6831dab84ebfc0efa475872d60f3fd68be45ee8db5fc3cc9f07c757bafa0d3eefdbca887ba284dd0a9293a0fbda15fc53fdecc2948efa68547ab69954313a26f9f7782ebaab3741322350b8b94a8b77d2c70b0b4e804cd272f3664aede252a57caccdad2c9196d491ba6cc9212805d07c0d4f09c3473c38ecadca31df2f6c854f4fb9fec1c09f36a3310fdf01a989fcfc3085d3fe001cc1417828f3c637f1a8ae74d0855228f7589b2ed9d271bfd0afa35700350019bca855412ac67732011e0329b0eefb750bfd6c95d836ccad627456c4acb763239ff0870043d35f9d07aaa7b78ecd8fa8aad02ab32d8e2a0ced0d5804de487890142ec3ec4342752f8ec51a2721bf7b4a314bfc4c97284f6c6e8f9b95311ef62c9e648ceada0e95374c1561c4735360ef1532afcca6b55975ed60b45005d1b15772d6b689c3a7a20de22a808937d3c6ceea64c21a733a187bd9fc26c94288f43c85517358d882a72f715a759dabdcfa1fc8a88d7a641ecc430d20a3623874147104be2a3a428d7995e992f19164279497af17689fa2348f81eeae75b3b68defab457fa89703d173fdd91e21d56e26f95d5de00f5aae3618cf8e5d00b3d7e9f86435001acb51729a13462a45eb759b11e8a3a597387dc51491bb8617561e1a49477a70207b16f406535f234ab0e2bf718d4a69f9f6c77da9c9ce0c3ca5878601b5665ee02f285d7989c7d800abcdb7bfc9685e164bfbf8f34666fb3013f89f25441af4582bdbfe4137d5ca39202c822965c4c99c75e5e098dbcbabcef3b1ed74a6307ad35d439033c073e874c2be1ce2acc0b88364034ba7724d08112bb7ba2012cd3ff2b71785ba2c589a882bfbdc8521872370e75c5c26a7f3727725ff745f1eedf18cd8e8adfb4c4a1e038846b420c68972bfc316a6ce3619d54c49739182551882a0ff9cfa9113034f61e165184f1304ed8f8b1a35a19a84c529782939f7fd4db5a963ffbab3c75053b377fbc57bd12dd3fbd7a78e721b0c6e75120c97cb2951120f1ca4f16a9fb9dd21f3a0bbf555db943c9c914497c08362e37db3a8abb90c31b03910c3be9feb6da9ee62480fa70b5234e14930981adec95ad16d9785e2555bac9e54c44cb276ac220a2eaffe70aad67051a2aa7b8bb70eb9110265476a3c467eab2d4b62b26efcc480ed161fe831e9ead1765b6c68678a2c7cd938c39409fd468aa8bd3f11c2bcec6266f9667d5054e6d6cb1b50f7f42069de7be18be7a9a332d80ccd4df2089a8636fc463ee0156a5842e9964bf1c5ed932233c5e1b69ff8bfcd8f749ad2753d39aba399401a37e66938a16f35387ad51bd5de670e7fa31616a39ba07c1e8d2c5844ccbd3d54baac735d11a505457c4d8378b7b86116736dedfd85b3edb30f5640f50ac4f3cadfb83476d76c4f676ad3f124e57f0dbaf046815a27bf9a7d26695fea3737cf087006312dd52ae127853dcb3c867406629109e2d40e1c3697c3aafa36bf3802ee0919a066cb2d459cb2e63a6511dbcc0bd432a04181f5fabb101305b298ca232841e1c61a4a1b702b019e83a841832dbeeddbb6f2f1995c2b3f218a0329f536ba9624b5abc22a05476bba6a61de07c4959608db220d82c8a2d8419234b9e0f6a1566ff30ddc200e2313206fc02e185fe297fb5ebf10ee8c078b9dc6fd5a74b96d37ba3bcd26293af7c86505ed83d903696f7df00d85498309043e65eb04ada8b3c62f0f36d2bc20bd32d8adfec149e0984678be5cc95c3cc8d74f3616aa18d3be44217d4ccb740f96ec68bf8e710f8a1f75091917b507a334dc54acd8f1724bff9bfb153ae6120cc2ca0d8281d5db03c5b6940a31a4bb105fc284e7281750ca98e55d08ab4ddc60bf9493ecef3f5224d5a9fbd967af80ec5c7bc1ef55dc9d2e53876522096543f85d498ecbbc67bf876b74c032ce1bb29aaedaf37abd85239c3a1b216ec408996d42ff81e4b32b0ba62a87ed680f0a66f231b4d94fe6cc700376e2f4487ac3a348b1ad9b2d19387115ef97baea23ed9d4dd1d32425db1fe39d8180d7a04efcba5e09272261da3efebdb4ad26e36e33753ac2de6caeb797a6601f8c84ceded75595b877eeee7e59e2c8e0c57c66b815ecca4f82874c2fd4c3346750d37eeecfa68a3dae7d86568301895b72185fe688d83d03b370a8d9dfdc71e41e6684cdd6104e55ff145b3acb485fd2bbfcdd8099c55b8a41aa74b959d575e001dbf29992ebbac2e46ec9831cb5b93c5d9d13e4ba37697c2cf7768b5c8cc5098b36d41c855b7438c62cc38d1b278032e4114702c2c225151393ba1b8465990680bfb426f0c9333f3dc66c08828d9d9aedf6bab9aa199611eeaf7d1fe9cbdd4e4539de06c04a97d442f98299a5a6d0b3b900f3d3efde518d51d47be8afb76a1bbb791d01a08953754fdadc3ad36ae716a3aeada5c63775c91d0faee5fe024c955d934c667390e118189912a72d6a6e502b836e3ad88e5b87c7dacb6f4e619586b69aad976bfd391b0b025f9753c88468631c7a31781ca59f5b874708d3a281c61255b6568d25db7d992f97febfc2e207346cedb7fe37821f1798f331b66fde4c6388f73688f54cd8f25a2c38766c53c48d0f6fca3c43d34a846bfc334116b0a5819daeedefcafe4f73864519359c2fbcafd11012a5f82b9a3e64faef074d675091d7d1a859a822118e3c8632f61c8559f7c41e5172ed3df2684192521a6de5656c75bcbae65301b4cbde6452b88baa02bd0bb3e9eca87f302508b63c58f58b438e47b38dca84d2783214d5087e2001d15a92f62765067138893e7a80428ad3c95ccc614b3e42dcaa35000d20201cb0c48e18b2898acbd8d34690cdb0c0cf74654301389a3d306ec0c6ae78bad5cf8087ee118a1f83159518cb63bcd13c541f9a231203174e4c09cab8f94141bccba3266aef3323b4cee7d2aeaf55236d71f9976b13ffcee890358c5cb634be1", + "envelope_header": "6167652d656e6372797074696f6e2e6f72672f76310a2d3e205832353531392049417861374664446e6836324d526b444b6a46375a7856543871326a4c5a6c5545384f5955654b31726b6b0a4b4e303753547769492f644865395861644833325a664674674e67584a532b3637752b50466b57646c466f0a2d2d2d2071796b634a7476302b3376324b646d2f437a535631784a4d704e5a582f49776e446c62526d3630767861670a", + "host": "d3b9b166a9b2b304971bf45a4e02d185ecc0b1d0920d6b67914e5651c823a2f6dca4595cb1a87480253a442ba86bd32fa6296b5a76723ead55a8f5484eec66d3cae15537801eb8b919370232e1bc423a6c14ea1b918ce4421e103913e6e72b49d6200421c6a6a95a0e48e029a691ca4137ce54e66ccd9a2bf257d9f24e3a57d5ada874b85b3961e0eac4384c62366bda9d0abcd8dc3bcc53fc63bdba5a64b4f3220f4a82afacfbd21259e5caaa17246ac90c8f30fd046dd99c7a89cf1f57a1c299f35da6c97cf3f5b91dda9230670762f366f9f0fb408ddf2d2c285ddf89e678f8a9489f88b5968af5cec162bc1197dc183cdd11c04684d1fa06d5ffd8d96986fe94ded9a4a54dba13ef82da01fac5b9a2795a738f966242849a81fd47a9df1dbed7781fd1171194282539fc9877a6a36a5a0a097eae7003b30a8778c90a6e675cc961c83ae203cef7ba380b4dbf6fb9a53faac2694b4486f319fa4560c5a4099db0c98bc095cc59d3beb2f2c9cd14e935674494128b2912b310c437a7b58e3cebfdee72eb0c70428936c1a0c959fa2ff33efd6559167538ce22e9e949c122330a9d038073b6cfc7e38bddcb8bf91b62ee79772c7886058e2d949c29327433cdeba1c79aa951b049c0908f1d33e2669b93f810455a921f1cfe0a0ed591da7d0059ce518b10a111ba85814c1b6bc674d25443604c171626f1781aaf8b9bb5f11abffbc2ec6c3061c7e6d52b7a4039ca43e341f33a2aad5c2452fd1f02e24ede2f4c4829f8c5a0194a7f67660eaad4ba2340976596218662e03dcafad12f67c544b6b35e285fd4b2ea02e08702ff1dde2058c9f3cd87a18939fa316327584bb82c891aa44b135ed843286d4eccbbaa3b032b677022328380cc246feb9ddcae8789e1e00e1f1fa2cbf5d5b704f7af8e2c3a82430dad07f9f472b2a017e6f460c2b326f090d18601eecc9b1b513a6024e3103b1e316d66aa315b73974051a4415cd7ae35f4128b9866638529c59a2c123bdbb9c5da7aeb40618052c1c2d983cca3a61e2c44e4c59a2e86fd1a17395522ee77ba4e88fa9c29b91e7bf569c06a762ad074a852244ffb4f4fd2d80ff6cc6a16077d8cebb2463c95e3eed915cce30dece6486ea72a2786a25de419a8dce67d8b59b92cd83609af6d45b20fdcb6dd793a1d5f8041cd718a18c145443aa67b5370ad48007d0b5f91daa6e34be851ef02baa81a873ec50949ad11db4665c3e822e94eafce39c204c4a3215958bfe90471fe509f8f66caaeb6e3024b72d4c78925e044acd6e069b173ccdd9409decb6b99d03b889e1959a5f7e63c9e62e7fb33b811e2c1c59407345030481ec0d4783bce6d7bcffb085da831842a04cfa871850f61ffc0fabbc0b40cfac70c5b6203dc09e7e5cc1e6b2a628e22db3444c57edbc00d413b53075ef2a73908dcd92d9240e3163bbd7c1ea40a084570b9968ef9d961e9c3c7b6e18c4435059750b987148911ab80e02938f3d64829e91d8ec8f4bdeb141108a877eba448738f656fe6c6b14f37bc4218678c2b40d229b4c4c2ae44b8d514f73daa3398ac6000be2583af541bc4529d161d6706da9d1f0d349bcfb4ff89b55a509363c54a95635c6ff94e9c7091faa96eeb891a8efadd54b2e235219088e0e1eeb55e3917ea312102a74baafd2124d5e3a2dab587fbd0d9e2167526ebc800d49ffa05bff6ff5677226d85eb4d1f21279806b3d254e277eb322e16514f2528b48f1b5d6d7da4c3fbeba0377238bb6c7bb12ed444c94df49879de1c2f2b13ba08578b81e3d08d92f2a772b02eb2259a307e7d97757f22c079db4b32e06e71df15b0502de748580f68ca7e89f6eca6955e6ae73554614396e9386073eac4ddda9a4dc6b9c07f2a597abc3a3f5d9c480d0774548bfa1d21b51b3b7b82e4938375c879bb2eeba02db7d027ebdd9f411ac012023b320da8bd69f601d0c7649696e2ec8d77f6449ed50ce03c2e09970f71b88193d02bf066b9737929928f208a25da5b102733e453b406e2b1bf6bca3a61ab6b6617077db9cae417a139da15fb44039af66e45c1ec284450e3f7869f62d510727c94a4e33ef75be901a2e4baecf61fd65180cd9ab588f62253f176c6d32ed48ab91e00720e761944ce735771ff83c7d7d6ae2b6d96db8c08c3bed240c1d7394a73635cc1fa352c22aad357ec8355a969ab07cc08a99106ec0879e9af70ca3c4affa1bc2fb0477046ceb3f7db8407cd05d7ef5264842769b09075f6aca28c7539f754f2ab43d8ac966547e199b27d458baa39df20e32f1c609eee59291778c3c6d85de8b18d7cf92fbfdefe76c1bb8b612c61be39c3c301c8d19ad5de56e749ec44dd94773388d7fa8b50cf75bcdb59ce97c0b87f6f23949f60c97ed889b81731d6ae155574ce2e71521e6c05fd994dde4e984340de4b71d875c1e6fdad9b46307c2a350fb3df9e03a8d2f596591c1681caa54dd07752519f79acedff294348a920ff4dd925fa8c27cf0477a4934d4201f51871fef4378cc76dcfaa985062ce2a53c031896ff649dd8aa69b6f6eb76e70647599f424744483837e97e6a302128200c304b4d7a8058495cd5434afd3f58eca2014be54c072c7041c510a8e105906a90ba1898d46a0b0d1f211b5c576435e47626d9deb4ebad549a102990059125474e4a7393e35aba91b38d00cb44ee06318f64199c3506fc53b209504b76b73181a4d2b4d298e04f5764e13b3a992300efb3caf2794b5a54637f316a603f0b50aaf478bb3ceff2ac3a77e309a7592a498eb9577eb8d7ccb989513f628f478415901dd02a072bd437257098c4c9cc8e67c1837ef13c38c49f791261c487391463886c815cb37f173176d8bb41b9c80a215545f84d28a77a58c3211d0a7324a06b9eeb2576eaeca7761efe1c3235b14190f6e34eef87bf857130f65d2764c703cce9883dfc3a8d8c90c99f4ee765f68263b073d26bb585cd2de50c8c98ab9605f91e95a820b82051b95dfcfad1ec4f26df443417c7c0727890e79d3e14203dab694f1fdc1e29e020173efd3dac567c0fa67890118ba630fd212e4a8bf1688d1e622e392c784e2d36ba887777a2df13ae43555cb71d9591cadd5c5b77b3e93f12f03ab91d1946d11b532385bc0eeb79d323f9bf263ba04e5d74b66b95316e07eb73f2196f4f9bba906b59306098cc85cc7958c8d240538668a5a49c480a3f4ce8ff05aa19b6f1b96816a94004314e7a021fabec880ff79a7366be4df988206cce768d0c222ff50737069137524acdf02ffe2be4dfb7e5ede03c0a011f8ce1a9952184154fdab1bb9767f715089897294a2db972899e56b270698cd8c6e3abd4432c9a7b05e2bf1980ed3b9fc5e3e4e446668467b4cc418276533791a569305bb33feab43a85a81cb743de78baf5f5ed8206db1a9db4af041c599caed6cfa9d2a6bc6101e8346ff65b861547487de89bdf6d67f6b21ef79e124d2a544721a8f545a658e7c9c0010d0b926912488b101c9e975f878d9fec63b7abe2998a11f12b9a76f35fd727e732954e15881217bf9b9539c1a5f85494d9e7fd43ce04350deda64793fcec67bf2f5250a2710b33689e135159fc339ee75ed2cb0c756f862c9aae981ed78b1cae302a96414a44e90c7b6a59311ab62508d614560e4534dd7e49dd3f8f010e5186a916853fba9dbc0f1f67cdda894de813250f80e49c1419871e6b77c20c13dbf8ea78c05f25c7ffb6918fd99e0eb3e406a0e99a44ad5121dd88977be14dc883b2e955a050c34ca9bda58205924aa7ec2659b374e9db003466710da6bc5d854646573e26e6dd3a30773cbca9c3e4013fe63e3b754bf72d48d0a0772082241db5442b557ddab94f0372d8753df7c45f58e6ea8227954e6e2842efb44b51da6ebfde2ebd0ca97fae3981280b370f2e298006559e4dd264be171da97e5b1d673c30d5ddb17c76fdd894710658f58583a7ce27cc04dbf3b3de8723df896c0c70c04a1f3397ebae43441b81290e52263beed66030d163b6efe5523fccec4d8cf5bb0f108bfb5cdb482fe0b381c0c2b93ae336957ff08408ec19d90a37fa97b175e8caa459d26cf689e3ee704e1ac0dddda1c91417ffe6ae2ffb4a85be359cb18244ec750d542e7afe343ea999d4ea882da7731d60766f81902b768d281ee47ee0cbc302ba28eea2ed34fe4bd4121f85f7918adc92b3fd67e749340787e17359ab3db802fb14e4c2897a2f2e30c40823a3b3bcd110ad78a2689c9bc0a0d9773da3d14f6ff6f14f730dd4a5462e5a47597997bbc6b96bff60fe1a55e2ba4089545184c0b0a973847130fc1324aa7dcdd29896f185fdd77b4800ef385de9d6a6259401f342400c314fc223a1bcbecded2dc7d0b7e34e0fd4c6d2c4d76a36a18cdd0b3f25e98707ed0c1c36859a635b5a09807fbb62edab178e17e42fb4fc7d415d0efde0e643b1cca0e10e05ae67fc93224aaa6287e068d12132f6c26ed78f756d566f83c833413cf9be11b74fabd3bbcfc5a09c346c656149b35ada313d71103862466e18abfece1b5de30d7d2da04ccbd68933cbffdfa3ef38317d0499bf04924582dc6f54edeef6b39df149eb3f386a602a812a01b998c2d54745feca7647c7ab6aba562dce1ce38aa499cad7c2c31bac32c5f2ccf512eb1bdfecc2949e44e9e8e0d718a9f11eb7d8226f8f6a0ca8d2ba55f76f5f52585aba2040797e4936af23bd8409dac6c2a9e72a25fd656889d2f85cb1ca61b4bc97eb4400c63a868af10fe6e0bba88260ec6f9631b6cf1f43c321e5a8507f2c9388173e113573737513dafc8b169bae1d3ad447e1f63d318d33f7c6a36008598aaf236f4cecb705e8925a140a53f4c935a269788b80c55d97571d2526f9fe7e1e88e3d76a2b9820f8ca6e590daec76c9e1d94b1e0e7d87f1160e3be70c3544e5620131fe3cde24da788b4f8e6c466a1525369829d563c21e6f38ea9ef40ee3a31a44bd11f48824dd6019c590ded7f60cde7d61dd36c122f187252f5af081090f14557ca930d061799beb24c67fbefcce03f21440f5d8631bac2419a5b3f56bd1bde054a8096bf16cfe0885d0ef33dc56fcfb951a371eaff0d5cf6e099e512d0d6e16afe5b753bfcb85e325262e2faf6e843478a060a64b5adf2c6038688c37e7e3a8a0bed370b3f8d847e77543413aed6cbec13ac64d6f751d18a3a805ef6741594111b068012a10e5ae943b821069c48efb76c9e9a57e6cfac6a1cf9bef28478d40cd259831aec9d088a2eb5c65ef2361df3e9f657dcd258af93d0780a0be390ebc532ffb45e5999c028f3e762849f9e20e9ecba400539c24ee9fcf5175868b6d876edeed19295640c2acc0852573a89f356ff43f0098439c81800dba4af9c666fd865790e73801ca4e010c12e65495cedfeb6669f7fc149b3b4e6da63b91ecd11bd8dabdd8fa15b2c885a1522a674e34aca1bdc9f5fd3551d0e20a49541d59b653d6a84a2e73289ba8506c1226d60a8c5aa3da866d1f88b75451a893a1e4d456712bfc53aac071dcaad92cfdce420d177a3405a7d89650c29a9040f6517cfdd93a10a6d7e40ce5cb131f0b1569d5a76fb6d51500dcb096d40faa5c04f7220b16f92e465a0de6e3f952e98a55250f02c9bee794825b9d2214f08839e65dd0a3a33af28258e53888926a18cf9168c24a6cece5932e7e114a1351949bead203b8a7912d5c6a5f2e00772ea18fca970e6d02b8113198ead9c36a73b2fe4d12cea0469cb28cbbe45f31e99608e18eca6ad113d12e2ef89e1f5ba3a6eca32288b1be7f951670c7d44f1017dd6f757fab16740c3c3622735a2d8ae90f0bdeca0c4c8e7ef203e2a08868f3755c21fa2fadd4121531344127022f046b34e1ad1c9066afc744fe1bfa5dbfa8c0ffef4ac6fe9960f06b4defad72ecf6efc39204a95f3d27aaf967d43543cf0b3e3dcc932bfdf6234f852b4817e6c21d0289445ace8c7749e314a8256e81c2a82cc414ab60948b1a9a60dab4b86e694689e4d160f2ed1c39971b27171bc7fd1928aa80404433eddad382f92e672c1b92578be6494bc13694be1c165bcbfddc4228957afceb5c867b85bd11c00d50e9c5722907f56dee6f3c45445be0283512aa65b0214ae2927823e941eae8ebfc215cf34e9b14bfc29645e2a63548f022deb49becdf344f1362890c1b3c39123e172c5092bc329a525d3386bea40c6a22d0bf8a8865387496126e63406d163a1f02944418fd8373afd863334ea510534e115e7f4999b4f4a4314ba43955a743a678d211b61b8a1e8619550bcb90816f18845989d80e9994b0ffc1c02236bc8651d5a1a520578df7368ac97715a8d88812944b4d97dfb57959722460388cd39d1d5e06a125653062ea6351943cff52fb7f6350538b80cdea1f3f2370385e87b9ec1aa6916174c4487036787ad62183706cf88b2b9eba7cff2a5a0eca6c1577fa2ed872c7f333e0e18e6479e8ae7060b7dad0a78ba89248c8db0412f251181ee6054c1e67ec4e5f3536610a8acb4cc03e8b06c378c294af6d58acbd8a5ba5629617b90b0fbf01b158d487d2d76d889268feabec421b222e30ab3fbd8cbe6be9ab2dad2b67e1c871d1ee7de65eb160b674262a57a6942e24e1a4210658183eba1dda62dab40c9811e34416ccb9bf977e1a3c5dbb51f0b1cd6d7e855cde268bcfd361a646b2cf65f5e7c6ae0f18001ca16a97ca11c60fbda5146e5574409d06d24a0892a0bde605f5ff0fc84354a2fcd38abe7a9da7049d8fdc966aebaa213cc8bd9e73b1773b6efbc51110865fe1c4464998d682ee08942f48dc01b376edfd42d6223c7dba44a9e5833d1484626072272915ce7f552e92e78d5552919adec3c5508c2084cdfca99228dee9e7e01f7fad976e2dcaced6c82c04f05aad40c7bf04ce6cbfb6f76ccf77cecaadf70f5bed8aa5e202c3dfc23c02174ae385d455d3fcc95df4d5ce5677c9c4e644d5a0384d33db5dbc670e2bb6dda99d1fa53dd7ce86e10eb8f49cb380931ae38a1fbc00b37503dbdbe66d93545b407cde600cf5e9b62c8494dec574b1826e4bed048fe406a96757e19080f8fc935ec05f626a6b3542048f3a678db1f684fb9471c388de7d3bfd3bac2e9dbbde3000c0745d7021b73cb1dc1bf60b91a9df32716819978f7a319d054baf47d2f2739c1ada3c52e228c45c648f3798915259e6ce30d737fe40cc33bb5883e2a2b65a5c97b8bfb4b83e1a8b145b8e3e47f9bf625cb4267268ed30565cf6f908c88a60dc709176fe5b61e32ec48db47a9746b507a7f43566e1a7decacf3e48a40c97c44f57a102df4aadc13a1ef52892a3ff39e59e9cf7cfca6165f09976171db6929b8c523164569c210c924392048b924a6940652b288cc4a40f49ee4b0cf5048e8ac88202582694c27ebd99f0498b07e15df6246444f180cb77936e69d41e6d1ea4a34a2177dd462d1ae229d4f26f07ff46cd673449e5066220c32a2ee1b6b19574b274ce19236b60154ba033a5060b6438f4d4e1508268d8d0a66d6bc465982a2652cb10c107fc676709d3ad2dbbd45c6761c224efe4f83b8a82524fbdedccfb1b47d5ac7d0de640e54068fc1cad6f115baed2e563506d2acdea6b7448263a62b929537f5fd0ae4a5201d5e62fc9e68280df3384ffe146de950c48b2343bab91a901988b1ed8ea9df2c336b404a6fa82010858bc6636ea4c179cd170cdf346a96a79c42ca8f2689d85e698309ab4f67e475a5e0c8bea103e65f885b109b1d9829ff01d36f8ff3e0af6967943ecd2d084bdeb46c808ab9f88d8b6a8305b5a4f42950ec953ec67acaccc0b556f2dbf43f00e2d57172cb81c4f45017af7f0889b981776dacda2c471832d3c82e359453f968f547c00831c5372f48ca9ed8f9be4389311c663522e6ac7d71c3dd048a8206e639f3dcbeb5956c33936da13711310b544d55c5cbedca0feeba63e6f8f334411c84695905046447705cd7ddf69e486475d78c2b342c00d55c18e9345c976196b3d2c4a15ecfa08a20ab0364e20ba311416ca4564a453294854d50cbd279d126e0fb3d0daf277d3dafe419167b9568289eb74f9d132af205c50b518444b11b579d05332d28bd00811e1a7182e436fc5403f0aae620e85ffee1dbcbb09f654fd89509e814d23319c31458ebf130bd31ce9c22cc00d512072dca567e499b2e533372329eb10064f353bfe2fd37be568a73e3687816c36bf3f8f5843d333a88ad81be636a1353950c2e22ebee07ea2b8d295061e7917789aeea9d1b5ecf4f7f9263d55d67d5f02ea35969fdb6a82def84fa43135c46fb9b1a06e744b80d85df2d235a23058802b6e8759a336e06a4d81594abba3c2f9affda78eac173d12c414a6647715c433f532d43bdae6325c8217765b5a152a5765baec0b285a5a6831dab84ebfc0efa475872d60f3fd68be45ee8db5fc3cc9f07c757bafa0d3eefdbca887ba284dd0a9293a0fbda15fc53fdecc2948efa68547ab69954313a26f9f7782ebaab3741322350b8b94a8b77d2c70b0b4e804cd272f3664aede252a57caccdad2c9196d491ba6cc9212805d07c0d4f09c3473c38ecadca31df2f6c854f4fb9fec1c09f36a3310fdf01a989fcfc3085d3fe001cc1417828f3c637f1a8ae74d0855228f7589b2ed9d271bfd0afa35700350019bca855412ac67732011e0329b0eefb750bfd6c95d836ccad627456c4acb763239ff0870043d35f9d07aaa7b78ecd8fa8aad02ab32d8e2a0ced0d5804de487890142ec3ec4342752f8ec51a2721bf7b4a314bfc4c97284f6c6e8f9b95311ef62c9e648ceada0e95374c1561c4735360ef1532afcca6b55975ed60b45005d1b15772d6b689c3a7a20de22a808937d3c6ceea64c21a733a187bd9fc26c94288f43c85517358d882a72f715a759dabdcfa1fc8a88d7a641ecc430d20a3623874147104be2a3a428d7995e992f19164279497af17689fa2348f81eeae75b3b68defab457fa89703d173fdd91e21d56e26f95d5de00f5aae3618cf8e5d00b3d7e9f86435001acb51729a13462a45eb759b11e8a3a597387dc51491bb8617561e1a49477a70207b16f406535f234ab0e2bf718d4a69f9f6c77da9c9ce0c3ca5878601b5665ee02f285d7989c7d800abcdb7bfc9685e164bfbf8f34666fb3013f89f25441af4582bdbfe4137d5ca39202c822965c4c99c75e5e098dbcbabcef3b1ed74a6307ad35d439033c073e874c2be1ce2acc0b88364034ba7724d08112bb7ba2012cd3ff2b71785ba2c589a882bfbdc8521872370e75c5c26a7f3727725ff745f1eedf18cd8e8adfb4c4a1e038846b420c68972bfc316a6ce3619d54c49739182551882a0ff9cfa9113034f61e165184f1304ed8f8b1a35a19a84c529782939f7fd4db5a963ffbab3c75053b377fbc57bd12dd3fbd7a78e721b0c6e75120c97cb2951120f1ca4f16a9fb9dd21f3a0bbf555db943c9c914497c08362e37db3a8abb90c31b03910c3be9feb6da9ee62480fa70b5234e14930981adec95ad16d9785e2555bac9e54c44cb276ac220a2eaffe70aad67051a2aa7b8bb70eb9110265476a3c467eab2d4b62b26efcc480ed161fe831e9ead1765b6c68678a2c7cd938c39409fd468aa8bd3f11c2bcec6266f9667d5054e6d6cb1b50f7f42069de7be18be7a9a332d80ccd4df2089a8636fc463ee0156a5842e9964bf1c5ed932233c5e1b69ff8bfcd8f749ad2753d39aba399401a37e66938a16f35387ad51bd5de670e7fa31616a39ba07c1e8d2c5844ccbd3d54baac735d11a505457c4d8378b7b86116736dedfd85b3edb30f5640f50ac4f3cadfb83476d76c4f676ad3f124e57f0dbaf046815a27bf9a7d26695fea3737cf087006312dd52ae127853dcb3c867406629109e2d40e1c3697c3aafa36bf3802ee0919a066cb2d459cb2e63a6511dbcc0bd432a04181f5fabb101305b298ca232841e1c61a4a1b702b019e83a841832dbeeddbb6f2f1995c2b3f218a0329f536ba9624b5abc22a05476bba6a61de07c4959608db220d82c8a2d8419234b9e0f6a1566ff30ddc200e2313206fc02e185fe297fb5ebf10ee8c078b9dc6fd5a74b96d37ba3bcd26293af7c86505ed83d903696f7df00d85498309043e65eb04ada8b3c62f0f36d2bc20bd32d8adfec149e0984678be5cc95c3cc8d74f3616aa18d3be44217d4ccb740f96ec68bf8e710f8a1f75091917b507a334dc54acd8f1724bff9bfb153ae6120cc2ca0d8281d5db03c5b6940a31a4bb105fc284e7281750ca98e55d08ab4ddc60bf9493ecef3f5224d5a9fbd967af80ec5c7bc1ef55dc9d2e53876522096543f85d498ecbbc67bf876b74c032ce1bb29aaedaf37abd85239c3a1b216ec408996d42ff81e4b32b0ba62a87ed680f0a66f231b4d94fe6cc700376e2f4487ac3a348b1ad9b2d19387115ef97baea23ed9d4dd1d32425db1fe39d8180d7a04efcba5e09272261da3efebdb4ad26e36e33753ac2de6caeb797a6601f8c84ceded75595b877eeee7e59e2c8e0c57c66b815ecca4f82874c2fd4c3346750d37eeecfa68a3dae7d86568301895b72185fe688d83d03b370a8d9dfdc71e41e6684cdd6104e55ff145b3acb485fd2bbfcdd8099c55b8a41aa74b959d575e001dbf29992ebbac2e46ec9831cb5b93c5d9d13e4ba37697c2cf7768b5c8cc5098b36d41c855b7438c62cc38d1b278032e4114702c2c225151393ba1b8465990680bfb426f0c9333f3dc66c08828d9d9aedf6bab9aa199611eeaf7d1fe9cbdd4e4539de06c04a97d442f98299a5a6d0b3b900f3d3efde518d51d47be8afb76a1bbb791d01a08953754fdadc3ad36ae716a3aeada5c63775c91d0faee5fe024c955d934c667390e118189912a72d6a6e502b836e3ad88e5b87c7dacb6f4e619586b69aad976bfd391b0b025f9753c88468631c7a31781ca59f5b874708d3a281c61255b6568d25db7d992f97febfc2e207346cedb7fe37821f1798f331b66fde4c6388f73688f54cd8f25a2c38766c53c48d0f6fca3c43d34a846bfc334116b0a5819daeedefcafe4f73864519359c2fbcafd11012a5f82b9a3e64faef074d675091d7d1a859a822118e3c8632f61c8559f7c41e5172ed3df2684192521a6de5656c75bcbae65301b4cbde6452b88baa02bd0bb3e9eca87f302508b63c58f58b438e47b38dca84d2783214d5087e2001d15a92f62765067138893e7a80428ad3c95ccc614b3e42dcaa35000d20201cb0c48e18b2898acbd8d34690cdb0c0cf74654301389a3d306ec0c6ae78bad5cf8087ee118a1f83159518cb63bcd13c541f9a231203174e4c09cab8f94141bccba3266aef3323b4cee7d2aeaf55236d71f9976b13ffcee890358c5cb634be1", + "host_offset": 3000, + "locator_plaintext": "a70082a200781c68747470733a2f2f656a656d706c6f2e6f72672f666f746f2e6a706701190bb8a1007842697066733a2f2f62616679626569676479727a74357366703775646d37687537367568377932366e6633656675796c71616266336f636c67747179353566627a64690158200ac808598a3da15de6cb7044f8a7ac60a55c2f1a64d7a36d17c79b74579467810258a86167652d656e6372797074696f6e2e6f72672f76310a2d3e205832353531392049417861374664446e6836324d526b444b6a46375a7856543871326a4c5a6c5545384f5955654b31726b6b0a4b4e303753547769492f644865395861644833325a664674674e67584a532b3637752b50466b57646c466f0a2d2d2d2071796b634a7476302b3376324b646d2f437a535631784a4d704e5a582f49776e446c62526d3630767861670a035820a62604fb56d89d37627c9070de21dd62ae22ce26fe28ae01a6b5ed782fd543a8041913a8055820da2c0d2b02e604e0741faa44d90abebe7dcf83dc376addbca1d46782c89ed9cd06590e7700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "locator_sealed": "6167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b203130303020353264623962613730653063633066366561663738303364643037343437613166353437373733356664336636363137393262613934363030633834653937310a6b4e67484f775a434135654b516832444c516c55753949464d7869654f702f784f61457a734f5161535333782f65523734586c6470696b64643730616c6c712b0a416e343454377876385334456f65796965526f4f6d5a43376a4c396256394469506e564d3046385a5264436d3245576868496548685551726574374b774a444d0a64687a756862494f49353964556e4b6764696566795038505a656b7a6b43527758596862456f67485957770a2d2d2d2059337534684437433451557a34507378436a5951514e42526a64746a7a6834656b544e4c726f6c78426e590a65ea20b4bbc9da9f24a8b9f18cc00c6bc50207140801897dc9ce71b8012bc3b126f5510fd01f818d6852f8ddc117a3152a3e760eb634928de17e708f5194f5b20a0a3067e418b57a95df7b2c9cb2de42c603399a1056bfc65f38152bfcd58501b252a5f5b36996eab5b63e8c44fa72b28c60e913caf3579123d5c1b167749830b7adac1c12a9059295725ed717d50f1d0065c111bd9958177408aa585d905a530ba41aadde33da6d9ac5f4976e55894829a955d143a94cb63d8c12b134704c707a9e4b696226a44a9efe4fe156425727d9c9e0f67b79a206581d02c771a0443da59207a4d1a4d40376ea0c8cff8444d41bbfcf228cc2d044ac5e1c834206e036b44cf9fbc8930f146b9cc1ddbea46f173c9ebffe705de2afed9a730c9e702090ba0104641199449b917916e45e7b7365bd8a7cee9f39f728801984b39fced931e6b326a3a30bb17b41697dee57bacf01578d86852efb16a9c0d8ababcbb38c8cca7bcb90d8bcce8cd1b7740360c21ce702c0948ab9747bbbe57042117d9e24f5b46d847d893ab1ba61c6f5e857794219db7f1c620e27e80f040282287fb47894766babc1178356c3918cbccbc4ce29e04315ff80a5f2de8c8cc6e47809ab9e0455406e761219f11ab80f85241e9bc870427d04b1568ea973fb46f57446d3ddfe2a774ebd1afbe82d56cf88df8ee24b34d4f788ba03e4c28eee79726a48140e4f7545253d8a0116b81e876e05530f9efd7754a63242d6a514975235b73e14dbd154d9b44c1a192f134e20b38f90fa5b856853d3a4297dfc48d8b43916cb3eb902d95d6f8a5f45457ad49dae3de83ff8614befc6a351205e66d8f812a528db70b6b53a52be8a4f1f30ecf2486e57cd6c7ce7cdf363328fa058c4b0b03007b89d1cf9257142a7ddd52a7d5ab4aab79a151e62d10835a4c00410968e41c951644a7d2772334a097a997a1b6031fa59376c0e0932cf71312c71c630b53c53d345315f369961260f8ebb92610f9bdce1413c6cb2be47885093f278008f349f3e5df44b925db20c1caa9afdcba837d5a6ca1f4f4b2e83b81bb3e62fb5053ec4fff01ab6f8a39bef140c4f35287ec105dccef8dc7d9f8736ed475f916b3e20767bb4067b9b7624a3ca81a6719662bdaeff3c757e81f8865cbd42dd84b93db2a3bc758e9a0d82c6c88827c5a27ace0c565ce22edf458d9ae008eb69abf74bdf36f883860aabbba9b5912856c9d32fab5c5c2b2b242a64a1f9d0d3ca466207b4553586a242f81c396de605fcb001e2d34e25d1c81bf14f5e31842c071fafdb6d2a0552b57d6eb08843d0b3fd8f7e9807723e3e404ea7e5a0275df61ef6be9cbf4ff74ef5df0184531641084bdf7bc8dcb13085d77581dc3035ae73e59ac1f9289eea23808c7bda710232230e7f2342df1657e3d302bde341b8c52a56cea90dd4727991386670ac765a27573806a738152e5432a7acbb34453c0f438a6359e9b966084a9180c692a3a212b8ad5ddf52286d4768203a2cb2e602812688a696b1b17de688ce5839d6d89252f30f90641f0a730840f2c105ea68518c8dbb74d82dcc5115b2fdba5cd16c146eb0963d2575600e22f87b1f914268583b19602d92e2ec5e76ca338fd1e15a61fa92ccc3475283e291185a23de78ec9064092afa5f2a4cbed83b56c2d75784f4764e8fdd04548a4e1cf849bf4e2bcab8c412767fb8507b4af37aa9873ab0ace2993848acf670727c327367c20defc285f1153e17283daec4ec28164ae028ba1183f23b32c971fb4248809c2cdda32c5fc74aa291665e5bc3703536f5ad60514948deae0e3994a76cb305bf666c9e8b255d0e4de7330613d650faeb8ff3f797e618a8a6f5622c3c9f7d645c4cf94d7aac1494c5260eaa6b4957a5cc5e0096697c8989a87b61b50d7dcb487b4f183578741bcde8df3c2b6602a251703ac8522e1b4a7ecba0a458f7832e1f4abddeff1ea7d8390158778248c81f9aea12c78dd9eccf08c16700d006fe80e3aa92af343dd1f67c46868f6da781b983c6ae567fc2213864b0a89d1da73a1b72f61d6e07d3bc987bf2dcb36a9e981ede9115b7714d52c1514774a631448240333c8e98ea2915ac5d7b2e300df3d7da8ca9d73c3753bfb0999b59cf9ff24a28c976c454d0e878c3422bb32c5bf0aa413a2f2c232df71ccf4f9412bfac58d9186dfb820c47fabb747ae3828600d6409af0ef2baeca226cd435f5eb4316a867e56627ac723380e6e4df463b3065f821129bace999a509ffbc30bc8fbb741f71f4f0aa9ceba9855a75ea9297eec9f834ff3cf6ed44a3712e2724a9a94716ef2a8d4a0225a5a3dd3894848be32f3a7e1bf14605bb0d1a91297e96ada0589171b0aa20666efc9e38965fea23f567d61b96185364cb53a4ca03c7e54b6c47fcc8ff7197a3f777ce01623627dc2d526151e65c408ab742c4c30cd7145a290b00893e9a312cb34c9205315173ab5696fa02be95641c306b5459c7cd9b01a5a93ef55ad0099db0cf081f069a2f7f7984f69574b9a9c7623c32f0f3da774fd0901ddacdd89acfbc27810efbcae4a0706fb8d597a6138404a823533ed6156377fe2b445c6c7819503cf29f5291912d68ecff2a27f0b79e3052a3950ce1c14fefa538cf11992e14ef4bec75fcbcdfeea29100014455309ef600711b6d4ebb43c7de994b3024be852832cbb06e2b67faf9d1c5596d3f719d9b42f9b182945ffffef6d1cfa0c77b1acb6bbaa25ed6d8d8e7416264baa7cea0290ff066e71f44f4fa0eed8ba79bb13b76496666cdac31faf864022e9fd00cb485c54cfe1662a9e773c51c3726464f4f131138ca23b577ce7ca60c5635d3230971a150afa6d9a3dd812783baf22abdd1709db9091a373be04067dad575357085e343349261dbf3fe963a95a3898f2ce34334262bed0fce9ed3c4141b31430bff947b7bbc7233af4a2937361a1bc8a39e978ea76928befced13e78733abdb7585a5e38ba2e164487ec92b23dab673573f6e9bf335fdf466c011380f81822e9f0cfceb27072e08324fd1936feb33bfdd8012af9d31d79be5c7e9c3caf635df1e6d9490943f66cf0d688c84ce8f4e631e22c118d0841446f8e16338f876c7ed3575cf4990c104ec14d2149772079b71e2913193410b81e068e058b71852e80b3425101cdd66436ad475cdd792a67e9244b8cb752893624fe96446c10a3b6cea8c85ce27b54ac8d650dc9a612edde9790b0f8cd859309c35f10e120e70770e931a7198b33f2a0b128d1aa5874cb8ac17b55a3aa2446e0c29d7bc07d341819fb3ac7084ef6fa6c2ccd1f7edc1be590878e8c22ea882b08a8877a7ea16e3bea6ce6a59e45095a90992a6497eb92454a75f24e78ea0c462d28757f0296261f1524027a8cace29dcd2882054c2de59820b37ceb81b4c74574f8e7272fa01771e9f26c2202d017094dcf9ba6dfdc83b6cd58aea5f3ccf5e6e065c1521e55eec06d06ed137e418bf371652eaf02a3f283d55725330edb40a33b02717e8c6bcb437b4aca7f6e1373f8f33f251c15d3f064c3ca5cb4a1696ef0e0dbac3572d760598bd2a9783b1d33e9f19f3dee0b2b4b6218a94a446d1b1bdb3bdb57d70675b434cdf87721bb910bd808e34498ff6566ba84d328afefe95b0ebc3f8a2e0bde53f02c729ed4f5a5151d0ad1aef4b5741808e955f50a3dcaedeb80c3b33494ac2d94b54881349efa1b9b560185bb6039588efcfb8b63c8538f48700f5d592cb08afa2b7cca34a5d3d972faca8553f74f8ded46b3dbb85f92f976dbb59ea59f72606daf1a62e164f37febdf44111a88b19ff1ccd01afb4adf6dc0fe59c2ded959e18e5cfd4ad37398d23e1aa672b67442c5cbc9ac31d3f94dd78976b3b6271e427c7a3d5d0defc4f5dfc7e61a10a6cf460195c551241327e42cb21a4a6bb448175b8bb3210efbb95eb9a69d94b03eb36233aceb58cdb1ddaaba9b4bf0bcfbb252063200f1829f30bf895e652c1062950117cd6f5662ed29c75a162ff60fad395b386337c8a4390bf0a7b4bd86e146404126265bd511909438f1503edcba451286d9a550e86b4a23125819510423af3097d3f786d7e3d6a7309245468eb8be478d7c627425b3b8c46ea2cf2b63169cc7906a4f879b60d5101baaa72b7a5a61fdd00c44bdf2d129d305779909730a9a49854c8f40c87f709c828591d926adaee844e5060ba168fecd5d8a07ca859d96683e61756a83bd2b2c21abca699c0df9a79784f12ce860868ad93d064f0577d6810bc0447e97de386d3df5956cdc534813cb5a6a0eb52c06855d69b0d16b3e086b1ad1c262a1c6022893c3c456a68f5ae083b229bed0b4422c0ca92285fc12913d83c6e6dd5b81dd1145848be2b44f638e7a97a7bb7b6141ad402c62e02104dd953d9cf3f26a10a1f869d873d2e4485b1c072ebae52f0dfb5a7c76e1b9d4bf2994862ebef8d0b64ed6b9bdb70dfd858277dbae2fd2c930ba5f7a6f946f75d9c10708eb099f81382875dd39e422e73387575eb8c8fcfb1b47e69e695aca4384d43fb0dda680b641612a5354bd5f51433607a6825850c83344fb789e929a29b09b45f2bbab2e42be4b02fc2a9ee4901e23211b72cded2fc852fb03aa434a4e24e6fa32b89622a4269c89494870a79a7c32c932cb1bf49124367a6b28b8a3b41f07f210e4267c386bff7bd84437d680e8cf0a2c5e98fbae26397fc7c6aba6de55105568196b7101c0d9042f1ab21b56db460b865cf8512516939ffad9232afc6776345412a28693b0d69a0ae0fd2f4524d8f0bfaa4b9cbc7d3690cec950034197b3f3b3ddc8aa9a54fd80b565aaa4994e4b9cbe8de6a61a21808ea77751f85e8af0d2894363b45771b2e1016c37bec7966383d46640855fb06fb7405bdbe07ecfdfdc5b3e1f035cb8db4ff47ec73dd6fb7c50abd8e977b60cf968f0c1139ad632aa27fd0ec2e57f15e5d947be0249d5d6c3c512bb8d4b4472b888529ac34f3de2d158a72956d1fd6c598e69e4bea43d94f483071f17cb800c47ddb388342b1cf9e5d0fe56576f01d9c790b801db2ccb393bd9b4c7ce03fac2c3bebe3927513e20f63f07aadc9cc3d14d6cc8f34ef2f8b64b02ad30c69f5643a1ecd2424efaa31f5c090a7bbfc07e16e5307ed5e6750c8fe47ac50620e1f8e17d996a19a41b7563cc83f48169d95ede33983f1d08145ab763056b1efb71367bf46eb3efc2ac7915886987ce7d0e6c3c096b5e3cd79979a318676ef03e94bc09e167cc39b5d07ac2af1e37b6046e5e9a9a95a6d5d0f377618a2619b182f8c4edeb94b0c97f00a44dedc6c708722687ba3de5fa5090e59c911a5b79db584b8bea5552234bd057ffcc303eb5fced6a7990d1da11911041a0a3c4b7c8d5687af57b0195150ac0dc604b71e00ecd76463704cd2a553019c65032adea9406e56169323aa57ed2fb4736c2e5dca1076f539e6169115c43d5f55634bd1c96979620f4ec3bb7cc5c0cbbc0dbe8c67f04e74df97be8c618d75940a95dd1e05bef1fa2cacb6663a1646df626f013a715a81cc93b5e04fa7ec874f529c1e6ea0140e1022e046ab99c34a8e44750f8e0f8be5644767604c708a1f866b33a80bb2df3c545899f66fb8732e432ea53358ee2612460d57cb960f5440c75b5b2a9cd4b6bfc09f67e861377ab4608ad9bd80dd76a40d172cdfd20784213451fb0dbd023b610efb47bf9d0c0e79c3841947af24a42e37d95c0725afa92b5eb1740cf6d73c39701343dff1e8efb18023fd680a116112a4c0536afecec0f8ba648576eacce35eb946c3ed6b804d0446fd46b89fb80f4288c349d0ee58ee523f3219106f1e18fe9e2d4c983fb6", + "extension_data": "a30078194361727461732064656c207669616a652061204c6973626f61017853646b315f65794a325a584a7a61573975496a6f784c434a755a58523362334a72496a6f695a4746305a57746c65584d3663585670593274755a585136646a45694c434a79623356755a4349364d5441774d4830025911636167652d656e6372797074696f6e2e6f72672f76310a2d3e20746c6f636b203130303020353264623962613730653063633066366561663738303364643037343437613166353437373733356664336636363137393262613934363030633834653937310a6b4e67484f775a434135654b516832444c516c55753949464d7869654f702f784f61457a734f5161535333782f65523734586c6470696b64643730616c6c712b0a416e343454377876385334456f65796965526f4f6d5a43376a4c396256394469506e564d3046385a5264436d3245576868496548685551726574374b774a444d0a64687a756862494f49353964556e4b6764696566795038505a656b7a6b43527758596862456f67485957770a2d2d2d2059337534684437433451557a34507378436a5951514e42526a64746a7a6834656b544e4c726f6c78426e590a65ea20b4bbc9da9f24a8b9f18cc00c6bc50207140801897dc9ce71b8012bc3b126f5510fd01f818d6852f8ddc117a3152a3e760eb634928de17e708f5194f5b20a0a3067e418b57a95df7b2c9cb2de42c603399a1056bfc65f38152bfcd58501b252a5f5b36996eab5b63e8c44fa72b28c60e913caf3579123d5c1b167749830b7adac1c12a9059295725ed717d50f1d0065c111bd9958177408aa585d905a530ba41aadde33da6d9ac5f4976e55894829a955d143a94cb63d8c12b134704c707a9e4b696226a44a9efe4fe156425727d9c9e0f67b79a206581d02c771a0443da59207a4d1a4d40376ea0c8cff8444d41bbfcf228cc2d044ac5e1c834206e036b44cf9fbc8930f146b9cc1ddbea46f173c9ebffe705de2afed9a730c9e702090ba0104641199449b917916e45e7b7365bd8a7cee9f39f728801984b39fced931e6b326a3a30bb17b41697dee57bacf01578d86852efb16a9c0d8ababcbb38c8cca7bcb90d8bcce8cd1b7740360c21ce702c0948ab9747bbbe57042117d9e24f5b46d847d893ab1ba61c6f5e857794219db7f1c620e27e80f040282287fb47894766babc1178356c3918cbccbc4ce29e04315ff80a5f2de8c8cc6e47809ab9e0455406e761219f11ab80f85241e9bc870427d04b1568ea973fb46f57446d3ddfe2a774ebd1afbe82d56cf88df8ee24b34d4f788ba03e4c28eee79726a48140e4f7545253d8a0116b81e876e05530f9efd7754a63242d6a514975235b73e14dbd154d9b44c1a192f134e20b38f90fa5b856853d3a4297dfc48d8b43916cb3eb902d95d6f8a5f45457ad49dae3de83ff8614befc6a351205e66d8f812a528db70b6b53a52be8a4f1f30ecf2486e57cd6c7ce7cdf363328fa058c4b0b03007b89d1cf9257142a7ddd52a7d5ab4aab79a151e62d10835a4c00410968e41c951644a7d2772334a097a997a1b6031fa59376c0e0932cf71312c71c630b53c53d345315f369961260f8ebb92610f9bdce1413c6cb2be47885093f278008f349f3e5df44b925db20c1caa9afdcba837d5a6ca1f4f4b2e83b81bb3e62fb5053ec4fff01ab6f8a39bef140c4f35287ec105dccef8dc7d9f8736ed475f916b3e20767bb4067b9b7624a3ca81a6719662bdaeff3c757e81f8865cbd42dd84b93db2a3bc758e9a0d82c6c88827c5a27ace0c565ce22edf458d9ae008eb69abf74bdf36f883860aabbba9b5912856c9d32fab5c5c2b2b242a64a1f9d0d3ca466207b4553586a242f81c396de605fcb001e2d34e25d1c81bf14f5e31842c071fafdb6d2a0552b57d6eb08843d0b3fd8f7e9807723e3e404ea7e5a0275df61ef6be9cbf4ff74ef5df0184531641084bdf7bc8dcb13085d77581dc3035ae73e59ac1f9289eea23808c7bda710232230e7f2342df1657e3d302bde341b8c52a56cea90dd4727991386670ac765a27573806a738152e5432a7acbb34453c0f438a6359e9b966084a9180c692a3a212b8ad5ddf52286d4768203a2cb2e602812688a696b1b17de688ce5839d6d89252f30f90641f0a730840f2c105ea68518c8dbb74d82dcc5115b2fdba5cd16c146eb0963d2575600e22f87b1f914268583b19602d92e2ec5e76ca338fd1e15a61fa92ccc3475283e291185a23de78ec9064092afa5f2a4cbed83b56c2d75784f4764e8fdd04548a4e1cf849bf4e2bcab8c412767fb8507b4af37aa9873ab0ace2993848acf670727c327367c20defc285f1153e17283daec4ec28164ae028ba1183f23b32c971fb4248809c2cdda32c5fc74aa291665e5bc3703536f5ad60514948deae0e3994a76cb305bf666c9e8b255d0e4de7330613d650faeb8ff3f797e618a8a6f5622c3c9f7d645c4cf94d7aac1494c5260eaa6b4957a5cc5e0096697c8989a87b61b50d7dcb487b4f183578741bcde8df3c2b6602a251703ac8522e1b4a7ecba0a458f7832e1f4abddeff1ea7d8390158778248c81f9aea12c78dd9eccf08c16700d006fe80e3aa92af343dd1f67c46868f6da781b983c6ae567fc2213864b0a89d1da73a1b72f61d6e07d3bc987bf2dcb36a9e981ede9115b7714d52c1514774a631448240333c8e98ea2915ac5d7b2e300df3d7da8ca9d73c3753bfb0999b59cf9ff24a28c976c454d0e878c3422bb32c5bf0aa413a2f2c232df71ccf4f9412bfac58d9186dfb820c47fabb747ae3828600d6409af0ef2baeca226cd435f5eb4316a867e56627ac723380e6e4df463b3065f821129bace999a509ffbc30bc8fbb741f71f4f0aa9ceba9855a75ea9297eec9f834ff3cf6ed44a3712e2724a9a94716ef2a8d4a0225a5a3dd3894848be32f3a7e1bf14605bb0d1a91297e96ada0589171b0aa20666efc9e38965fea23f567d61b96185364cb53a4ca03c7e54b6c47fcc8ff7197a3f777ce01623627dc2d526151e65c408ab742c4c30cd7145a290b00893e9a312cb34c9205315173ab5696fa02be95641c306b5459c7cd9b01a5a93ef55ad0099db0cf081f069a2f7f7984f69574b9a9c7623c32f0f3da774fd0901ddacdd89acfbc27810efbcae4a0706fb8d597a6138404a823533ed6156377fe2b445c6c7819503cf29f5291912d68ecff2a27f0b79e3052a3950ce1c14fefa538cf11992e14ef4bec75fcbcdfeea29100014455309ef600711b6d4ebb43c7de994b3024be852832cbb06e2b67faf9d1c5596d3f719d9b42f9b182945ffffef6d1cfa0c77b1acb6bbaa25ed6d8d8e7416264baa7cea0290ff066e71f44f4fa0eed8ba79bb13b76496666cdac31faf864022e9fd00cb485c54cfe1662a9e773c51c3726464f4f131138ca23b577ce7ca60c5635d3230971a150afa6d9a3dd812783baf22abdd1709db9091a373be04067dad575357085e343349261dbf3fe963a95a3898f2ce34334262bed0fce9ed3c4141b31430bff947b7bbc7233af4a2937361a1bc8a39e978ea76928befced13e78733abdb7585a5e38ba2e164487ec92b23dab673573f6e9bf335fdf466c011380f81822e9f0cfceb27072e08324fd1936feb33bfdd8012af9d31d79be5c7e9c3caf635df1e6d9490943f66cf0d688c84ce8f4e631e22c118d0841446f8e16338f876c7ed3575cf4990c104ec14d2149772079b71e2913193410b81e068e058b71852e80b3425101cdd66436ad475cdd792a67e9244b8cb752893624fe96446c10a3b6cea8c85ce27b54ac8d650dc9a612edde9790b0f8cd859309c35f10e120e70770e931a7198b33f2a0b128d1aa5874cb8ac17b55a3aa2446e0c29d7bc07d341819fb3ac7084ef6fa6c2ccd1f7edc1be590878e8c22ea882b08a8877a7ea16e3bea6ce6a59e45095a90992a6497eb92454a75f24e78ea0c462d28757f0296261f1524027a8cace29dcd2882054c2de59820b37ceb81b4c74574f8e7272fa01771e9f26c2202d017094dcf9ba6dfdc83b6cd58aea5f3ccf5e6e065c1521e55eec06d06ed137e418bf371652eaf02a3f283d55725330edb40a33b02717e8c6bcb437b4aca7f6e1373f8f33f251c15d3f064c3ca5cb4a1696ef0e0dbac3572d760598bd2a9783b1d33e9f19f3dee0b2b4b6218a94a446d1b1bdb3bdb57d70675b434cdf87721bb910bd808e34498ff6566ba84d328afefe95b0ebc3f8a2e0bde53f02c729ed4f5a5151d0ad1aef4b5741808e955f50a3dcaedeb80c3b33494ac2d94b54881349efa1b9b560185bb6039588efcfb8b63c8538f48700f5d592cb08afa2b7cca34a5d3d972faca8553f74f8ded46b3dbb85f92f976dbb59ea59f72606daf1a62e164f37febdf44111a88b19ff1ccd01afb4adf6dc0fe59c2ded959e18e5cfd4ad37398d23e1aa672b67442c5cbc9ac31d3f94dd78976b3b6271e427c7a3d5d0defc4f5dfc7e61a10a6cf460195c551241327e42cb21a4a6bb448175b8bb3210efbb95eb9a69d94b03eb36233aceb58cdb1ddaaba9b4bf0bcfbb252063200f1829f30bf895e652c1062950117cd6f5662ed29c75a162ff60fad395b386337c8a4390bf0a7b4bd86e146404126265bd511909438f1503edcba451286d9a550e86b4a23125819510423af3097d3f786d7e3d6a7309245468eb8be478d7c627425b3b8c46ea2cf2b63169cc7906a4f879b60d5101baaa72b7a5a61fdd00c44bdf2d129d305779909730a9a49854c8f40c87f709c828591d926adaee844e5060ba168fecd5d8a07ca859d96683e61756a83bd2b2c21abca699c0df9a79784f12ce860868ad93d064f0577d6810bc0447e97de386d3df5956cdc534813cb5a6a0eb52c06855d69b0d16b3e086b1ad1c262a1c6022893c3c456a68f5ae083b229bed0b4422c0ca92285fc12913d83c6e6dd5b81dd1145848be2b44f638e7a97a7bb7b6141ad402c62e02104dd953d9cf3f26a10a1f869d873d2e4485b1c072ebae52f0dfb5a7c76e1b9d4bf2994862ebef8d0b64ed6b9bdb70dfd858277dbae2fd2c930ba5f7a6f946f75d9c10708eb099f81382875dd39e422e73387575eb8c8fcfb1b47e69e695aca4384d43fb0dda680b641612a5354bd5f51433607a6825850c83344fb789e929a29b09b45f2bbab2e42be4b02fc2a9ee4901e23211b72cded2fc852fb03aa434a4e24e6fa32b89622a4269c89494870a79a7c32c932cb1bf49124367a6b28b8a3b41f07f210e4267c386bff7bd84437d680e8cf0a2c5e98fbae26397fc7c6aba6de55105568196b7101c0d9042f1ab21b56db460b865cf8512516939ffad9232afc6776345412a28693b0d69a0ae0fd2f4524d8f0bfaa4b9cbc7d3690cec950034197b3f3b3ddc8aa9a54fd80b565aaa4994e4b9cbe8de6a61a21808ea77751f85e8af0d2894363b45771b2e1016c37bec7966383d46640855fb06fb7405bdbe07ecfdfdc5b3e1f035cb8db4ff47ec73dd6fb7c50abd8e977b60cf968f0c1139ad632aa27fd0ec2e57f15e5d947be0249d5d6c3c512bb8d4b4472b888529ac34f3de2d158a72956d1fd6c598e69e4bea43d94f483071f17cb800c47ddb388342b1cf9e5d0fe56576f01d9c790b801db2ccb393bd9b4c7ce03fac2c3bebe3927513e20f63f07aadc9cc3d14d6cc8f34ef2f8b64b02ad30c69f5643a1ecd2424efaa31f5c090a7bbfc07e16e5307ed5e6750c8fe47ac50620e1f8e17d996a19a41b7563cc83f48169d95ede33983f1d08145ab763056b1efb71367bf46eb3efc2ac7915886987ce7d0e6c3c096b5e3cd79979a318676ef03e94bc09e167cc39b5d07ac2af1e37b6046e5e9a9a95a6d5d0f377618a2619b182f8c4edeb94b0c97f00a44dedc6c708722687ba3de5fa5090e59c911a5b79db584b8bea5552234bd057ffcc303eb5fced6a7990d1da11911041a0a3c4b7c8d5687af57b0195150ac0dc604b71e00ecd76463704cd2a553019c65032adea9406e56169323aa57ed2fb4736c2e5dca1076f539e6169115c43d5f55634bd1c96979620f4ec3bb7cc5c0cbbc0dbe8c67f04e74df97be8c618d75940a95dd1e05bef1fa2cacb6663a1646df626f013a715a81cc93b5e04fa7ec874f529c1e6ea0140e1022e046ab99c34a8e44750f8e0f8be5644767604c708a1f866b33a80bb2df3c545899f66fb8732e432ea53358ee2612460d57cb960f5440c75b5b2a9cd4b6bfc09f67e861377ab4608ad9bd80dd76a40d172cdfd20784213451fb0dbd023b610efb47bf9d0c0e79c3841947af24a42e37d95c0725afa92b5eb1740cf6d73c39701343dff1e8efb18023fd680a116112a4c0536afecec0f8ba648576eacce35eb946c3ed6b804d0446fd46b89fb80f4288c349d0ee58ee523f3219106f1e18fe9e2d4c983fb6", + "addresses": [ + { + "uri": "https://ejemplo.org/foto.jpg", + "offset": 3000, + "host": "ejemplo.org" + }, + { + "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", + "offset": 0, + "host": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi" + } + ], + "envelope_key": "0ac808598a3da15de6cb7044f8a7ac60a55c2f1a64d7a36d17c79b7457946781", + "rest_digest": "a62604fb56d89d37627c9070de21dd62ae22ce26fe28ae01a6b5ed782fd543a8", + "rest_size": 5032, + "capsule_digest": "da2c0d2b02e604e0741faa44d90abebe7dcf83dc376addbca1d46782c89ed9cd", + "padding_cases": [ + { + "base": 100, + "total": 4096 + }, + { + "base": 3000, + "total": 4096 + }, + { + "base": 4000, + "total": 4096 + }, + { + "base": 4060, + "total": 4096 + }, + { + "base": 4066, + "total": 4096 + }, + { + "base": 4067, + "total": 4096 + }, + { + "base": 4068, + "total": 4096 + }, + { + "base": 4069, + "total": 4096 + }, + { + "base": 4070, + "total": 8192 + }, + { + "base": 4071, + "total": 4096 + }, + { + "base": 4072, + "total": 4096 + }, + { + "base": 4090, + "total": 4096 + }, + { + "base": 4094, + "total": 8192 + }, + { + "base": 4095, + "total": 8192 + }, + { + "base": 4096, + "total": 4096 + }, + { + "base": 4097, + "total": 8192 + }, + { + "base": 4100, + "total": 8192 + }, + { + "base": 8160, + "total": 8192 + }, + { + "base": 8190, + "total": 12288 + }, + { + "base": 8192, + "total": 8192 + }, + { + "base": 8193, + "total": 12288 + }, + { + "base": 12000, + "total": 12288 + } + ], + "uri_cases": [ + { + "uri": "https://ejemplo.org/a.bin", + "ok": true + }, + { + "uri": "https://ejemplo.org:8443/x?y=1", + "ok": true + }, + { + "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", + "ok": true + }, + { + "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/ruta", + "ok": true + }, + { + "uri": "", + "ok": false + }, + { + "uri": "http://ejemplo.org/a", + "ok": false + }, + { + "uri": "file:///etc/passwd", + "ok": false + }, + { + "uri": "ftp://x/y", + "ok": false + }, + { + "uri": "https://user:pass@ejemplo.org/", + "ok": false + }, + { + "uri": "https://", + "ok": false + }, + { + "uri": "ipfs://notacid", + "ok": false + }, + { + "uri": "https://ejemplo.org/ñ", + "ok": false + }, + { + "uri": "https://ejemplo.org/a b", + "ok": false + }, + { + "uri": "https://%D0%B0pple.com/x", + "ok": false + }, + { + "uri": "https://ejemplo.org%E2%80%AEtxt.exe/", + "ok": false + }, + { + "uri": "https://127.0.0.1/", + "ok": false + }, + { + "uri": "https://[::1]/", + "ok": false + }, + { + "uri": "https://0x7f000001/", + "ok": false + }, + { + "uri": "https://a.com:99999999/", + "ok": false + }, + { + "uri": "https://a.com:0/", + "ok": false + }, + { + "uri": "https://xn--pple-43d.com/", + "ok": true + } + ] +} diff --git a/testdata/vectors/security_cms.json b/testdata/vectors/security_cms.json new file mode 100644 index 0000000..227b339 --- /dev/null +++ b/testdata/vectors/security_cms.json @@ -0,0 +1,349 @@ +{ + "description": "SECURITY_CBOR with an author signature of alg 2 or a time seal of seal_type 2, its context and the verdicts of spec v0.11 29.7, 29.10 and 29.11. Certificates and tokens are made once with test keys and the file is frozen. See testdata/README.md.", + "spec": "0.10", + "cases": [ + { + "name": "alg 2: two signers, each sealed before the round time", + "security_cbor": "a30071646174656b6579732d7365637572697479010102590f61a3000201584582582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc582046218f3323671ebac0c2383e2382322e0a05624f864841d69933d9651b76113902590f1230820f0e06092a864886f70d010702a0820eff30820efb020101310d300b0609608648016503040201300b06092a864886f70d010701a0820486308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e430820306308201eea0030201020208193a2a79e27fbc66300d06092a864886f70d01010b0500302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a301e170d3230303130313030303030305a170d3430303130313030303030305a302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a30820122300d06092a864886f70d01010105000382010f003082010a0282010100e3755ca7fd01a67483239a8cf4ed8c0046683ce30f7ff4b1850d9fb62775a9317ed98ef3655024ff23da46fd710cfb864146d87fb43b3cb77f910bddfbb84c2d26d74ca4059002e3bbfcc5322d03201b1fa9314edc683cb267b7ffb7c3cae0784b6c7ded5211c7ed2ce59f4412f5a709d9549303f5235aca2c4e15512a7daa45d360d75f6aaa112eae1218329fb370d411d39785254d1f034751c940bf01876e0abee9dcf28bd7fe9864b9587848bdf606b5b9ba2f2ead6ae0e7bb28f2c3a727aa4d358af65d6a0e1251258184f6fc5bc2e4211fc5d84cdfc7f8b82a1a3c7ea44be1f4e475d6f3f6fef80459d97481fe89e6b9320c1b47916722293bca3241e90203010001a3283026300e0603551d0f0101ff04040302078030140603551d0e040d040b4c7569732047c3b36d657a300d06092a864886f70d01010b050003820101003c5778f609c3e7755e03614c0d14720257e98aca07dd96cad905cc9c0ecf07baf165844fbb75f075821a385259e9341347d54065d02504bed0d1481dcb349144e9a859f4105e16ce37b3aba616a086051cf6df62d7736c286ca3c9bd220ef7a0619ecb8cea10ae0253911922ed5efdddaa0105b231782d5529dc59749665439c2b213897706ae621120dfb449576a10ecf43e87a175a7f737f1fecdbd3b89ba3e7f29553b515c6a632136b70ebac0b2015cce0931dc3f548bf51ec10a6ac9dbe9c757505ec3a8effe70d862d912210f28ff5f4a25a8d6b862db9a784d78ad2324d0abd5b6b4dd4524469549b2098834491385ff8dfd11345790a1610bbb48e2d31820a4e308204c30201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e243989a6cc0f8dd3048764de75c6849ea1dde4e74226f09bf6c182c449a3a493037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d04030204473045022100e985ff316ee456c61378ea1ea48c67da0dfa3bb71be5a252f372d24850a71d5d02204ac5759b9daab6efa5a1d3864db7747a9d3daa55bdaaf0e15305f7d21bd19d03a182039830820394060b2a864886f70d010910020e318203833082037f06092a864886f70d010702a08203703082036c020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420e976abf3318fce3ff4fea8cdbd2b92aea1544e560de862b3e2c90dcd2b83cbaa02012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204209d0a3a3e4112f315d650b827cc04b4a9b631201488076f91d605914108ba9d09300a06082a8648ce3d040302044630440220141c329e9fb6079d97ccbd69f3bf737ff466c4b2dcd36727d6193089338f18d302203e9e317eaec54f7716d78905663f287595cd3bbf8c0570c30f505b5b4ea2f9bf30820583020101303a302e31163014060355040a130d446174654b65797320746573743114301206035504030c0b4c7569732047c3b36d657a0208193a2a79e27fbc66300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e243989a6cc0f8dd3048764de75c6849ea1dde4e74226f09bf6c182c449a3a493037060b2a864886f70d010910022f3128302630243022042046218f3323671ebac0c2383e2382322e0a05624f864841d69933d9651b761139300d06092a864886f70d01010105000482010008cd9f2444946f21c6027271b61ab2a978c16103f32afd8e108ef61766a500e13fb93a17b0514e843559ab3ac97f4203bc019f048e9219f2005c0c5dd8226743cc5b28a266693700f580d04802acba95a71c57f408524737d42c08f2df0b282ad57dd940788902b49e1e3aad5434b381181b575f689eb4e67f3d6c9f6af66b87821529b30ddacaaef7cd9ed7ee20907eadddf1ceb7f35f31e1c7e5b0c52cf2c0dda17f0fee656e2bffdb3d571642d10e7e76fce44f9b8810ddf89ae0b5bb3114ec39ccdc6a72d248fb55040a29c10b854c79893195560359c1a369f2d81c5507850717e7a69921d34283365216dab0e8d9fdb55cbd985934754ca6ca435bb356a182039930820395060b2a864886f70d010910020e318203843082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104203133909689be7b6e7f3a635f7628c1dd502b72b770090e5484b9a30563b9579302012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d0109043122042002c0ae1862d888d856794a82163f419ffa4eb371ceea06e3ac96d088e2e99b71300a06082a8648ce3d0403020447304502202bf0294f2c65f11243655691bfda067e717feab0cc7a94ee8a2996c89d6f6b34022100afabbc3e20527df993f954c9dbf756f1b2a8fa0552fe4d9605152f0d5f8e0ad2", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F6", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "valid", + "seal_time": "2026-09-30T12:00:00Z", + "before_round_time": true + }, + { + "holder": "Luis Gómez", + "issuer": "Luis Gómez", + "result": "valid", + "seal_time": "2026-09-30T12:00:00Z", + "before_round_time": true + } + ] + }, + { + "name": "alg 2: a seal after the round time proves nothing before it", + "security_cbor": "a30071646174656b6579732d73656375726974790101025906b0a3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc025906833082067f06092a864886f70d010702a08206703082066c020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4318204c9308204c50201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d04030204473045022100f4e2b82dc6b1429bb433247b34fb25a907a086ae34b602f65bf84c419b14bbec02203fd119c23b1dc005258bfb0d16ef7efc487f948e9dc7b9b6d7b5d33eb6aac167a182039a30820396060b2a864886f70d010910020e318203853082038106092a864886f70d010702a08203723082036e020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104203fa6e3f4031d5ad633dce60408c4c63aafb6af2d65f7a0cebb9f286c8c961d3e02012a180f32303330303130313031303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013530820131020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d01090431220420acc298b6d7077397d13950532815d76c9b30a39aaf67312f460f77550a67ab54300a06082a8648ce3d04030204483046022100e265c660c3bb8be16a524b8e8bd7849f45c0101ec5ae9a3f94605c3b095e8fb9022100c616fb16ad2a70bcc30b34ccb6dbb598a3a415472106d449c29f207537e93f8f", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F6", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "valid", + "seal_time": "2030-01-01T01:00:00Z", + "before_round_time": false + } + ] + }, + { + "name": "alg 2: a signer who is not required shows apart", + "security_cbor": "a30071646174656b6579732d7365637572697479010102590d37a3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc02590d0a30820d0606092a864886f70d010702a0820cf730820cf3020101310d300b0609608648016503040201300b06092a864886f70d010701a0820323308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4308201a330820128a003020102020835a4deccdaab6ba3300a06082a8648ce3d040303302731163014060355040a130d446174654b6579732074657374310d300b060355040313044f74726f301e170d3230303130313030303030305a170d3430303130313030303030305a302731163014060355040a130d446174654b6579732074657374310d300b060355040313044f74726f3076301006072a8648ce3d020106052b81040022036200043385b3174e9de495aad288fd3549a386e2187016abdfbc3deb2f2ed314c72eb6dd930cd70aa5c1d7137bf4e66fd459874b391883d01c0d53815dfe7fa2fbf291f64972d69b8a9d81e172cb78ac6d353e54a097d8f07112950f85cc2c140fea1ea321301f300e0603551d0f0101ff040403020780300d0603551d0e040604044f74726f300a06082a8648ce3d0403030369003066023100d171c2da04ba594e86a73a57adbd9b20f75d8785464b718334adbfa5bb268812ee6f881b96dbd12172fda26ce2213e2e023100fb198badb7b2fa34ff4d71c689c453e0ba93ea31192b6bb486be6385718ef7b95933af58748ad2a5e998214a527c2a92318209a9308204c30201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d04030204473045022100e7458b88374bd0ca99f4b2b443bc82ffac1718c5aa2d8aef2d381e665e2f2314022076ada20a1e1181febe5c531f34a05f98594b2c072f45c0c52ea4c34fcbf18640a182039830820394060b2a864886f70d010910020e318203833082037f06092a864886f70d010702a08203703082036c020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104204997b27370ce829613415dfa4dc4edb0e309cf1c166c2c94fb4a839020a496ce02012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d0109043122042075eadf0db2015273d67c2bc8a6649061d1275903fe2fa96e17bc60ff4490fdb0300a06082a8648ce3d0403020446304402206361a04ec1f1142b6ee695db78dfad8bd6abe1012ef294b10fa768e20f9b9d8f022038c21706cb8f1d59af7ea3096ac1560077d8882b8bf929f169928341fef7a805308204de0201013033302731163014060355040a130d446174654b6579732074657374310d300b060355040313044f74726f020835a4deccdaab6ba3300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042088dce787be2d37c7b7b8be2a37e7268b20d60f98cd2e69431bf660619ae1bf59300a06082a8648ce3d04030204673065023100e9b4dff00534a57117ddb1e618364ecd99bc49acc15f430cd580931bef35658c583827941b1a90679cc2de9dd215c16d023004858dba8c4f71f0dcca26f4b48cb8c549273905c5e0e9acc1ee21b02abc9277f65202f92ba4e80206bfaaff2b799238a182039930820395060b2a864886f70d010910020e318203843082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104201d41f0fd23c7965e32d4dadbb85e6f8132c2174442a93442b7b01b9a284ddfdf02012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d01090431220420f386d364fed4b4c3d4a2a0cc1d15fe9698f0c336a81dd847e13af387291d3218300a06082a8648ce3d040302044730450221008cd1e5b7216fd5865ae9ca2f58007b115ef41f871efe25fee66a71f152c4c7c102201cd7968a591709b980c1c18cc16a31c545efd5da054f5d2554be217cd4d4dae0", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F6", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "valid", + "seal_time": "2026-09-30T12:00:00Z", + "before_round_time": true + } + ], + "foreign_signers": [ + { + "holder": "Otro", + "issuer": "Otro", + "result": "valid", + "seal_time": "2026-09-30T12:00:00Z", + "before_round_time": true + } + ] + }, + { + "name": "alg 2: a required signer is absent", + "security_cbor": "a30071646174656b6579732d73656375726974790101025906d0a3000201584582582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc582046218f3323671ebac0c2383e2382322e0a05624f864841d69933d9651b761139025906813082067d06092a864886f70d010702a082066e3082066a020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4318204c7308204c30201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d01090431220420e243989a6cc0f8dd3048764de75c6849ea1dde4e74226f09bf6c182c449a3a493037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d04030204463044022030e89724e9a7bc7742c3070ea844c8c6135fc2f1f090ff02d4b8e013787f748a02202d7e5a32fa3be2e4497b868bdbea7dc74cea338e9af063796a16f58b592f8c9ea182039930820395060b2a864886f70d010910020e318203843082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420d978156a516b3550c5c59d8f842ae75f4b086e551f91176ba97a3c5b1a9de88102012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d0109043122042042f3033bb9a81c0ed2dd9c2f2b07a99c2278d32eeeaafc2eb6fd1545090e8a26300a06082a8648ce3d04030204473045022100cf6c1039534dd01fee54a21ba821557991d573eb63bb1b1aae7738bb40acf08502207225a9f503c13c87b958ee8d83776e621da7b6cadd14c4fd4631d562b4ff1d7c", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F5", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "valid", + "seal_time": "2026-09-30T12:00:00Z", + "before_round_time": true + }, + { + "holder": "46218f3323671ebac0c2383e2382322e0a05624f864841d69933d9651b761139", + "issuer": "", + "result": "absent", + "before_round_time": false + } + ] + }, + { + "name": "alg 2: no seal", + "security_cbor": "a30071646174656b6579732d7365637572697479010102590311a3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc025902e4308202e006092a864886f70d010702a08202d1308202cd020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e43182012a308201260201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d0403020446304402202405ddf8c290eca0488e097209f2b5d4fd00ef228bcf2dfacdd21620614de47d022069ae19a347d757338f52b04e0dff7c199a03f229e03fe60e5c04c61be7d346ac", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F5", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "without seal", + "before_round_time": false + } + ] + }, + { + "name": "alg 2: a seal from before the certificate was valid", + "security_cbor": "a30071646174656b6579732d73656375726974790101025906b0a3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc025906833082067f06092a864886f70d010702a08206703082066c020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4318204c9308204c50201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d04030204483046022100a53ff1be1b099213410faaf5d129f313f3805943b0ca9a91548095523e3e6ab40221008f2f80658797162a7635698ae27d641099a2a56a704518c39a7457943cc0307da182039930820395060b2a864886f70d010910020e318203843082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420ac6338330973f43870125e217bb36d225633fc89616b39f9ed38d320c383f89102012a180f32303139303130313030303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d0109043122042000ffc82983ab7841e9c7c7221c7df79d31f4d835953932a940efd1c4e38a1165300a06082a8648ce3d0403020447304502207264362223b28bd85933b98a7320b68d5221c78078f4e410d8d5ab26a96162c7022100f2b315a3fccf8b533d430c8722cbac202f59391b521d4b329e6471ddbda9aa95", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F5", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "invalid seal", + "before_round_time": false + } + ] + }, + { + "name": "alg 2: a key 3 beside it", + "security_cbor": "a40071646174656b6579732d73656375726974790101025906aea3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc025906813082067d06092a864886f70d010702a082066e3082066a020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4318204c7308204c30201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d0403020447304502210088b768db47d80f09500a967980ad2ac0a2eb82f458777e891f593e34cc14d0820220659290ece942794938661a0484c3bd5b0530b42344b0bdc01312980c5ba3fbcea182039830820394060b2a864886f70d010910020e318203833082037f06092a864886f70d010702a08203703082036c020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420b4d58800f353fd51a2be33700e54876fefe6d247dbd0accc92f6397889a8ba4702012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204202a52076c932f135a14b86a88f42b66b77977d5b5d43cba3d115e89ee5fa1110b300a06082a8648ce3d0403020446304402206d1b9fb6d44839be881774b7498bb3b765666102095c3996e98e551f54f63bee0220190f2d2305c490196dd6a9b9bc348b6986f656434ba6b560e5dc55efd2084bd90346a20001014101", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F5", + "seal": "S1", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "valid", + "seal_time": "2026-09-30T12:00:00Z", + "before_round_time": true + } + ] + }, + { + "name": "alg 2: another head", + "security_cbor": "a30071646174656b6579732d73656375726974790101025906afa3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc025906823082067e06092a864886f70d010702a082066f3082066b020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4318204c8308204c40201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d0403020446304402207a1647947225c8f411342b312c22561009adb7b7ce3302d76f98cc0820b143c002205010984a5c17f64b3f12548fed1cf39ec99926848dae4d68148a3edc9ff90203a182039a30820396060b2a864886f70d010910020e318203853082038106092a864886f70d010702a08203723082036e020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420635c606d8492e086879058d5ed73f29d342b9849792743228d08f00ebe4c81d102012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013530820131020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204204aa9eb4ecca82d42d6f3408fd0ee151cc773de1b32f642dfff5470c4f143a0ac300a06082a8648ce3d04030204483046022100ea89187fe24bbefcc313b9e666adbe7ae53c0a95d97ab3a43de657e308253d20022100ae8d4020e8db3e85da2a2591d9caeb1c0099521cd97535d4f0a851a1c0f53ac8", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3787ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F2", + "seal": "S0", + "signers": [ + { + "holder": "Ana López", + "issuer": "Ana López", + "result": "invalid", + "before_round_time": false + } + ] + }, + { + "name": "alg 2: without the context of a capsule", + "security_cbor": "a30071646174656b6579732d73656375726974790101025906afa3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc025906823082067e06092a864886f70d010702a082066f3082066b020101310d300b0609608648016503040201300b06092a864886f70d010701a082017c308201783082011da0030201020208399eb3a7749a61f6300a06082a8648ce3d040302302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a301e170d3230303130313030303030305a170d3430303130313030303030305a302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a3059301306072a8648ce3d020106082a8648ce3d030107034200049ba7f4999209b8a6d393b928bbd84aae10eefcda758b94ac9a171c3f8059a065bdd433cfd9da5789f85d9a3be45a73bc5f1308c0991b2fd5cec0b11fa27d7eeea3273025300e0603551d0f0101ff04040302078030130603551d0e040c040a416e61204cc3b370657a300a06082a8648ce3d0403020349003046022100871158b887973e04034747995358dea51032602153b05e6bf5cf1b8778d0a623022100be16176bd54cab25f50e34ed130d6324c43f7f1d775f307a28a8b8f2109791e4318204c8308204c40201013039302d31163014060355040a130d446174654b65797320746573743113301106035504030c0a416e61204cc3b370657a0208399eb3a7749a61f6300b0609608648016503040201a08184301806092a864886f70d010903310b06092a864886f70d010701302f06092a864886f70d010904312204208a0a6d927c8efe36ab066eaa1321276832694a7d36b38e01786e2fca1ba4387d3037060b2a864886f70d010910022f3128302630243022042013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc300a06082a8648ce3d0403020447304502210098cce1331f2bcbeead0a8f72d10e370e88547acbb7a060774476fbbeefbcb4dd02203cc8ad8db9161990e9405998479d55122325b0d0aacf592db0a3489615244822a182039930820395060b2a864886f70d010910020e318203843082038006092a864886f70d010702a08203713082036d020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b06096086480165030402010420dcd9f7eb86fc8586a0bb1f37714d9f11e2aa854872daacc521058ab89d29d0e602012a180f32303236303933303132303030305a3003020101a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204205fe6287d68fc6e459c852cb7ac7bf5050374de18353747e70bb9a219ecba780a300a06082a8648ce3d04030204473045022100d7d713c85125e46ccecb2f5fb4e2db990b5e54f71b6486e5b81e64b8ba56efcd022077904deb3e45c01f144899fdeacd3f628c3cb672dfe188d84ae99578ad853f2c", + "no_context": true, + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F1", + "seal": "S0" + }, + { + "name": "alg 2: SIGNERS out of order", + "security_cbor": "a30071646174656b6579732d7365637572697479010102584fa30002015845825820ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb58203e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d02423000", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F1", + "seal": "S0" + }, + { + "name": "alg 2: an empty SIGNERS", + "security_cbor": "a30071646174656b6579732d73656375726974790101024aa3000201418002423000", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F1", + "seal": "S0" + }, + { + "name": "alg 2: not a CMS", + "security_cbor": "a30071646174656b6579732d73656375726974790101025832a3000201582381582013c811b56e109e9ce48cd885cd2686750c380fde4bbd887399239d013d70c8cc02476e6f7420444552", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F1", + "seal": "S0" + }, + { + "name": "seal: before the round time", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010106032a0304302f300b060960864801650304020104203d799ba25f479a7f2d0c37fcf326752ce74b3a0f654dbb9026738c763afe068302012a180f32303236303933303132303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204205fe6075847442b1eea668b09c8f86114d1271afe9991081fc0cdb5a31588da17300a06082a8648ce3d04030204473045022035826188c3bb3188be9cf91df2dc4304c17631fafffe8f2c0f80642bbc6c25b6022100908217b93a2edc80ef83409cd4442a388f18364dbdeced11e0e18d6677221ba0", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S4", + "seal_holder": "Autoridad de Sellado de prueba", + "seal_time": "2026-09-30T12:00:00Z" + }, + { + "name": "seal: after the round time", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010106032a0304302f300b060960864801650304020104203d799ba25f479a7f2d0c37fcf326752ce74b3a0f654dbb9026738c763afe068302012a180f32303330303130313030303130305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204206ec611e50ba08a9652626f2e01c82ecea7dcc274e609f2aa345d021863dcad7d300a06082a8648ce3d04030204473045022058e49c9469d43a91f95e2f85cef863047352a1dcabf91b5e7e33045b2999b49b022100ef93e6c13cdcbe5b60aa931f645f5289a594ff09c1914623c035fcc09c6eb46d", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S5", + "seal_holder": "Autoridad de Sellado de prueba", + "seal_time": "2030-01-01T00:01:00Z" + }, + { + "name": "seal: the accuracy reaches the round time", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a0359038aa20002015903833082037f06092a864886f70d010702a08203703082036c020101310d300b06096086480165030402013065060b2a864886f70d0109100104a0560454305202010106032a0304302f300b060960864801650304020104203d799ba25f479a7f2d0c37fcf326752ce74b3a0f654dbb9026738c763afe068302012a180f32303239313233313233353935395a3003020102a08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a318201333082012f020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d01090431220420471721ed38663795e173165313eb086b98a36585f824a592258e6796265b290c300a06082a8648ce3d0403020446304402200d7a4e1cbb38fc5ab7e36e68a02ff0ce522afd5d5339f3f498a2ed38b5d5929e02204e3fc60d1475324c1262d93e2ccc3220b6f20d5c2789ab98de90fc725095dc68", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S5", + "seal_holder": "Autoridad de Sellado de prueba", + "seal_time": "2029-12-31T23:59:59Z" + }, + { + "name": "seal: over another subject", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010106032a0304302f300b06096086480165030402010420d9298a10d1b0735837dc4bd85dac641b0f3cef27a47e5d53a54f2f3f5b2fcffa02012a180f32303236303933303132303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d0109043122042020b72ae51c6f228bc1779cb6f447612e6884942940b9d925cf0600ec815f8eb6300a06082a8648ce3d0403020447304502204acb02f9a823d1d511923009bbba27633f0fb1d86abf288e8c91fac127ffeea402210091ed23012ba6318ba11640fadd5b532cf162b9be3911d6f724b812f17d38c7d3", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S3" + }, + { + "name": "seal: the authority had expired at its time", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010106032a0304302f300b060960864801650304020104203d799ba25f479a7f2d0c37fcf326752ce74b3a0f654dbb9026738c763afe068302012a180f32303431303130313030303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d01090431220420952183c5071984e2814df7f00ebb35b71da2bdcbbdd4dbe03d05d716ab67687b300a06082a8648ce3d04030204473045022100c206a35b6ac94901a3fcc2e507a2a21f3d23ba85f2e156d98e87cb045531f7db02203e32681a6f58a9c6abe88c04cb4debf27ce8cd5d2d5b7c954e002a3d14533ef8", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S3" + }, + { + "name": "seal: a TSTInfo of version 2", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010206032a0304302f300b060960864801650304020104203d799ba25f479a7f2d0c37fcf326752ce74b3a0f654dbb9026738c763afe068302012a180f32303236303933303132303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204207e5374ba63316e3801f8ceee00bf0d1654583ad4b2abf0c568aee47d8b8cec8a300a06082a8648ce3d04030204473045022100b8760f30aaea150c3cc178d6f8d69da5aa1658a39fb8c18519de80927b9becad022017b1bbd893a5cd8e5f8406499d77a17e5e1234007aba5a0dd656609ab30109ef", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S2" + }, + { + "name": "seal: not DER", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a034ca2000201476e6f7420444552", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S2" + }, + { + "name": "seal: SHA-384 in the imprint", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590396a200020159038f3082038b06092a864886f70d010702a082037c30820378020101310d300b06096086480165030402013070060b2a864886f70d0109100104a061045f305d02010106032a0304303f300b06096086480165030402020430e8ebf3d61bf90b15bca8f52f442c258a22fd8813dde6462308f13d3d2ae3bc512fb5b2613a392c68a94f4281a60ee3be02012a180f32303236303933303132303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204200fb8e41b236629a2ce055afa2f6fc3bc4fbc56a606cb5dc6eb44388b65a65133300a06082a8648ce3d0403020447304502202cf305a8f490c47d643b1321ec74fc560d720c782f940120b8c72feb44c64603022100e8bc71c72a78453cc208edf5a8ef00ab72d0f180f21ebfb016108fb2dd30334f", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F4", + "seal": "S1" + }, + { + "name": "seal: without a context, as a reader of v0.10", + "security_cbor": "a40071646174656b6579732d73656375726974790101025869a30001015820ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c02584064d805ef80b891e851aa844d3c455a4b95752f88ee0f1d8e3d0d28c7431d516c9838294e7c361f20c7c9a33e7c7c8803ad934bff6174aae97a88ad8fac41f90a03590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010106032a0304302f300b060960864801650304020104203d799ba25f479a7f2d0c37fcf326752ce74b3a0f654dbb9026738c763afe068302012a180f32303236303933303132303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d010904312204205fe6075847442b1eea668b09c8f86114d1271afe9991081fc0cdb5a31588da17300a06082a8648ce3d04030204473045022100f3e262b82a8270b9ba9ac7c53e3ac684cfafb8799ca3543161e5f4883dd7f1cc02204c806cc886fbd06e0eecc1e3a3857fb33741f04a5d0f4e3f6327f1a895df483e", + "no_context": true, + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F1", + "seal": "S1" + }, + { + "name": "seal: over a capsule without a signature", + "security_cbor": "a30071646174656b6579732d7365637572697479010103590386a200020159037f3082037b06092a864886f70d010702a082036c30820368020101310d300b06096086480165030402013060060b2a864886f70d0109100104a051044f304d02010106032a0304302f300b060960864801650304020104202c95d37cb9658ed6387ff8e29854bbff409a1c4456e17ab6d2c46eeb54d7b3eb02012a180f32303236303933303132303030305aa08201b8308201b430820159a003020102020816b536ff6d9413dc300a06082a8648ce3d040302304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261301e170d3230303130313030303030305a170d3430303130313030303030305a304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f206465207072756562613059301306072a8648ce3d020106082a8648ce3d030107034200044430921fc91a68617c785dbc7c013ede1800b37704747bd9b7280e20e475251cca9f1799b84f3cc4cf4640590697e4c425fde6329b1878f7198e91ca9fafd9e7a33b3039300e0603551d0f0101ff04040302078030270603551d0e0420041e4175746f72696461642064652053656c6c61646f20646520707275656261300a06082a8648ce3d0403020349003046022100b26b717908be147fccbe24182e8c0072e920af74fd217c818ee34950d3a8aa41022100a6d042065cc3048680da599203465f7ac6322d76a8409dfc9c79435a72c2a30a3182013430820130020101304d304131163014060355040a130d446174654b6579732074657374312730250603550403131e4175746f72696461642064652053656c6c61646f20646520707275656261020816b536ff6d9413dc300b0609608648016503040201a07a301a06092a864886f70d010903310d060b2a864886f70d0109100104302b060b2a864886f70d010910020c311c301a301830160414f4b0c8ba1da2495736b3b8ebba20262ca957c5bd302f06092a864886f70d0109043122042016bf09210739e6175026faad38a0095930e12eaf345d0e740cdaf4aa5022f143300a06082a8648ce3d04030204473045022100e9c7003e488da05574e7bb2828349e8ce5d324edc32e4ab996d1b6c0335a090502206c5d0742831aa0c9a99315560dbb1e5550522f44bb9fb4ebc9482e9f9f4c911b", + "context": { + "control_commit": "0fcd568a5cb9bdb4677b69354b11ee415af8f784519cff3da49a26f84eaee7f2", + "head_digest": "9f2e6d33a3717ee826353a404ba4618d1aeeb6879ad7936bce8ed5f46814924d", + "round_time": "2030-01-01T00:00:00Z" + }, + "signature": "F0", + "seal": "S4", + "seal_holder": "Autoridad de Sellado de prueba", + "seal_time": "2026-09-30T12:00:00Z" + } + ] +}