Skip to content

Match DSS token id format so untrusted-chain reports survive leading zero bytes - #466

Merged
kwart merged 1 commit into
masterfrom
fix/dss-token-id-leading-zero
Jul 25, 2026
Merged

Match DSS token id format so untrusted-chain reports survive leading zero bytes#466
kwart merged 1 commit into
masterfrom
fix/dss-token-id-leading-zero

Conversation

@kwart

@kwart kwart commented Jul 25, 2026

Copy link
Copy Markdown
Member

Problem

The snapshot deployment for 0ae3d85 failed:

[ERROR] DssSigningEngineTest.untrustedSignerChainReportsCertificateIdentity:356 must name the signer-chain role
[ERROR] Failed to execute goal ...maven-surefire-plugin:3.5.6:test on project jsignpdf-engine-dss

The reactor stopped at jsignpdf-engine-dss, so nothing was published. The run before it, and the run after, both passed on the same code — this is a 1-in-256 flake with a real bug behind it.

Root cause

The alert DSS raised in that run carried this token id:

C-D20ED85E0CE554EFBAE9621F08DC2824FD721334F18BA85C12F7496B999DEA

That is 62 hex characters, not 64. Identifier.asXmlId() is "C-" + Digest.getHexValue(), and getHexValue() is:

new BigInteger(1, value).toString(16)   // leading zeros strippedprepend "0" if odd lengthtoUpperCase(ENGLISH)

Leading zero bytes are dropped outright; the odd-length pad only restores a leading zero nibble. So a certificate whose DER SHA-256 begins with 0x00 gets a 62-character id — probability 1/256, and EmbeddedCa generates fresh key pairs on every run.

Both sides of the issue #448 enrichment assumed a fixed 64:

  • DssUntrustedChainReporter.TOKEN_ID was C-[0-9A-Fa-f]{64}, which did not match the shorter id, so collectTokenIds() came back empty and describe() returned "".
  • CertificateInfo.tokenId() zero-padded through HexFormat, so even a matched id would have missed in the signer / timestamp chain lookup.

This is not test-only. For roughly one certificate in 256 the enrichment silently degraded back to the bare C-<fingerprint> message it was written to replace, and the id= field in the FINE certificate log did not cross-reference DSS's own output.

Fix

  • CertificateInfo.tokenId() now replicates Digest#getHexValue() exactly.
  • TOKEN_ID accepts {2,64} hex characters.

Tests

Both new tests mine a certificate whose DER SHA-256 starts with 0x00 — cheaply, by reusing one key pair and varying only the serial number (~2s), turning the flake into a deterministic check:

  • CertificateInfoTest.tokenIdDropsLeadingZeroBytesLikeDss
  • DssUntrustedChainReporterTest.namesCertificateWhoseTokenIdHasALeadingZeroByte — end-to-end through describe(), with DSS's own CertificateToken.getDSSIdAsString() as the authoritative id

tokenIdIsDssCertificateTokenId had the old zero-padded form baked into its expected value and was updated.

Verified as real guards: with the two main-source changes reverted and the tests kept, both fail — the second with the exact CI symptom (must name the signer role). With the fix, the full mvn test reactor is green.

No release-note entry: #448 and #452 are both unreleased in 3.2.0, so this corrects unshipped work.

🤖 Generated with Claude Code

…zero bytes

DSS renders a certificate token id through BigInteger (Digest#getHexValue),
which drops leading zero bytes and pads back only an odd nibble count. A
certificate whose DER SHA-256 starts with 0x00 is therefore reported as a
62-character id, not the usual 64.

Both sides of the issue #448 enrichment assumed a fixed 64:

- DssUntrustedChainReporter's TOKEN_ID pattern did not match the shorter id,
  so no token id was collected and describe() returned an empty block.
- CertificateInfo.tokenId() zero-padded via HexFormat, so even a matched id
  would not have been found in the signer / timestamp chain index.

For roughly one certificate in 256 the enrichment silently degraded to the
bare C-<fingerprint> message it was written to replace, and the id= field of
the FINE certificate log did not cross-reference DSS's own output.

Both regression tests mine a certificate with a leading zero digest byte by
reusing one key pair and varying only the serial number, which turns a 1/256
CI flake (it broke the snapshot deployment of 0ae3d85) into a deterministic
check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kwart
kwart merged commit 890375e into master Jul 25, 2026
1 check passed
@kwart
kwart deleted the fix/dss-token-id-leading-zero branch July 25, 2026 14:16
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.

1 participant