Skip to content

feat(xmldsig): resolve ECKeyValue keys#70

Merged
polaz merged 7 commits into
mainfrom
feat/#69-ec-key-value
Jun 30, 2026
Merged

feat(xmldsig): resolve ECKeyValue keys#70
polaz merged 7 commits into
mainfrom
feat/#69-ec-key-value

Conversation

@polaz

@polaz polaz commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

  • Parse XMLDSig 1.1 dsig11:ECKeyValue into curve OID plus uncompressed SEC1 public point
  • Resolve EC KeyValue sources by converting P-256/P-384 points into SPKI and validating against the SignatureMethod
  • Keep unsupported or unusable EC KeyValue sources non-fatal while later KeyInfo sources can still resolve
  • Add tracked donor P-256/P-384 end-to-end fixtures and README capability note

Testing

  • cargo fmt -- --check
  • cargo check --workspace
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo build --workspace --all-features
  • cargo nextest run --workspace (494 passed)
  • cargo test --doc --workspace (3 passed)
  • git diff --check

Closes #69

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fe333024-0af6-4088-8390-71c8ea373676

📥 Commits

Reviewing files that changed from the base of the PR and between 5895062 and 71b412f.

📒 Files selected for processing (2)
  • src/xmldsig/keys.rs
  • src/xmldsig/parse.rs

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added support for XML Digital Signature documents that use elliptic-curve public keys, including common P-256 and P-384 signatures.
    • Expanded signature key lookup so more signature files can be verified without manual intervention.
  • Bug Fixes
    • Improved fallback behavior when one key source is incompatible or malformed, helping verification continue when another valid key is available.
    • Added broader test coverage and new signature examples to improve reliability across more real-world signed documents.

Walkthrough

XMLDSig 1.1 ECKeyValue parsing now preserves curve OIDs and public key bytes, resolves EC keys into SPKI DER, and adds P-256/P-384 donor fixtures with parser and resolver coverage.

Changes

ECKeyValue Parsing and Resolution

Layer / File(s) Summary
KeyValueInfo EC shape and constants
src/xmldsig/parse.rs
Replaces the EC sentinel with a structured KeyValueInfo variant and adds named-curve constants and EC public-key length bounds.
ECKeyValue parsing pipeline
src/xmldsig/parse.rs
Adds fail-closed dsig11 namespace checks and parses dsig11:ECKeyValue with curve normalization, child-order validation, and SEC1 point validation.
EC key resolution in DefaultKeyResolver
src/xmldsig/keys.rs
Matches RSA and EC KeyValueInfo, converts key material to SPKI DER, and defers selected EC resolution errors so later KeyInfo sources can still be scanned.
Fixtures and status updates
src/xmldsig/keys.rs, tests/fixtures/xmldsig/xmldsig11-interop-2012/signature-enveloping-p256_sha256.xml, tests/fixtures/xmldsig/xmldsig11-interop-2012/signature-enveloping-p384_sha384.xml, tests/fixtures_smoke.rs, README.md
Adds P-256 and P-384 donor fixtures, updates the fixture-count smoke test, and records EC KeyValue support in the README.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main ECKeyValue resolution change.
Description check ✅ Passed The description is directly related to parsing and resolving ECKeyValue support.
Linked Issues check ✅ Passed The changes implement ECKeyValue parsing, resolver support, and donor fixture coverage requested by #69.
Out of Scope Changes check ✅ Passed The README, fixture, and smoke-test updates are all directly tied to the ECKeyValue feature work.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#69-ec-key-value

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 29, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds XMLDSig EC KeyValue support. The main changes are:

  • Parses XMLDSig 1.1 ECKeyValue sources for P-256 and P-384.
  • Converts supported EC public points into SPKI verification keys.
  • Keeps unsupported or unusable EC sources non-fatal so later KeyInfo sources can resolve.
  • Adds EC interop fixtures and updates the README capability list.

Confidence Score: 5/5

The EC KeyValue support appears merge-safe with focused parsing, validation, and interop fixture coverage.

The change is well scoped, exercises the new P-256 and P-384 paths through fixtures, and preserves non-fatal handling for unsupported or unusable key sources.

T-Rex T-Rex Logs

What T-Rex did

  • Compared the ec-keyvalue_verify harness outputs from base and head, noting that the base run produced Invalid(KeyNotFound) for P-256 and P-384 with exit code 101, while the head run produced Valid with exit code 0.
  • Attempted to run the ec-keyvalue-fallback tests in this environment; the base-command and head-command runs failed because cargo was not found (exit 127), so the outcome remains inconclusive.
  • Reviewed the ec-keyvalue-parse-docs harness results; the before state showed placeholders for ECKeyValue and missing donor fixtures, while the after state parsed P-256 and P-384 with correct curve OIDs and uncompressed points, mapped unsupported and invalid values appropriately, and donor fixtures plus README coverage are present.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (7): Last reviewed commit: "fix(xmldsig): preserve malformed EC fall..." | Re-trigger Greptile

