Don't refuse to sign when append mode can't bump the declared PDF version - #467
Merged
Conversation
…sion
Signing a PDF whose declared version is older than the one nominally
associated with the chosen hash algorithm (e.g. SHA-256 on a PDF-1.3
document) aborted in append mode, because OpenPDF cannot rewrite the
header version of an incremental update.
The declared version has no bearing on the signature: the digest lives
inside the CMS blob, no /DigestMethod entry is written for
adbe.pkcs7.detached, and validators accept SHA-256 regardless of the
declared version. The DSS engine has never had an equivalent check, so
the same input signed fine there and failed here. Log a warning and
carry on instead of aborting.
Also fixes two defects in the same block:
- console.updateVersion was "... 1.{0} -> 1.{1}" while the caller
already passed full version strings, rendering "1 1.3 -> 11.6". A
leftover from OpenPDF 1.x, where getPdfVersion() returned a bare
digit. Corrected in all locales; arguments now pass version names so
both messages read alike.
- PdfVersion.fromStringVersion() returns null outside 1.2-1.7, so a
PDF-1.0 or PDF-1.1 input hit an NPE on getVersionName() - exactly the
documents this branch targets. Falls back to the raw version string.
console.updateVersionNotPossibleInAppendModeForGivenHash is replaced by
console.appendModeVersionNotUpdated; the old text told users to disable
append mode or pick another algorithm, which is no longer the remedy.
Removed from all locales so no translation keeps showing the old
wording, along with some stale commented-out copies of a related key.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Signing a PDF whose declared version is older than the one nominally associated with the chosen hash algorithm — e.g. SHA-256 on a PDF-1.3 document, which is what
demo/service-agreement.pdfis — aborted the run in append mode:Why the gate goes
The
SHA-1 → 1.3, SHA-256 → 1.6, SHA-384/SHA-512/RIPEMD160 → 1.7table is a correct citation of Adobe's Digital Signatures in a PDF and the/DigestMethodnotes in ISO 32000-1, but it doesn't justify refusing to sign:/DigestMethodentry, which is only meaningful foradbe.x509.rsa_sha1. JSignPdf writesadbe.pkcs7.detached, so no version-tagged dictionary entry is emitted at all.DssSigningEnginehas no equivalent, so the same document signed fine through DSS and hard-failed through OpenPDF.The failure it prevented was cosmetic; the failure it caused was total. Now it logs a
WARNINGand signs.Not changed: writing a catalog
/Versionoverride to keep the declaration honest. It's feasible (PdfStamper.markUsedis public), but DSS'sPdfObjectModificationsFilter.isVersionChangewhitelists/Versiononly when the action type isMODIFICATION. Adding the key to a document that lacks one is aCREATION, which falls through to "undefined changes" — and that's precisely the case where we'd want to write it. Not worth risking how a pre-existing signature gets classified for a version number no validator consults.Two defects fixed in the same block
console.updateVersionrendered garbage. The message wasUpdating PDF version info 1.{0} -> 1.{1}while the caller already passed full version strings, producing "Updating PDF version info 11.3 -> 11.6". A leftover from OpenPDF 1.x, wheregetPdfVersion()returned a bare digit. Corrected in all 19 locales; the arguments now pass version names so both messages read alike.PdfVersion.fromStringVersion()returnsnulloutside 1.2–1.7, so.getVersionName()threw — on exactly the old documents this branch targets. Now falls back to the raw version string.Messages
console.updateVersionNotPossibleInAppendModeForGivenHashis replaced byconsole.appendModeVersionNotUpdated; the old text told users to disable append mode or pick another algorithm, which is no longer the remedy. The obsolete key is removed from all locales so no translation keeps showing the old "impossible" wording, along with some stale commented-out copies of a related key.Verification
Append mode, SHA-256, on the PDF-1.3 demo document — previously a hard failure:
pdfsigon that output confirms the premise:A SHA-256 signature in a document still declaring PDF-1.3 validates fine. (
Certificate issuer is unknownis just the self-signed demo cert.)Non-append (
--overwrite) path: logsUpdating PDF version info PDF-1.3 -> PDF-1.6and the output header really is%PDF-1.6.mvn testonengines/api+engines/openpdf: 23 tests, 0 failures.🤖 Generated with Claude Code