Skip to content

Normalize RSA signature to modulus width to prevent short XMLDSig SignatureValue#10

Merged
scribetw merged 1 commit intomasterfrom
copilot/summary-issue-9-defensive-programming
Mar 30, 2026
Merged

Normalize RSA signature to modulus width to prevent short XMLDSig SignatureValue#10
scribetw merged 1 commit intomasterfrom
copilot/summary-issue-9-defensive-programming

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 28, 2026

ninja can serialize RSA signatures without left-padding the result BigInt to modulus width, silently dropping leading 0x00 bytes. For a 2048-bit key this produces 255 bytes (340 Base64 chars) instead of the required 256 bytes (344 Base64 chars), causing intermittent verification failures downstream with no clear error.

Changes

  • lib/src/utils.dart — New normalizeRsaSignatureBase64(String base64Sig, BigInt modulus) helper:

    • Left-pads decoded signature bytes with 0x00 to ceil(modulus.bitLength / 8) when short
    • Returns unchanged if already the correct width
    • Throws StateError if longer than the modulus width (indicates a serious upstream bug)
  • lib/src/signed_xml.dart — Applied normalization in RSASHA1, RSASHA256, and RSASHA512 getSignature using the private key's .n (modulus):

    final rsa = RSAPrivateKey.fromPEM(utf8.decode(signingKey));
    final raw = rsa.signSsaPkcs1v15ToBase64(utf8.encode(xml), hasher: EmsaHasher.sha1);
    final res = normalizeRsaSignatureBase64(raw, rsa.n); // ← guards against ninja bug
  • test/utils_test.dart — Unit tests for normalizeRsaSignatureBase64: correct-length passthrough, one- and two-byte-short padding (the ninja bug scenario), oversized throws StateError, and 1024-bit key variant.

…ureValue in XMLDSig

Agent-Logs-Url: https://github.com/rikulo/xml-crypto/sessions/822e4c7c-2b12-4ac6-a99f-3ff2255791e0

Co-authored-by: scribetw <6398934+scribetw@users.noreply.github.com>
@scribetw scribetw marked this pull request as ready for review March 28, 2026 15:20
Copilot AI review requested due to automatic review settings March 28, 2026 15:20
Copy link
Copy Markdown

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

This PR prevents intermittent XMLDSig verification failures by ensuring RSA SignatureValue is always encoded at the full modulus width (left-padding with 0x00 when the signing library emits a shorter BigInt-derived byte sequence).

Changes:

  • Added normalizeRsaSignatureBase64(base64Sig, modulus) to left-pad decoded RSA signature bytes to ceil(modulus.bitLength / 8) and throw if oversized.
  • Applied normalization to RSA-SHA1 / RSA-SHA256 / RSA-SHA512 signing paths using the private key modulus (rsa.n).
  • Added unit tests covering passthrough, 1–2 byte short padding, oversized throw, and a 1024-bit modulus case.

Reviewed changes

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

File Description
lib/src/utils.dart Adds signature normalization helper (pad/validate to modulus byte width).
lib/src/signed_xml.dart Normalizes RSA signature output for SHA1/SHA256/SHA512 signing.
test/utils_test.dart Adds focused unit tests for normalization behavior and edge cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@scribetw scribetw merged commit ac86d3d into master Mar 30, 2026
6 checks passed
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.

3 participants