Comment thread src/xmldsig/parse.rs Outdated
Comment thread src/xmldsig/keys.rs Outdated
Comment thread src/xmldsig/keys.rs
Comment thread src/xmldsig/keys.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/xmldsig/keys.rs`:
- Around line 285-296: The EC curve OIDs in the key resolver are duplicated as
string literals, which can drift from the parser contract. Update the match in
the key resolution logic to reuse the shared EC OID constants instead of
hardcoded values, ideally by importing the constants used by the parser or
moving them into a common module; keep the existing behavior in the resolver
around the p256::PublicKey and p384::PublicKey branches unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7bd984fb-f24f-4ab5-8b54-52ea39f22419

📥 Commits

Reviewing files that changed from the base of the PR and between 0f296c3 and f714343.

📒 Files selected for processing (6)
  • README.md
  • src/xmldsig/keys.rs
  • src/xmldsig/parse.rs
  • tests/fixtures/xmldsig/xmldsig11-interop-2012/signature-enveloping-p256_sha256.xml
  • tests/fixtures/xmldsig/xmldsig11-interop-2012/signature-enveloping-p384_sha384.xml
  • tests/fixtures_smoke.rs

Comment thread src/xmldsig/keys.rs
Comment thread src/xmldsig/parse.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/xmldsig/parse.rs (1)

2370-2374: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert the decoded EC point bytes, not only the length.

This positive P-384 case would still pass if the parser returned any 97-byte point. Compare public_key to the expected SEC1 bytes to cover the “preserve exact point bytes” contract for this fixture.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/xmldsig/parse.rs` around lines 2370 - 2374, The P-384 assertion in the EC
key parsing test only checks the point length, so it can miss regressions in the
decoded bytes. Update the test around the `assert!(matches!(...))` for
`KeyInfoSource::KeyValue(KeyValueInfo::Ec { curve_oid, public_key })` to compare
`public_key` against the expected SEC1-encoded bytes for this fixture, while
still verifying `EC_P384_OID`, so the exact point-preservation contract is
tested.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/xmldsig/keys.rs`:
- Around line 641-689: Add a regression test around the key resolution path in
VerifyContext/DefaultKeyResolver that exercises a document containing only an
invalid or curve-mismatched dsig11:ECKeyValue and no later fallback source. The
test should assert that verification returns the deferred typed error from
ECKeyValue handling, specifically InvalidPublicKey or AlgorithmMismatch, rather
than KeyNotFound or a silent ignore. Reuse the existing helpers and symbols like
replace_key_info, KeyResolverConfig, VerificationKey,
SignatureAlgorithm::EcdsaP256Sha256, and verify to locate and cover the
no-fallback branch.

---

Outside diff comments:
In `@src/xmldsig/parse.rs`:
- Around line 2370-2374: The P-384 assertion in the EC key parsing test only
checks the point length, so it can miss regressions in the decoded bytes. Update
the test around the `assert!(matches!(...))` for
`KeyInfoSource::KeyValue(KeyValueInfo::Ec { curve_oid, public_key })` to compare
`public_key` against the expected SEC1-encoded bytes for this fixture, while
still verifying `EC_P384_OID`, so the exact point-preservation contract is
tested.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d9adde8c-5f87-4058-827d-f3fd48b3169c

📥 Commits

Reviewing files that changed from the base of the PR and between f714343 and 7828213.

📒 Files selected for processing (2)
  • src/xmldsig/keys.rs
  • src/xmldsig/parse.rs

Comment thread src/xmldsig/keys.rs
@polaz

polaz commented Jun 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai Fixed the outside-diff P-384 parser test item. parse_ec_key_value_accepts_bare_curve_oid now compares the decoded public_key bytes against the expected SEC1 point while still asserting EC_P384_OID.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@polaz Sounds good — thanks for updating that test to assert both EC_P384_OID and the decoded SEC1 public_key bytes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/xmldsig/parse.rs`:
- Around line 627-633: The `public_key` parsing in `parse.rs` currently treats
all failures from `decode_crypto_binary` and `validate_ec_public_key_point` as
`KeyValueInfo::InvalidEcPublicKey`, which incorrectly makes malformed
`PublicKey` payloads fallback-eligible. Update the `public_key` match so only
successfully decoded values that fail `validate_ec_public_key_point` map to
`InvalidEcPublicKey`, while decode/structure/base64 errors from
`decode_crypto_binary` are returned as real parse failures. Use the `public_key`
decode block, `decode_crypto_binary`, and `validate_ec_public_key_point` to
separate fatal decode errors from non-fatal invalid EC-point cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 008a43bf-daf3-430b-b9a6-cd14100fb211

📥 Commits

Reviewing files that changed from the base of the PR and between 7828213 and cf71e2c.

📒 Files selected for processing (2)
  • src/xmldsig/keys.rs
  • src/xmldsig/parse.rs

Comment thread src/xmldsig/parse.rs Outdated
Comment thread src/xmldsig/parse.rs
Comment thread src/xmldsig/parse.rs Outdated
Comment thread src/xmldsig/parse.rs
Comment thread src/xmldsig/parse.rs Outdated
@polaz polaz merged commit a14c381 into main Jun 30, 2026
10 checks passed
@polaz polaz deleted the feat/#69-ec-key-value branch June 30, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(xmldsig): parse ECKeyValue parameters

1 participant