Skip to content

feat(xmldsig): complete Merlin interop - #108

Merged
polaz merged 4 commits into
mainfrom
feat/#105-merlin-interop
Aug 13, 2026
Merged

feat(xmldsig): complete Merlin interop#108
polaz merged 4 commits into
mainfrom
feat/#105-merlin-interop

Conversation

@polaz

@polaz polaz commented Aug 12, 2026

Copy link
Copy Markdown
Member

Summary

  • complete verification coverage for the tracked Merlin XMLDSig interoperability corpus, including document-level and reference-level assertions
  • add pure-Rust DSA-SHA1 and HMAC-SHA1 verification with strict legacy-algorithm policies and caller-bound HMAC output lengths
  • support bounded caller-provided external resources resolved against effective xml:base, including RFC 3986 normalization, inherited-base bypass for scheme-bearing identities, network-path URIs, and a consistent internal-DTD policy for root and detached XML
  • support namespace-aware X.509 RetrievalMethod resolution, authenticated CRL handling, and bounded manifest references
  • enumerate signature-valid X.509 paths through configured lookup intermediates, stop at explicit trust anchors, validate cross-signed alternatives, and keep unsupported branches from suppressing valid sibling paths
  • bind every X.509 selector category to one signature-valid selected path while preserving legitimate leaf/intermediate/root selector sets
  • enforce typed RFC 5280 ExtendedKeyUsage policy across complete certificate paths, including critical EKU and custom purpose OIDs, while preserving anyExtendedKeyUsage semantics and fail-closed resolver/operation policy intersection
  • preserve OpenSSL/xmlsec1 path compatibility for historical non-critical CA BasicConstraints while enforcing cA and keyCertSign
  • validate AES-KW KEK size before custom-provider dispatch and bound lexical KeySize metadata before integer parsing
  • make resolved X.509 RetrievalMethod resource identities explicit and cover inherited xml:base plus dot-segment normalization
  • enforce RFC 5280 path-length, self-issued rollover, NameConstraints syntax, malformed SAN, duplicate-extension, critical-extension, complete-CRL reason-code, and revocation rules during certificate-path validation
  • enforce RFC 4055 RSASSA-PSS issuer-SPKI restrictions when parameters are present while accepting parameterless unrestricted PSS keys
  • enforce typed RSA and DSA issuer-key strength policy before X.509 certificate and applicable CRL authentication
  • apply the immutable operation key-strength policy identically to direct and resolver-produced built-in verification keys
  • verify X.509 DSA-SHA1 DER signatures at the issuer's subgroup width without applying XMLDSig's fixed-width wire framing
  • apply legacy RSA-SHA1 policy independently of named, DER, KeyValue, or X.509 key source while preserving backend interoperability capability
  • introduce immutable verify/sign/encrypt/decrypt policy snapshots with typed violations, a shared pre-parse XML document byte ceiling, caller-owned node accounting, and fail-closed resolver trust composition
  • enforce shared typed RSA modulus/exponent policy before outbound signing and OAEP provider dispatch, with a 2048-bit secure default and an absolute 8192-bit implementation ceiling
  • route digest, signature dispatch, typed X.509 algorithms with built-in RSA-PSS/Ed25519 authentication and custom-provider dispatch for modeled OIDs, AES-CBC/GCM, AES-KW, RSA-OAEP, and randomness through an explicit capability-queryable RustCrypto provider without fallback, with ECDSA hash selection independent of the P-256/P-384/P-521 SPKI curve
  • enforce facade-owned cryptographic framing around custom-provider dispatch, including fixed digest and signature outputs plus AES-CBC/GCM, AES-KW, and modulus-sized RSA-OAEP inputs and outputs
  • reject zero typed KeySize values and non-SHA1 MGF configuration for legacy rsa-oaep-mgf1p before resolver or custom-provider dispatch
  • accept direct typed X509Data retrieval without a transform while requiring explicit XPath selection when the dereferenced root is a wrapper
  • separate signed-payload URI policy from key-retrieval URI policy so external key material always requires its own explicit opt-in
  • preserve failed or unsupported advisory RetrievalMethod sources so resolvers can continue to later usable key material while retaining the original failure when no source resolves
  • enforce transform allowlists from the complete terminal data type, share one Reference ceiling across SignedInfo and authenticated Manifests, bound external XML reparsing, and cap canonicalized SignedInfo plus retained pre-digest diagnostics across a signature
  • import the complete required Merlin fixture snapshot through a reproducible curated importer that preserves donor bytes while removing non-fixture prose and normalizing the historical HMAC filename
  • pin reciprocal interoperability to the exact xmlsec1 1.3.13 Git object with source-identity verification, transactional installer rollback, and strict fresh-and-cached version-output validation
  • enforce positive X.509 serial numbers, matching signed and outer signature algorithms, X.520-prepared RFC 4514 issuer/subject matching, and untrusted lookup/intermediate paths that terminate only at explicit trust anchors
  • add SHA-256 X509Digest coverage and a bounded XMLDSig verification fuzz target seeded with a complete valid X.509 signature
  • harden CI with read-only permissions, credential-free checkouts, and an explicit fuzz runtime budget
  • replace the vulnerable RSA private-operation backend with hardened pure-Rust sad-rsa, update cryptographic dependency requirements, and synchronize public documentation

