feat(xmldsig): complete Merlin interop - #108
Conversation
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
|
Too many files changed for review (107 files, 100 file limit). Bypass the limit by tagging |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (13)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe 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. ChangesXML security foundation
Interoperability and tooling
Documentation and support matrix
Estimated code review effort: 5 (Critical) | ~120 minutes Mergeability Score: ⚪ Minimal · up to 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
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
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 valueRemove the second synthetic parse;
is_xml_ncnamealready covers it.
is_xml_ncnameparses<{value}/>and confirms that the resulting tag name equalsvalue. 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 winDocument the breaking API changes and add
#[non_exhaustive]toSignatureAlgorithmandSignedInfo.
ParseErroris already#[non_exhaustive]. Document theSignatureAlgorithmrenames, new variants, andSignedInfo::hmac_output_length_bitsin 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
⛔ Files ignored due to path filters (10)
tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/badb.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/balor.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/bres.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/ca.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh-cert.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/macha.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/merlin.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/morigu.pemis excluded by!**/*.pemtests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/nemain.pemis excluded by!**/*.pem
📒 Files selected for processing (94)
.gitattributes.github/workflows/ci.yml.gitignoreCargo.tomlREADME.mddocs/xmldsig.mddocs/xmlenc.mdfuzz/Cargo.tomlfuzz/corpus/xmldsig_verify/signature.xmlfuzz/fuzz_targets/xmldsig_verify.rsscripts/import-donor-fixtures.shscripts/install-xmlsec1.shsrc/c14n/mod.rssrc/c14n/serialize.rssrc/c14n/xml_base.rssrc/hard_limits.rssrc/lib.rssrc/policy.rssrc/provider.rssrc/xml.rssrc/xmldsig/builder.rssrc/xmldsig/digest.rssrc/xmldsig/keys.rssrc/xmldsig/mod.rssrc/xmldsig/mutation.rssrc/xmldsig/parse.rssrc/xmldsig/sign.rssrc/xmldsig/signature.rssrc/xmldsig/transforms.rssrc/xmldsig/types.rssrc/xmldsig/uri.rssrc/xmldsig/verify.rssrc/xmldsig/x509.rssrc/xmldsig/xpath.rssrc/xmlenc/decrypt.rssrc/xmlenc/encrypt.rssrc/xmlenc/mod.rssrc/xmlenc/parse.rssrc/xmlenc/types.rstests/base64_transform_integration.rstests/common/xmlsec1.rstests/donor_full_verification_suite.rstests/donor_interop_suite.rstests/donor_negative_vectors.rstests/ecdsa_signature_integration.rstests/fixtures/xmldsig/README.mdtests/fixtures/xmldsig/aleksey-xmldsig-01/enveloped-x509-digest-sha256.xmltests/fixtures/xmldsig/external-data/xml-stylesheet-2005tests/fixtures/xmldsig/external-data/xml-stylesheet-2005.b64tests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/badb.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/balor.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/ca.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh-cert.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/lugh.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/macha.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/merlin.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/certs/nemain.dertests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloped-dsa.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-b64-dsa.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-b64-dsa.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-dsa.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-dsa.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1-80.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1-80.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-hmac-sha1.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-enveloping-rsa.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-b64-dsa.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-b64-dsa.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-dsa.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-external-dsa.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-keyname.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-keyname.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-retrievalmethod-rawx509crt.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-retrievalmethod-rawx509crt.xmltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-crt-crl.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-crt.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-is.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-ski.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature-x509-sn.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature.tmpltests/fixtures/xmldsig/merlin-xmldsig-twenty-three/signature.xmltests/fixtures/xmlenc/README.mdtests/fixtures_smoke.rstests/install_xmlsec1.rstests/merlin_interop.rstests/signature_builder.rstests/signing_digest.rstests/uri_integration.rstests/x509_chain_integration.rstests/xmlenc_encrypt_integration.rstests/xmlenc_encrypt_xmlsec1.rstests/xmlsec1_interop.rstests/xpath_transform_integration.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
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
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
📒 Files selected for processing (30)
CHANGELOG.mdCargo.tomldocs/xmldsig.mddocs/xmlenc.mdscripts/import-donor-fixtures.shsrc/hard_limits.rssrc/policy.rssrc/provider.rssrc/xmldsig/builder.rssrc/xmldsig/keys.rssrc/xmldsig/mutation.rssrc/xmldsig/parse.rssrc/xmldsig/signature.rssrc/xmldsig/transforms.rssrc/xmldsig/verify.rssrc/xmldsig/x509.rssrc/xmlenc/decrypt.rssrc/xmlenc/encrypt.rssrc/xmlenc/parse.rstests/common/xmlsec1.rstests/donor_full_verification_suite.rstests/donor_negative_vectors.rstests/fixtures/xmldsig/README.mdtests/import_donor_fixtures.rstests/merlin_interop.rstests/rsa_signature_integration.rstests/signing_digest.rstests/x509_chain_integration.rstests/xmlenc_encrypt_xmlsec1.rstests/xmlsec1_interop.rs
- accept unrestricted parameterless RFC 4055 PSS keys - apply typed DSA policy before provider dispatch - verify complete importer rollback inventory
|
@codex review |
There was a problem hiding this comment.
💡 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".
- 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
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Summary
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 XMLRetrievalMethodresolution, authenticated CRL handling, and bounded manifest referencesanyExtendedKeyUsagesemantics and fail-closed resolver/operation policy intersectioncAandkeyCertSignKeySizemetadata before integer parsingxml:baseplus dot-segment normalizationKeyValue, or X.509 key source while preserving backend interoperability capabilityKeySizevalues and non-SHA1 MGF configuration for legacyrsa-oaep-mgf1pbefore resolver or custom-provider dispatchX509Dataretrieval without a transform while requiring explicit XPath selection when the dereferenced root is a wrapperSignedInfoand authenticated Manifests, bound external XML reparsing, and cap canonicalizedSignedInfoplus retained pre-digest diagnostics across a signatureX509Digestcoverage and a bounded XMLDSig verification fuzz target seeded with a complete valid X.509 signaturesad-rsa, update cryptographic dependency requirements, and synchronize public documentationTesting
cargo buildcargo build --no-default-featurescargo build --all-featurescargo clippy --all-targets --all-features -- -D warningscargo nextest run --all-featurescargo test --doc --all-featurescargo +nightly fuzz run xmldsig_verify -- -runs=256 -max_len=65536Closes #105