Skip to content

feat(xmldsig): add reference verification pipeline#20

Merged
polaz merged 18 commits intomainfrom
test/#19-donor-digest-vectors
Mar 26, 2026
Merged

feat(xmldsig): add reference verification pipeline#20
polaz merged 18 commits intomainfrom
test/#19-donor-digest-vectors

Conversation

@polaz
Copy link
Member

@polaz polaz commented Mar 26, 2026

Summary

  • add XMLDSig digest, SignedInfo parsing, and Reference verification modules
  • cover end-to-end Reference processing with integration tests and xmlsec1 donor vectors
  • accept the exact xmlsec-style XPath enveloped exclusion expression while continuing to reject other XPath expressions
  • use the latest stable Rust as the default toolchain while keeping crate MSRV at Rust 1.92
  • update CI to validate build and test on both stable and 1.92.0

Technical Details

  • move base64 to regular dependencies for runtime digest and parsing support
  • export the new XMLDSig modules from the crate root module surface
  • add fail-fast reference processing results and real-vector coverage for SHA-1, SHA-256, SHA-384, and SHA-512
  • preserve InclusiveNamespaces PrefixList for SignedInfo exclusive C14N, enforce digest-length invariants during parsing, and keep the compat XPath path fail-closed
  • add rust-toolchain.toml for the default stable developer/compiler target

Test Plan

  • cargo +stable nextest run --workspace
  • cargo +stable build
  • cargo +1.92.0 build

Closes #19

Copilot AI review requested due to automatic review settings March 26, 2026 08:49
@coderabbitai
Copy link

coderabbitai bot commented Mar 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dadd55a6-2877-46c7-923c-7a78417bdb1b

📥 Commits

Reviewing files that changed from the base of the PR and between b6bf910 and a3e9b06.

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

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added XMLDSig parsing, digest computation (SHA-1/256/384/512), and Reference verification with strict validation.
    • Added an XPath-compatible transform to exclude signature elements from digest input.
  • Chores

    • Updated project to Rust 2024 edition and pinned toolchain guidance; MSRV remains 1.92.
    • CI expanded to run tests across multiple Rust versions using nextest.
  • Tests

    • Added extensive unit and integration tests plus new XML fixtures for multiple digest scenarios.

Walkthrough

Implements XMLDSig Reference verification: adds digest algorithms, strict SignedInfo/Reference parsing, transform execution (including xmlsec-compatible XPath), URI dereferencing, digest computation and constant-time comparison, plus donor-based and integration tests and CI/toolchain updates.

Changes