Testing

  • cargo build
  • cargo build --no-default-features
  • cargo build --all-features
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo nextest run --all-features
  • cargo test --doc --all-features
  • cargo +nightly fuzz run xmldsig_verify -- -runs=256 -max_len=65536

Closes #105

Implement the complete pure-Rust Merlin XMLDSig interoperability pipeline, including bounded external resources, DSA/HMAC verification, X.509 path and CRL validation, typed policy, provider trust boundaries, donor fixtures, fuzzing, reciprocal xmlsec1 coverage, and public documentation.

Closes #105
@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown

Too many files changed for review (107 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

@coderabbitai

coderabbitai Bot commented Aug 12, 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: 1d4b58ac-aa7c-4505-a9e6-2432b16853d6

📥 Commits

Reviewing files that changed from the base of the PR and between 30d5780 and a204966.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • docs/xmldsig.md
  • fuzz/corpus/xmldsig_verify/signature.xml
  • fuzz/fuzz_targets/xmldsig_verify.rs
  • src/provider.rs
  • src/xmldsig/keys.rs
  • src/xmldsig/signature.rs
  • src/xmldsig/verify.rs
  • src/xmldsig/x509.rs
  • tests/donor_negative_vectors.rs
  • tests/import_donor_fixtures.rs
  • tests/merlin_interop.rs
  • tests/x509_chain_integration.rs

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added broader XML signature and encryption support, including DSA, HMAC, Ed25519, certificate chains, external references, and configurable cryptography providers.
    • Added configurable signing, verification, encryption, and decryption policies with resource limits.
  • Bug Fixes

    • Improved XML Base resolution, URI handling, namespace validation, malformed-input rejection, and encryption validation.
    • Added stronger protection against oversized documents, resources, signatures, and encryption payloads.
  • Documentation

    • Expanded XMLDSig and XML encryption guidance, compatibility notes, and supported algorithm coverage.
  • Tests

    • Added extensive interoperability, certificate, resource-limit, installation, and fuzzing coverage.

Walkthrough

The change adds typed security policies, pluggable cryptographic providers, bounded XML and URI processing, expanded XMLDSig and XMLEnc support, Merlin interoperability fixtures, fuzzing, and pinned xmlsec1 CI installation.

Changes

XML security foundation

Layer / File(s) Summary
Policy and cryptographic provider foundation
Cargo.toml, src/policy.rs, src/provider.rs, src/hard_limits.rs, src/xml.rs, src/xmldsig/digest.rs
Adds operation policies, hard resource ceilings, provider-neutral cryptography, RustCrypto implementations, shared XML name validation, and provider-aware digesting.
Bounded canonicalization and URI resolution
src/c14n/*, src/xmldsig/transforms.rs, src/xmldsig/types.rs, src/xmldsig/uri.rs, src/xmldsig/xpath.rs
Propagates XML Base, node, canonicalization, and external-resource budgets through XMLDSig processing.
XMLDSig parsing, signing, and verification
src/xmldsig/parse.rs, src/xmldsig/signature.rs, src/xmldsig/sign.rs, src/xmldsig/mutation.rs
Adds DSA-SHA1, HMAC-SHA1, generic ECDSA algorithms, RetrievalMethod parsing, normalized X.509 processing, policy-aware signing, and signature framing checks.
Policy-aware XML encryption and decryption
src/xmlenc/*
Routes encryption and decryption through providers and enforces structural, metadata, recipient, plaintext, document, DTD, and replacement limits.

Interoperability and tooling

Layer / File(s) Summary
Fixtures and interoperability validation
tests/fixtures/xmldsig/*, tests/merlin_interop.rs, tests/x509_chain_integration.rs, tests/*integration*.rs
Adds Merlin and XMLSec fixtures and expands tests for algorithms, external resources, certificates, manifests, CRLs, and policies.
Pinned xmlsec1 tooling and fuzzing
.github/workflows/ci.yml, scripts/install-xmlsec1.sh, scripts/import-donor-fixtures.sh, fuzz/*, tests/install_xmlsec1.rs, tests/common/xmlsec1.rs
Adds transactional xmlsec1 installation, shared version checks, fixture normalization, fuzz verification, and a nightly fuzz smoke job.

Documentation and support matrix

Layer / File(s) Summary
Capability and policy documentation
README.md, docs/xmldsig.md, docs/xmlenc.md, tests/fixtures/xmldsig/README.md, tests/fixtures/xmlenc/README.md, CHANGELOG.md
Documents algorithms, policies, resource limits, certificate validation, external resources, DTD behavior, encryption validation, and the pinned fixture source.

Estimated code review effort: 5 (Critical) | ~120 minutes

Mergeability Score: ⚪ Minimal · up to a2049

This PR expands XMLDSig/X.509 interoperability and cryptographic policy enforcement; no actionable correctness, security, or availability risk remains at the current head, so it is merge-ready after normal checks.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant SignContext
  participant TransformExecutionBudget
  participant CryptoProvider
  participant XMLDocument
  Caller->>SignContext: configure SigningPolicy and CryptoProvider
  SignContext->>XMLDocument: parse and mutate with policy
  SignContext->>TransformExecutionBudget: create shared transform budgets
  TransformExecutionBudget->>XMLDocument: canonicalize with XML Base and output limits
  SignContext->>CryptoProvider: digest and sign canonicalized data
  CryptoProvider-->>SignContext: return signature bytes
  SignContext->>XMLDocument: validate generated signature document
  SignContext-->>Caller: return signed XML
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes substantial XML Encryption implementation, documentation, and test changes that are not covered by the linked XMLDSig interoperability issue [#105]. Move XML Encryption changes to a separate issue or link the relevant XML Encryption requirements to this pull request.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately identifies the primary change: completing Merlin XMLDSig interoperability.
Description check ✅ Passed The description directly summarizes Merlin interoperability, cryptographic support, policy changes, testing, and fixture work in the changeset.
Linked Issues check ✅ Passed The changes address the linked Merlin interoperability objectives, including DSA, HMAC, external resources, X.509 validation, fixtures, and exhaustive tests [#105].
Docstring Coverage ✅ Passed Docstring coverage is 84.70% which is sufficient. The required threshold is 80.00%.
✨ 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/#105-merlin-interop

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.

❤️ Share

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c255360e64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/xmldsig/x509.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: 15

Caution

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

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

588-602: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Remove the second synthetic parse; is_xml_ncname already covers it.

is_xml_ncname parses <{value}/> and confirms that the resulting tag name equals value. Any value that reaches line 598 is therefore already a valid XML NCName, and a valid NCName is always a valid namespace prefix. The declaration parse adds a second document allocation and parse without adding a constraint.

Keep the reserved-prefix rejection and drop the redundant parse.

♻️ Proposed simplification
 fn is_namespace_prefix(value: &str) -> bool {
     // Namespaces in XML reserves these names regardless of the URI being bound.
-    // Keep the invariant explicit instead of depending on parser rejection of a
-    // synthetic declaration assembled below.
-    if matches!(value, "xml" | "xmlns") || !is_xml_ncname(value) {
-        return false;
-    }
-
-    // Parsing delegates the complete Unicode XML Name grammar to the same parser
-    // used by the rest of the crate.
-    roxmltree::Document::parse(&format!(
-        "<{value}:n xmlns:{value}=\"urn:xml-sec:prefix-validation\"/>"
-    ))
-    .is_ok()
+    // The shared helper delegates the complete Unicode XML Name grammar to the
+    // same parser used by the rest of the crate.
+    !matches!(value, "xml" | "xmlns") && is_xml_ncname(value)
 }
🤖 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/builder.rs` around lines 588 - 602, Simplify is_namespace_prefix
by retaining the reserved-name and !is_xml_ncname checks, then returning true
once those checks pass. Remove the synthetic roxmltree::Document::parse
declaration validation, since is_xml_ncname already establishes the required
validity.
src/xmldsig/parse.rs (1)

76-95: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Document the breaking API changes and add #[non_exhaustive] to SignatureAlgorithm and SignedInfo.

ParseError is already #[non_exhaustive]. Document the SignatureAlgorithm renames, new variants, and SignedInfo::hmac_output_length_bits in the changelog and migration notes.

🤖 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 76 - 95, Mark the public
SignatureAlgorithm enum and SignedInfo struct with #[non_exhaustive] to preserve
future extensibility. Add changelog and migration-note entries documenting the
SignatureAlgorithm renames, newly added variants, and the
SignedInfo::hmac_output_length_bits API change, while leaving ParseError
unchanged.
🤖 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 `@Cargo.toml`:
- Around line 31-52: Review the RSA dependency and all RSA signing/OAEP
private-key operations in the affected cryptographic code, then remove or
replace the vulnerable rsa 0.10.0-rc.18 path before merging. If RSA must remain,
add an explicit documented mitigation and ensure the dependency cannot enable
the vulnerable private-key operations by default.

In `@docs/xmldsig.md`:
- Around line 133-148: Add a synchronization test that derives or references the
documented 8 MiB resource, 32 MiB aggregate, 64-component, and 1 MiB
URI-resolution ceilings from their implementation constants and fails when they
diverge. Keep the documentation values unchanged and anchor the check to the
existing resource-policy and URI-resolution limit symbols.

In `@docs/xmlenc.md`:
- Around line 106-125: Update the decryption documentation to refer to
DecryptionPolicy instead of EncryptionPolicy for both data_algorithms and
xml.allow_internal_dtd, while retaining DocumentDecryptionOptions::allow_dtd and
the existing behavior descriptions.

In `@scripts/import-donor-fixtures.sh`:
- Around line 53-59: Update the rename logic in normalize_imported_snapshot so
it checks whether the destination signature-enveloping-hmac-sha1-80.$extension
path already exists before invoking mv. Fail the import without overwriting
either fixture, preserving donor-provided bytes when both -40 and -80 names are
present.

In `@src/policy.rs`:
- Around line 245-250: Centralize the resource ceilings in src/hard_limits.rs
and reuse them everywhere: update src/policy.rs lines 245-250 and
KeyTrustPolicy::validate to use shared constants instead of the literal 64 and 9
values; move MAX_X509_CHAIN_DEPTH and MAX_REFERENCES_PER_SIGNATURE from
src/xmldsig/parse.rs lines 71-74 into src/hard_limits.rs and update the parser
to reference them.
- Around line 467-488: Extend VerificationPolicy::check_signature_algorithm in
src/policy.rs:467-488 so DsaSha1 and HmacSha1, like RsaSha1, require
allow_legacy_rsa_sha1 before verification. Also update verify_dsa_signature_spki
in src/xmldsig/signature.rs:274-303 to enforce the configured minimum DSA key
size, mirroring verify_rsa_signature_spki_with_minimum.

In `@src/provider.rs`:
- Around line 1006-1016: Update the CBC decryption path around decrypt_cbc so
invalid block decryption and invalid XMLEnc padding both return the same
ProviderError::InvalidInput(ProviderInputError::AesCbcCiphertext) variant.
Replace the distinct XmlEncCbcPadding error for invalid padding length,
preserving successful padding validation and plaintext handling.
- Line 781: Update compatible_rsa_pss_public_key_from_spki and its callers to
derive the issuer RSA minimum from RsaKeyPolicy::minimum_modulus_bits, threading
that configured value through to validate_rsa_key_components instead of using
the literal 2048; keep the provider behavior aligned with
verify_rsa_signature_spki_with_minimum.

In `@src/xmldsig/mutation.rs`:
- Around line 22-30: Clamp caller-provided ResourcePolicy limits to the
corresponding hard limits before use: in src/xmldsig/mutation.rs lines 22-30,
cap policy.resources.max_xml_nodes at XML_DOCUMENT_NODE_CEILING before assigning
nodes_limit; in src/xmldsig/transforms.rs lines 305-316, cap max_xml_nodes,
max_canonicalized_bytes, max_xml_base_components, and
max_xml_base_resolution_bytes at their corresponding constants before
constructing budgets. Apply this centrally in ResourcePolicy::validate if that
validation path is guaranteed, otherwise clamp at both derivation sites.

In `@src/xmldsig/parse.rs`:
- Around line 1735-1795: Update trailing_whitespace_is_escaped to recognize
trailing spaces, tabs, carriage returns, and newlines, matching the whitespace
characters removed by both loops in parse_distinguished_name. Preserve the
existing backslash-parity check so escaped trailing whitespace is retained.

In `@src/xmldsig/signature.rs`:
- Around line 385-396: Add a dedicated SignatureVerificationError variant
carrying the RsaKeyPolicy PolicyViolation, then update
validate_rsa_key_components to preserve and return the original violation
instead of mapping every failure to InvalidKeyDer; keep malformed-key errors
distinct and update any required error conversions or constructors.

In
`@tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-retrievalmethod-rawx509crt.tmpl`:
- Line 14: Update the RetrievalMethod URI in the signature-retrieval fixture to
reference tests/merlin-xmldsig-twenty-three/certs/balor.der instead of the
nonexistent dsa-1024-cert.der path, preserving the rawX509Certificate Type and
matching the signed fixture resolver mapping.

In `@tests/merlin_interop.rs`:
- Around line 314-321: Replace the broad is_err assertions in
tests/merlin_interop.rs at lines 314-321, 385-391, 393-403, and 409-416 with
exact pattern matches: assert DsigError::Reference containing
UnsupportedUri("http://www.w3.org/TR/xml-stylesheet"),
DsigError::ParseSignedInfo(ParseError::InvalidStructure("HMACOutputLength must
be a byte-aligned value from 80 through 160")), DsigError::InvalidStructure with
the specified SignatureValue length reason, and
DsigError::ParseKeyInfo(ParseError::Base64(_)), respectively.

In `@tests/signing_digest.rs`:
- Around line 631-640: Refine the assertion around
SignContext::new(...).sign_template(&xml) to match SigningError::Policy
containing PolicyViolation::Algorithm with operation "SignedInfo
canonicalization", then assert the reported algorithm equals
exclusive_c14n().uri(). Preserve the existing rejection expectation while
ensuring unrelated policy violations cannot satisfy the test.

In `@tests/xmlsec1_interop.rs`:
- Around line 241-244: Update the skip messages in all 11 listed sites in
tests/xmlsec1_interop.rs (lines 241-244, 264-267, 285-288, 326-329, 349-352,
385-388, 408-411, 443-446, 482-485, 514-517, and 559-562) to state that xmlsec1
>= 1.3.13 is required. Prefer a shared xmlsec1::skip_reason() helper in
tests/common/xmlsec1.rs derived from REQUIRED_VERSION, and use it from each
affected test so messages stay synchronized with the pinned version.

---

Outside diff comments:
In `@src/xmldsig/builder.rs`:
- Around line 588-602: Simplify is_namespace_prefix by retaining the
reserved-name and !is_xml_ncname checks, then returning true once those checks
pass. Remove the synthetic roxmltree::Document::parse declaration validation,
since is_xml_ncname already establishes the required validity.

In `@src/xmldsig/parse.rs`:
- Around line 76-95: Mark the public SignatureAlgorithm enum and SignedInfo
struct with #[non_exhaustive] to preserve future extensibility. Add changelog
and migration-note entries documenting the SignatureAlgorithm renames, newly
added variants, and the SignedInfo::hmac_output_length_bits API change, while
leaving ParseError unchanged.
🪄 Autofix

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: 7eb3dd5d-1425-49f8-9e53-56fbb70cff25

📥 Commits

Reviewing files that changed from the base of the PR and between 0bf4812 and c255360.

⛔ Files ignored due to path filters (10)
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/badb.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/balor.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/bres.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/ca.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh-cert.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/macha.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/merlin.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/morigu.pem is excluded by !**/*.pem
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/nemain.pem is excluded by !**/*.pem
📒 Files selected for processing (94)
  • .gitattributes
  • .github/workflows/ci.yml
  • .gitignore
  • Cargo.toml
  • README.md
  • docs/xmldsig.md
  • docs/xmlenc.md
  • fuzz/Cargo.toml
  • fuzz/corpus/xmldsig_verify/signature.xml
  • fuzz/fuzz_targets/xmldsig_verify.rs
  • scripts/import-donor-fixtures.sh
  • scripts/install-xmlsec1.sh
  • src/c14n/mod.rs
  • src/c14n/serialize.rs
  • src/c14n/xml_base.rs
  • src/hard_limits.rs
  • src/lib.rs
  • src/policy.rs
  • src/provider.rs
  • src/xml.rs
  • src/xmldsig/builder.rs
  • src/xmldsig/digest.rs
  • src/xmldsig/keys.rs
  • src/xmldsig/mod.rs
  • src/xmldsig/mutation.rs
  • src/xmldsig/parse.rs
  • src/xmldsig/sign.rs
  • src/xmldsig/signature.rs
  • src/xmldsig/transforms.rs
  • src/xmldsig/types.rs
  • src/xmldsig/uri.rs
  • src/xmldsig/verify.rs
  • src/xmldsig/x509.rs
  • src/xmldsig/xpath.rs
  • src/xmlenc/decrypt.rs
  • src/xmlenc/encrypt.rs
  • src/xmlenc/mod.rs
  • src/xmlenc/parse.rs
  • src/xmlenc/types.rs
  • tests/base64_transform_integration.rs
  • tests/common/xmlsec1.rs
  • tests/donor_full_verification_suite.rs
  • tests/donor_interop_suite.rs
  • tests/donor_negative_vectors.rs
  • tests/ecdsa_signature_integration.rs
  • tests/fixtures/xmldsig/README.md
  • tests/fixtures/xmldsig/aleksey-xmldsig-01/enveloped-x509-digest-sha256.xml
  • tests/fixtures/xmldsig/external-data/xml-stylesheet-2005
  • tests/fixtures/xmldsig/external-data/xml-stylesheet-2005.b64
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/badb.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/balor.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/ca.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh-cert.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/macha.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/merlin.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/nemain.der
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloped-dsa.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-b64-dsa.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-b64-dsa.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-dsa.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-dsa.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1-80.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1-80.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-rsa.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-b64-dsa.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-b64-dsa.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-dsa.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-dsa.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-keyname.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-keyname.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-retrievalmethod-rawx509crt.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-retrievalmethod-rawx509crt.xml
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-crt-crl.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-crt.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-is.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-ski.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-sn.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature.tmpl
  • tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature.xml
  • tests/fixtures/xmlenc/README.md
  • tests/fixtures_smoke.rs
  • tests/install_xmlsec1.rs
  • tests/merlin_interop.rs
  • tests/signature_builder.rs
  • tests/signing_digest.rs
  • tests/uri_integration.rs
  • tests/x509_chain_integration.rs
  • tests/xmlenc_encrypt_integration.rs
  • tests/xmlenc_encrypt_xmlsec1.rs
  • tests/xmlsec1_interop.rs
  • tests/xpath_transform_integration.rs

Comment thread Cargo.toml
Comment thread docs/xmldsig.md
Comment thread docs/xmlenc.md
Comment thread scripts/import-donor-fixtures.sh Outdated
Comment thread src/policy.rs Outdated
Comment thread src/xmldsig/signature.rs
Comment thread tests/merlin_interop.rs Outdated
Comment thread tests/signing_digest.rs
Comment thread tests/xmlsec1_interop.rs
- enforce typed legacy and key-strength policy across verification paths
- unify hard limits, X.509 EKU semantics, and CBC failure contracts
- harden donor imports, migration docs, and RSA private operations

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30d57809f5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/provider.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: 2

🤖 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/provider.rs`:
- Around line 657-666: Add dsa_keys: DsaKeyPolicy to X509ChainOptions,
initialize and propagate it through issuer-policy validation and the X.509 DSA
verification path. In the DSA provider flow around
verify_dsa_signature_spki_with_minimum, replace the hard-coded 1024-bit minimum
with the configured dsa_keys.minimum_modulus_bits and preserve
PolicyViolation::KeySize instead of converting it to false.

In `@tests/import_donor_fixtures.rs`:
- Around line 332-340: Update the conflicting-donor import test around the
existing failure assertion to verify the target directory’s complete contents
after the failed import, not just sentinel.xml. Assert that only the
pre-existing sentinel file remains and no files copied from the conflicting
donors are present, while preserving the existing sentinel-content check.
🪄 Autofix

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: 2f83fcfe-19fe-4224-b65b-cb10cdffabaa

📥 Commits

Reviewing files that changed from the base of the PR and between c255360 and 30d5780.

📒 Files selected for processing (30)
  • CHANGELOG.md
  • Cargo.toml
  • docs/xmldsig.md
  • docs/xmlenc.md
  • scripts/import-donor-fixtures.sh
  • src/hard_limits.rs
  • src/policy.rs
  • src/provider.rs
  • src/xmldsig/builder.rs
  • src/xmldsig/keys.rs
  • src/xmldsig/mutation.rs
  • src/xmldsig/parse.rs
  • src/xmldsig/signature.rs
  • src/xmldsig/transforms.rs
  • src/xmldsig/verify.rs
  • src/xmldsig/x509.rs
  • src/xmlenc/decrypt.rs
  • src/xmlenc/encrypt.rs
  • src/xmlenc/parse.rs
  • tests/common/xmlsec1.rs
  • tests/donor_full_verification_suite.rs
  • tests/donor_negative_vectors.rs
  • tests/fixtures/xmldsig/README.md
  • tests/import_donor_fixtures.rs
  • tests/merlin_interop.rs
  • tests/rsa_signature_integration.rs
  • tests/signing_digest.rs
  • tests/x509_chain_integration.rs
  • tests/xmlenc_encrypt_xmlsec1.rs
  • tests/xmlsec1_interop.rs

Comment thread src/provider.rs Outdated
Comment thread tests/import_donor_fixtures.rs
- accept unrestricted parameterless RFC 4055 PSS keys
- apply typed DSA policy before provider dispatch
- verify complete importer rollback inventory
@polaz

polaz commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0385689923

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/xmldsig/verify.rs
Comment thread fuzz/corpus/xmldsig_verify/signature.xml Outdated
Comment thread src/provider.rs Outdated
- apply operation key policy to direct built-in keys
- verify X.509 DSA signatures at issuer q width
- seed fuzzing with a complete valid signature
@polaz

polaz commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: a20496623e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@polaz
polaz merged commit 4b31f57 into main Aug 13, 2026
10 checks passed
@polaz
polaz deleted the feat/#105-merlin-interop branch August 13, 2026 00:42
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): complete Merlin interoperability

1 participant