Repository navigation
test(xtest): DSPX-1561 add shared assertion conformance vectors and cross-SDK cases - #702
Draft
dmihalcik-virtru wants to merge 8 commits into
Draft
dmihalcik-virtru wants to merge 8 commits into
dmihalcik-virtru wants to merge 8 commits into
Conversation
assertion_hash now hashes the assertion as received, minus only its top-level binding, with RFC 8785 JCS from the rfc8785 package. The old json.dumps(sort_keys=True) formats numbers differently and sorts member names by code point instead of by UTF-16 code unit. assertions.py also gains a reference reader for Sections 3 to 8 of the ZTDF assertions contract (DSPX-5519): strict parsing (duplicate members, I-JSON, case variants of modelled member names), the exact id, the binding form, and binding verification for one assertion with an already-selected key. Each check fails with its Section 9 reason. Also restores the "@base" context key in the STANAG 5636 fixture, which had been mangled into a Markdown link. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
xtest/vectors/assertions-phase0.json is the shared vector set for Phase 0 of the ZTDF assertions contract (DSPX-5519). The Go, Java, and JS SDKs vendor it byte-for-byte and run every vector in their unit tests. It covers parsing, the hash input (starting with the spec Section 4.4 worked examples), binding forms, and single-assertion verification. vectors/generate_assertion_vectors.py produces it deterministically from two committed, test-only RSA-2048 keys. The offline test_assertion_vectors_units.py, now run by the check workflow, regenerates the file and requires a byte-identical match, checks the Section 4.4 anchor hashes, and runs every vector against the reference reader in assertions.py. Every expected assertionHash was also cross-checked against Go github.com/gowebpki/jcs and JS json-canonicalize. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
Moves the vector generator's JSON-text builder into xtest/jsontext.py and its JWS, JWK, certificate, and binding-claims helpers into assertions.py, so the xtest cases that put assertions into real TDFs build them the same way the DSPX-5520 vectors do. The generated vector file is unchanged byte for byte. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
… binding forms Adds the Phase 0 feature gates assertion_header_key_pinning and assertion_hash_raw. Every cli.sh answers no until a release ships; branch builds run the cases with XT_FORCE_SUPPORTS. test_assertion_verification.py builds assertions into TDFs that each SDK wrote and checks how each SDK reads them: - key selection from configuration only: per-ID key, default key, and payload key, including embedded jwk and x5c and the default key through each CLI's verification-keys file; - the hash over the assertion as received; - strict manifest parsing, including assertions from the DSPX-5520 vectors; - spec Section 5.1 binding forms. Every rejection is matched by its reported reason and has a positive control under the same configuration. The reference reader in assertions.py checks each built assertion before an SDK sees it. test_assertion_gmac_limitation.py documents a known, unfixed limitation of GMAC segment integrity for holders of the payload key (spec Section 10.7). It needs the local KAS key and skips without it. tdfs.update_manifest_text rewrites a manifest's raw JSON text, for changes the Manifest model cannot represent. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
…est in the shared vectors Extend the shared assertion vectors and the reference reader to the revised parsing rule: a member is rejected when it is a case variant of a name listed for its level, or when two members of a listed object are case variants of each other. The file now carries the level table (modelledNames) and the IsStreamable exception, so SDK tests can check their own tables against it. Also add vectors for strict base64url and canonical x5c base64, minimal RSA integers, well-formed EC and OKP embedded keys, x5c leaf structure, duplicate JWS header and claim members, ignored registered claims, invalid UTF-8 and BOMs anywhere in the manifest, and unusable configured keys. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
…l TDFs Add profile cases that inject Payload alongside payload, URL in a key access object, and SchemaVersion into real TDFs, plus a positive control for the IsStreamable spelling written by older Java SDKs. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
… default keys Adds the force-only feature gate reject_empty_key_access. Every cli.sh answers no until a release ships; branch builds run the case with XT_FORCE_SUPPORTS. test_empty_key_access.py builds a TDF whose encryptionInformation.keyAccess is empty. Apart from that it is internally consistent: payload, segment hash, root signature, and an HS256 payload-key assertion all under the all-zero key, checked in Python before any reader sees it. Each reader must refuse it, with assertion verification on or off, reporting "no key access objects" and writing no plaintext. test_assertion_verification.py pins documented default-key behaviour (spec 6.1): a Java-written TDF read with only a default RS256 key fails with algorithm-mismatch on its payload-key system-metadata assertion. The control is the same file read with an empty keys file. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
Add test_assertion_verification.py, test_assertion_gmac_limitation.py and test_empty_key_access.py to the standard and focused xtest steps, so their cases run on branch builds. They are gated on force-only features and skip unless a run forces them. Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
This was referenced Nov 9, 2026
|
This was referenced Nov 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
This adds shared assertion conformance vectors and cross-SDK xtest coverage for the matching Go, Java, and JS changes.
xtest/vectors/assertions-phase0.jsonholds 288 vectors covering parsing, hash input, binding forms, and single-assertion verification. Each gives an expected assertion hash or failure reason.xtest/assertions.pycontains a reference reader, andassertion_hashnow uses RFC 8785 through therfc8785package.test_assertion_verification.py: verification key selection,defaultKey, hash input, binding forms, and the JSON profile, over real TDFs from every writer;test_empty_key_access.py: manifests with no key access objects;test_assertion_gmac_limitation.py: a fixture documenting segment-integrity behaviour under GMAC.assertion_header_key_pinning,assertion_hash_raw, andreject_empty_key_access. They are force-only until the SDK releases ship; useXT_FORCE_SUPPORTSlocally or theforce-supportsworkflow input.xtest.ymlruns the new modules.@basekey in the STANAG assertion fixture.Testing
cd xtest && uv run ruff check . && uv run ruff format --check . && uv run pyright, plus the offline unit tests.dspx-1561). xtest puts the version name into temporary filenames twice, so long branch names can exceed filename limits.Related pull requests