Cohort / File(s) Summary
Core XMLDSig logic
src/xmldsig/digest.rs, src/xmldsig/parse.rs, src/xmldsig/verify.rs
New modules: digest algorithms (SHA-1/256/384/512) and constant-time compare; strict SignedInfo/Reference parsing with base64 decoding and digest-length checks; reference processing (URI dereference → transforms → digest → constant-time compare) with result types and fail-fast semantics.
Module exports & transforms
src/xmldsig/mod.rs, src/xmldsig/transforms.rs
Re-export digest/parse/verify APIs; add XpathExcludeAllSignatures transform supporting the exact xmlsec XPath not(ancestor-or-self::dsig:Signature) with strict prefix binding; implement exclusion behavior across all Signature subtrees.
Integration & donor tests
tests/reference_integration.rs, tests/donor_digest_vectors.rs
End-to-end integration tests exercising dereference → transforms → digest pipeline, multi-reference fail-fast, pre-digest storage, and donor-vector validation across SHA families.
Fixtures
tests/fixtures/xmldsig/aleksey-xmldsig-01/*
Added four donor XML fixtures (SHA-1, SHA-256, SHA-384, SHA-512) with enveloped signatures and XPath transforms.
CI / toolchain / manifest
Cargo.toml, rust-toolchain.toml, .github/workflows/ci.yml, README.md
Updated crate edition to 2024, promoted base64 to runtime dependency, added rust-toolchain, CI matrix/jobs using nextest, and documented MSRV (1.92).
Minor refactors & imports
src/c14n/..., tests/..., tests/c14n_golden.rs, tests/fixtures_smoke.rs
Small refactors and import/ordering adjustments, closure trait bound explicitness, and fixture-count update to include new donor files (no behavioral changes otherwise).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Parser as Parse
    participant Resolver as UriResolver
    participant Transform as Transforms
    participant Digest as Digest
    participant Verify as Verify

    Client->>Parser: parse_signed_info(xml)
    Parser-->>Client: SignedInfo + References[]

    loop for each Reference
        Client->>Resolver: dereference(uri)
        Resolver-->>Client: bytes

        Client->>Transform: execute_transforms(bytes, transforms)
        Transform-->>Client: transformed_bytes

        Client->>Digest: compute_digest(algorithm, transformed_bytes)
        Digest-->>Client: digest_bytes

        Client->>Verify: process_reference(ref, resolver)
        Verify->>Digest: compute_digest(...)
        Verify->>Verify: constant_time_eq(computed, stored)
        Verify-->>Client: ReferenceResult { valid, uri, digest_algorithm, pre_digest? }
    end

    Client->>Verify: process_all_references(all_refs, resolver)
    Verify-->>Client: ReferencesResult { all_valid, first_failure }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(xmldsig): add reference verification pipeline' clearly and specifically describes the main change - adding the reference verification pipeline module.
Description check ✅ Passed The description is directly related to the changeset, providing clear technical details about the XMLDSig modules, parsing, verification, and CI updates that are present in the PR.
Linked Issues check ✅ Passed The PR implements all acceptance criteria from issue #19: digest/parse/verify modules with strict validation, fail-fast reference processing, donor vector tests for SHA digests, and the exact xmlsec-style XPath expression support while rejecting arbitrary XPath.
Out of Scope Changes check ✅ Passed All changes are in scope: new xmldsig modules (digest, parse, verify), integration tests, donor fixture files, CI updates, toolchain configuration, and minor import reordering in existing test/config files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 test/#19-donor-digest-vectors

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an XMLDSig <Reference> verification pipeline to the xmldsig module, including strict parsing, transform execution, digest computation, and end-to-end validation against real xmlsec1 donor vectors.

Changes:

  • Introduces new xmldsig modules for digest computation, SignedInfo/Reference parsing, and reference verification (process_reference / process_all_references).
  • Extends transform parsing to accept a narrow xmlsec1-compatible XPath transform that is treated as enveloped-signature.
  • Adds integration tests plus donor-vector tests covering SHA-1/256/384/512 reference digest verification.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Cargo.toml Moves base64 into regular dependencies for runtime parsing/digest support.
src/xmldsig/digest.rs Adds SHA-family digest computation + constant-time digest comparison helpers.
src/xmldsig/parse.rs Adds strict parsing for <Signature>/<SignedInfo>/<Reference> including base64 digest decode.
src/xmldsig/transforms.rs Adds narrow XPath-compat parsing and maps it to the enveloped transform.
src/xmldsig/verify.rs Implements reference processing pipeline and fail-fast aggregation results.
src/xmldsig/mod.rs Exposes the new XMLDSig modules and re-exports key APIs/types.
tests/reference_integration.rs Adds integration coverage for reference processing behavior (enveloped, subtree URIs, fail-fast, algo variants).
tests/donor_digest_vectors.rs Adds xmlsec1 donor-vector digest verification tests across SHA families.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/xmldsig/digest.rs`:
- Around line 104-106: Replace the #[allow(deprecated)] on the constant_time_eq
function with #[expect(deprecated)] so the deprecation suppression becomes an
expect check; locate the constant_time_eq function that calls
ring::constant_time::verify_slices_are_equal and change the attribute to
#[expect(deprecated)] (preserving any existing behavior and return value).

In `@src/xmldsig/transforms.rs`:
- Around line 175-176: The compat XPath expression that matches
"not(ancestor-or-self::dsig:Signature)" must not be treated as
Transform::Enveloped because it excludes all dsig:Signature subtrees rather than
only the containing Signature; update parse_xpath_compat_transform so it returns
a distinct transform variant (e.g., Transform::XpathCompat or
Transform::XPathExcludeAllSignatures) instead of mapping to
Transform::Enveloped, add that new enum variant to Transform, and update any
match arms that special-case Transform::Enveloped (including wherever XPATH_URI
is parsed and later transform application code) to handle the new variant
correctly (or explicitly reject it where only the narrow donor-vector
enveloped-case is allowed). Ensure code paths that compare or apply transforms
use the new variant rather than collapsing into Enveloped, and include tests to
assert the two behaviors differ.

In `@src/xmldsig/verify.rs`:
- Around line 69-73: The code currently treats a missing Reference.uri as "" and
calls resolver.dereference, which conflates an omitted-URI (meaning the caller
must supply the signed object) with the null same-document URI; change this to
fail closed: detect when reference.uri is None and return an error instead of
using unwrap_or(""), e.g. add or use a ReferenceProcessingError variant like
MissingUri (or a suitably named variant) and return
Err(ReferenceProcessingError::MissingUri) when reference.uri.is_none(); only
call resolver.dereference(uri) when reference.uri is Some and pass the exact
dereferenced string.

In `@tests/donor_digest_vectors.rs`:
- Around line 15-18: The tests currently hard-code the gitignored donor corpus
in donor_xml, which causes panics on clean checkouts; either vendor the four
XMLs under a tracked tests/fixtures/ directory and update donor_xml to read from
that new path (replace Path::new("donors/...") with
Path::new("tests/fixtures/...")), or mark the donor-dependent integration tests
(the ones calling donor_xml around lines 50-67) with #[ignore = "requires donor
corpus"] so they are skipped by default; update the donor_xml function and the
test attributes accordingly to implement one of these two fixes.

In `@tests/reference_integration.rs`:
- Around line 384-385: The test function reference_with_inclusive_c14n should be
renamed to an explicit expected-outcome name (e.g.,
reference_with_inclusive_c14n_valid or inclusive_c14n_reference_verifies) to
follow naming convention; update the function declaration (fn
reference_with_inclusive_c14n -> fn reference_with_inclusive_c14n_valid) and
adjust any references to that symbol (calls, documentation, or CI/test filters)
so the test still runs under the new name.
- Around line 441-442: Rename the test function reference_with_sha384_digest to
a name that encodes the expected outcome (e.g., sha384_digest_reference_verifies
or reference_with_sha384_digest_valid) so the purpose is clear; update the
function declaration fn reference_with_sha384_digest() { to the chosen name and
make sure any references to this test symbol (such as module-level test listings
or documentation comments) are updated accordingly.
- Around line 558-559: The test function name
process_single_reference_with_pre_digest is ambiguous; rename the test to a more
descriptive name (e.g., process_single_reference_with_pre_digest_valid or
process_reference_stores_pre_digest_data) to express the expected outcome;
update the test function identifier process_single_reference_with_pre_digest
accordingly and adjust any references or test annotations so the new name
compiles and runs.
- Around line 142-143: The test function name
saml_assertion_level_enveloped_reference should be renamed to
saml_assertion_level_enveloped_reference_valid to follow the
<what>_<condition>_<expected>() guideline; update the function identifier in the
test declaration and any references (e.g., module tests or test filters) that
refer to saml_assertion_level_enveloped_reference so they use
saml_assertion_level_enveloped_reference_valid instead.
🪄 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

Run ID: 5a4d4a0f-7216-4261-8df9-2ababe5e6444

📥 Commits

Reviewing files that changed from the base of the PR and between df7d39d and d6d78e8.

📒 Files selected for processing (9)
  • Cargo.toml
  • src/xmldsig/digest.rs
  • src/xmldsig/mod.rs
  • src/xmldsig/parse.rs
  • src/xmldsig/transforms.rs
  • src/xmldsig/verify.rs
  • tests/c14n_golden.rs
  • tests/donor_digest_vectors.rs
  • tests/reference_integration.rs

polaz added 4 commits March 26, 2026 11:08
- add digest, SignedInfo parsing, and reference verification modules
- cover donor digest vectors and XPath-compatible enveloped parsing
- expand XMLDSig integration tests for end-to-end reference processing

Closes #19
- switch the crate manifest to Rust 2024 with rust-version 1.85
- apply the edition-driven return-position impl Trait syntax update

Refs #19
- pin the default toolchain to Rust 1.94.0
- raise rust-version to 1.92 and add an MSRV CI job
- run CI tests with cargo nextest instead of cargo test

Refs #19
- require exactly one ds:XPath child in the XMLDSig namespace
- reject extra element children and duplicate XPath nodes

Refs #19
@polaz polaz force-pushed the test/#19-donor-digest-vectors branch from bbfa338 to ee31e62 Compare March 26, 2026 09:13
@polaz polaz requested a review from Copilot March 26, 2026 09:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

polaz added 2 commits March 26, 2026 11:22
- split compat XPath semantics from enveloped-signature
- fail closed on omitted reference URI and vendor donor fixtures
- rename integration tests to encode expected outcomes
- remove implicit From mapping from URI dereference errors
- reject compat XPath when dsig prefix is bound outside XMLDSig
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/xmldsig/mod.rs`:
- Around line 18-27: The pub use lines in mod.rs are not formatted in rustfmt's
expected ordering; run cargo fmt (or rustfmt) to reorder the imports so they
match project style/lexicographic order—for example adjust the grouped exports
around compute_digest, constant_time_eq, DigestAlgorithm, find_signature_node,
parse_signed_info, ParseError, Reference, SignatureAlgorithm, SignedInfo,
execute_transforms, parse_transforms, Transform, NodeSet, TransformData,
TransformError, process_all_references, process_reference,
ReferenceProcessingError, ReferenceResult, and ReferencesResult so rustfmt
passes CI.

In `@src/xmldsig/parse.rs`:
- Around line 71-74: The public method signing_allowed() should be annotated
with #[must_use] to prevent callers from accidentally ignoring its boolean
result (which enforces the RSA-SHA1 restriction); update the pub fn
signing_allowed(self) -> bool signature by adding the #[must_use] attribute
above the function (leave the implementation using matches!(self, Self::RsaSha1)
unchanged) so any discard of the return value will trigger a compiler warning.
- Around line 136-143: The public function find_signature_node returns an Option
that callers may accidentally ignore; add the #[must_use] attribute to its
declaration to warn users when its return value is discarded. Locate the
find_signature_node function and annotate it with #[must_use] immediately above
pub fn find_signature_node<'a>(doc: &'a Document<'a>) -> Option<Node<'a, 'a>> so
the compiler emits a warning if callers do not use the Option result.
- Around line 293-294: The import ordering violates rustfmt alphabetical rules:
move the `use base64::Engine;` line so it appears before `use
base64::engine::general_purpose::STANDARD;` (i.e., reorder the two `use`
statements referencing `base64` so `Engine` precedes
`engine::general_purpose::STANDARD`).

In `@src/xmldsig/verify.rs`:
- Around line 162-166: The imports inside the tests module are not ordered
according to rustfmt; reorder the use statements (for DigestAlgorithm,
parse_signed_info, Reference, Transform, UriReferenceResolver, and Document)
into the canonical rustfmt order (group extern crates, then crate::... items,
alphabetize within groups) so the tests module passes CI formatting
checks—adjust the use declarations in the tests module of src/xmldsig/verify.rs
accordingly.
- Around line 42-47: The public method ReferencesResult::all_valid() should be
annotated with #[must_use] so callers cannot accidentally ignore its boolean
result; update the impl for ReferencesResult by adding the #[must_use] attribute
directly above the pub fn all_valid(&self) -> bool declaration and keep the
method body unchanged so callers receive a compiler warning if they discard the
returned bool.
- Line 14: The import list in verify.rs is not sorted for rustfmt/CI — reorder
the items in the use super::digest::{...} statement so symbols are alphabetized
(put DigestAlgorithm before compute_digest, and ensure constant_time_eq is
placed in correct alphabetical position) so the line becomes alphabetically
ordered among compute_digest, constant_time_eq, and DigestAlgorithm; update that
single use line accordingly.

In `@tests/c14n_golden.rs`:
- Line 199: Run rustfmt (cargo fmt) to fix formatting and resolve the import
ordering drift; specifically, sort and group the use/import statements around
the top of the file (the block near the subtree_predicate definition) into
canonical alphabetical order and remove the stray "+ use<>" token from the fn
subtree_predicate signature so it reads a valid Rust signature (e.g., fn
subtree_predicate(root: roxmltree::Node) -> impl Fn(roxmltree::Node) -> bool).
After formatting, re-run CI or cargo fmt -- --check to confirm the file is
clean.

In `@tests/reference_integration.rs`:
- Around line 13-18: The imports in tests/reference_integration.rs are
mis-ordered for rustfmt; run cargo fmt or reorder the use statements so they
follow rustfmt's canonical ordering (e.g. group and alphabetize the
base64::Engine import and the xml_sec::xmldsig::* imports such as
digest::{compute_digest, DigestAlgorithm}, parse::{find_signature_node,
parse_signed_info}, transforms::execute_transforms, uri::UriReferenceResolver,
and verify::{process_all_references, process_reference}) to satisfy CI.
🪄 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

Run ID: 5e61951d-6e97-4884-a20d-d1851a9e780f

📥 Commits

Reviewing files that changed from the base of the PR and between bbfa338 and 8aeb7f5.

📒 Files selected for processing (18)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • Cargo.toml
  • README.md
  • rust-toolchain.toml
  • src/xmldsig/digest.rs
  • src/xmldsig/mod.rs
  • src/xmldsig/parse.rs
  • src/xmldsig/transforms.rs
  • src/xmldsig/verify.rs
  • tests/c14n_golden.rs
  • tests/donor_digest_vectors.rs
  • tests/fixtures/xmldsig/aleksey-xmldsig-01/enveloped-sha1-rsa-sha1.xml
  • tests/fixtures/xmldsig/aleksey-xmldsig-01/enveloped-sha256-ecdsa-sha256.xml
  • tests/fixtures/xmldsig/aleksey-xmldsig-01/enveloped-sha384-ecdsa-sha384.xml
  • tests/fixtures/xmldsig/aleksey-xmldsig-01/enveloped-x509-digest-sha512.xml
  • tests/fixtures_smoke.rs
  • tests/reference_integration.rs

- normalize formatter-driven import ordering and layout
- collapse clippy-reported nested if chains in c14n and xmldsig
- keep workspace build, fmt, clippy, and nextest clean
polaz added 3 commits March 26, 2026 11:35
- annotate SignatureAlgorithm::signing_allowed with #[must_use]
- prevent callers from silently discarding the signing policy check
- annotate find_signature_node with #[must_use]
- surface discarded signature lookup results to callers
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

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

173-212: ⚠️ Potential issue | 🟠 Major

Reject empty <ds:Transforms> instead of treating it as “no transforms”.

If <Transforms> is present but contains zero <Transform> children, this returns Ok(vec![]), and execute_transforms() later falls back to default inclusive C14N. That turns malformed references into no-transform references instead of failing closed.

🔧 Suggested fix
     for child in transforms_node.children() {
         if !child.is_element() {
             continue;
         }
@@
         };
         chain.push(transform);
     }
 
+    if chain.is_empty() {
+        return Err(TransformError::UnsupportedTransform(
+            "<ds:Transforms> must contain at least one <ds:Transform> child".into(),
+        ));
+    }
+
     Ok(chain)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/xmldsig/transforms.rs` around lines 173 - 212, The parser currently
returns Ok(vec![]) when a <ds:Transforms> element contains no <Transform>
children, which causes execute_transforms() to treat it as "no transforms"
instead of failing closed; after the loop that builds the local variable chain
(the Vec named chain that iterates transforms_node.children()), add a check that
if chain.is_empty() you return an Err(TransformError::UnsupportedTransform(...))
indicating an empty <Transforms> element (refer to transforms_node, chain, and
the TransformError::UnsupportedTransform variant), otherwise continue to return
Ok(chain).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/xmldsig/parse.rs`:
- Around line 156-165: parse_signed_info currently only reads the
CanonicalizationMethod URI (via required_algorithm_attr) and loses any
ec:InclusiveNamespaces PrefixList child; update the CanonicalizationMethod
handling (around c14n_node / verify_ds_element / required_algorithm_attr) to
also look for a child element named "InclusiveNamespaces" (namespace/ec prefix
as used in verify_ds_element) and extract its PrefixList attribute, then
construct the C14nAlgorithm with those inclusive prefixes (either by calling a
new/overloaded constructor on C14nAlgorithm or passing the prefixes into
C14nAlgorithm::from_uri so the returned variant for Exclusive C14N preserves the
prefixes). If the InclusiveNamespaces child exists but the algorithm URI is not
an Exclusive C14N type, return a ParseError::UnsupportedAlgorithm or a new
ParseError variant. Ensure you reference c14n_node, required_algorithm_attr,
C14nAlgorithm::from_uri (or its new signature) and parse_signed_info in your
changes.

In `@src/xmldsig/transforms.rs`:
- Around line 247-255: The code currently collapses all ASCII whitespace in the
XPath literal by using text.split_whitespace().collect::<String>(), which allows
malformed inputs to normalize to ENVELOPED_SIGNATURE_XPATH_EXPR; change the
normalization to only trim leading/trailing XML whitespace instead (use
text.trim().to_string() from the xpath_node.text() result) so interior
whitespace remains significant, then continue to compare expr ==
ENVELOPED_SIGNATURE_XPATH_EXPR and check the dsig namespace via
xpath_node.lookup_namespace_uri(Some("dsig")) == Some(XMLDSIG_NS_URI) before
returning Transform::XpathExcludeAllSignatures.

---

Outside diff comments:
In `@src/xmldsig/transforms.rs`:
- Around line 173-212: The parser currently returns Ok(vec![]) when a
<ds:Transforms> element contains no <Transform> children, which causes
execute_transforms() to treat it as "no transforms" instead of failing closed;
after the loop that builds the local variable chain (the Vec named chain that
iterates transforms_node.children()), add a check that if chain.is_empty() you
return an Err(TransformError::UnsupportedTransform(...)) indicating an empty
<Transforms> element (refer to transforms_node, chain, and the
TransformError::UnsupportedTransform variant), otherwise continue to return
Ok(chain).
🪄 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

Run ID: 302a391c-db02-4872-9520-6da89c1719bb

📥 Commits

Reviewing files that changed from the base of the PR and between 8aeb7f5 and 0de6ea0.

📒 Files selected for processing (14)
  • src/c14n/mod.rs
  • src/c14n/ns_exclusive.rs
  • src/c14n/ns_inclusive.rs
  • src/c14n/serialize.rs
  • src/c14n/xml_base.rs
  • src/xmldsig/mod.rs
  • src/xmldsig/parse.rs
  • src/xmldsig/transforms.rs
  • src/xmldsig/verify.rs
  • tests/c14n_golden.rs
  • tests/c14n_integration.rs
  • tests/reference_integration.rs
  • tests/transforms_integration.rs
  • tests/uri_integration.rs

@polaz polaz requested a review from Copilot March 26, 2026 10:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.

Copy link

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/xmldsig/parse.rs`:
- Around line 46-57: Add the #[must_use] attribute to the public function
from_uri so callers are warned if they discard its Option<Self> result; update
the signature of the impl method from_uri (the XML algorithm URI parser) to be
annotated with #[must_use] to enforce the lint and prevent silent ignores of
unsupported algorithm lookups.
🪄 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

Run ID: dfec09cd-fbc6-4fc1-9ea1-45a2ef7b0128

📥 Commits

Reviewing files that changed from the base of the PR and between 0de6ea0 and 512a163.

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.

polaz added 2 commits March 26, 2026 12:48
- run doc tests alongside nextest in CI
- mark SignatureAlgorithm::from_uri as must_use
- remove the empty dev-dependencies section
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

- replace moving rust-toolchain @master refs with @stable in CI jobs
- reword XPath compatibility errors so they describe XMLDSig namespace requirements without implying a literal ds prefix
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

- keep stable and MSRV validation in matrix jobs
- add top-level build and test aggregator jobs for branch protection
Copy link

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/xmldsig/parse.rs`:
- Around line 60-70: The public method uri() should be annotated with
#[must_use] so callers don't accidentally ignore its &'static str return; add
the #[must_use] attribute above the impl method named uri() in the same enum
where from_uri() and signing_allowed() live to match their annotations and
ensure the returned namespace URI isn't discarded by callers.
🪄 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

Run ID: 2feb73fe-3af5-44b5-8f7c-e8a54dd151c6

📥 Commits

Reviewing files that changed from the base of the PR and between 0de6ea0 and b6bf910.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • Cargo.toml
  • README.md
  • rust-toolchain.toml
  • src/xmldsig/parse.rs
  • src/xmldsig/transforms.rs
  • tests/reference_integration.rs

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

- add must_use to SignatureAlgorithm::uri for API consistency
- keep parse API warnings aligned across xmldsig algorithm helpers
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

@polaz polaz merged commit eef9f8f into main Mar 26, 2026
13 checks passed
@polaz polaz deleted the test/#19-donor-digest-vectors branch March 26, 2026 15:35
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: add XMLDSig reference verification pipeline and donor coverage

2 participants