feat: update JSignPdf to 3.1.0 with jsignpdf-php 3.0.0 - #8256
Merged
Conversation
Points the submodule at LibreSign/3rdparty#96, which bumps jsignpdf/jsignpdf-php from 1.3.1 to 3.0.0 for JSignPdf 3.1.0. The pointer will move to the merge commit once that pull request lands. Signed-off-by: André Maia <andrefnkmm@gmail.com> Assisted-by: Claude Code:claude-fable-5-1
JSignPdf 3.1 dropped the single JSignPdf.jar. The minimal package, meant for headless use, ships a lib/ directory that the wrapper starts through the classpath, so the configured path becomes the extracted directory, stored in the new jsignpdf_path key. The legacy jsignpdf_jar_path key is removed on install and on uninstall, and the archive is verified against the SHA256SUMS file published with the release instead of a hard-coded md5. The release metadata lives in JSignPdfRelease so it can be unit tested; SignSetupService and the setup check read the new key. Signed-off-by: André Maia <andrefnkmm@gmail.com> Assisted-by: Claude Code:claude-fable-5-1
…wrapper jsignpdf-php 3 escapes every argument itself and takes the options as a list, so the handler stops building shell syntax: the parameters are arrays, one cloned JSignParam per visible element, the signature text is passed as is instead of quoted, the JVM option and the JSIGNPDF_HOME variable go through their own setters, and the TSA password goes through setTsaPassword(), which the wrapper writes to the stdin of JSignPdf instead of the command line. The wrapper also renamed the jar path to a directory path and reports failures through the exit code. The tests assert the parameters that reach the wrapper, captured from setParam(), with structured providers, a case with shell special characters in the signature text and a TSA provider that checks the password never reaches the command line. Signed-off-by: André Maia <andrefnkmm@gmail.com> Assisted-by: Claude Code:claude-fable-5-1
…ertificate generateRootCert() resolves the CRL distribution point from the CA identifier. Without one the certificate generation failed and 68 tests of this class were skipped as "Certificate initialization failed". Signed-off-by: André Maia <andrefnkmm@gmail.com> Assisted-by: Claude Code:claude-fable-5-1
vitormattos
requested changes
Sep 5, 2026
vitormattos
left a comment
Member
There was a problem hiding this comment.
Excellent work!
I think that only have a small improvement and small changes to make psalm happy.
Member
|
@maia-andre this PR is blocking the CI because I already made the merge at 3rdparty. I'll need to go ahead with the small changes to merge this. After the merge, will be pending the backport flow. |
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Member
|
/backport to stable35 |
Member
|
/backport to stable34 |
Member
|
/backport to stable33 |
This was referenced Sep 5, 2026
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.
Resolves: #8068
📝 Summary
Updates the JSignPdf signing backend to JSignPdf 3.1.0 through jsignpdf-php 3.0.0 (LibreSign/3rdparty#96). JSignPdf 3.1.0 also uses SHA-256 as the default TSA hash, which is what #8145 is about.
Install. JSignPdf 3.1 dropped the single
JSignPdf.jar: theminimalpackage, meant for headless and command line use, ships alib/directory that the wrapper starts through the classpath.InstallServicenow downloadsjsignpdf-3.1.0-minimal.zip, verifies it against theSHA256SUMSfile published with the release (instead of a hard-coded md5), and stores the extracted directory in the newjsignpdf_pathapp config key. The legacyjsignpdf_jar_pathkey is deleted on install and on uninstall. The release metadata lives in the newJSignPdfReleaseclass so it can be unit tested.SignSetupServiceand the setup check read the new key.Handler. jsignpdf-php 3 escapes every argument itself and takes the options as a list, so
JSignPdfHandlerstops building shell syntax: the parameters are arrays (addJSignParameters(), one clonedJSignParamper visible element), the signature text is passed as is (no more quoting of"and$), the JVM option-Duser.homeand theJSIGNPDF_HOMEvariable go throughsetJavaOptions()/setEnvironmentVariables(), and the TSA password goes throughsetTsaPassword(), which the wrapper writes to the stdin of JSignPdf instead of the command line. The wrapper now reports failure through the exit code instead of the "Finished: Signature succesfully created." message; the error parsing incheckTsaError()/checkHashAlgorithmError()is unchanged.Tests.
JSignPdfHandlerTestasserts the parameters that reach the wrapper (captured fromsetParam()), with the sign cases as structured providers, a case with shell special characters in the signature text, and a TSA provider covering no TSA, URL only, policy OID, basic authentication with the password over stdin, shell characters in the password, and the two cases with incomplete credentials.JSignPdfReleaseTestcovers the download URL, checksum URL and install path.JSignPdfSetupCheckTestandSignSetupServiceTestfollow the new key; the setup check gained two cases for mutants that escaped.While doing this I found that 68 tests of
JSignPdfHandlerTestwere being skipped as "Certificate initialization failed":generateRootCert()needs a CA identifier to resolve the CRL distribution point and the class never generated one.setUpBeforeClass()now callsCaIdentifierService::generateCaId(), likeOpenSslHandlerTestdoes, and all 96 tests run.Existing installations. JSignPdf 2.3.0 cannot read passwords from stdin, so it does not work with the new wrapper: after upgrading,
occ libresign:install --jsignpdf(or the install button in the admin settings) has to run once. Until then the setup check reports "JSignPdf not found" with that command as the tip, becausejsignpdf_pathis empty. I kept this explicit instead of downloading 35 MB duringocc upgrade; say so if you prefer a repair step. The-a(append) default of the wrapper is a no-op in 3.x, where appending is the default, and LibreSign already rewrites the PDF header before signing, so the 3.x limitation that append mode cannot raise the PDF version for SHA-256 does not apply.🧪 How to test
occ libresign:install --use-local-cert --javaandocc libresign:install --use-local-cert --jsignpdf: the jsignpdf appdata folder getsjsignpdf-3.1.0/lib/*.jar,occ config:app:get libresign jsignpdf_pathpoints to it andjsignpdf_jar_pathis gone.occ libresign:configure:check(or the admin overview) reports JSignPdf version 3.1.0.pswhile signing, or the--enable-stdin-passwords -ksp - -tsp -in the command).composer run test:unit -- tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php: 96 tests, none skipped.⚙️ API / Back‑end changes
InstallService,SignSetupService,JSignPdfSetupCheck,JSignPdfHandler, newJSignPdfRelease; new app config keyjsignpdf_path(replacesjsignpdf_jar_path)composer openapi(no API change)🚧 Tasks
mainalso carries pdf-signature-validator 0.5.1.✅ Checklist
JSignPdfHandlerTest107/107 (68 of them used to be skipped),JSignPdfReleaseTest6/6,JSignPdfSetupCheckTest11/11,SignSetupServiceTest23/23; whole unit suite 3600 tests, the only 4 failures are inAEngineHandlerTestand pass when the class runs alone (state leaking between classes, unrelated to this change).main(--git-diff-lines): 68 mutants, 68 killed, 100% coverage and 100% MSI. Per class:JSignPdfRelease32/32,JSignPdfSetupCheck33/33.InstallServicehas no unit coverage, as before; the install path is exercised by the behat and Playwright jobs (libresign:install --jsignpdf) and by the manual run below.occ libresign:install --use-local-cert --jsignpdfdownloadedjsignpdf-3.1.0-minimal.zip, verified it and setjsignpdf_pathto.../x86_64/jsignpdf/jsignpdf-3.1.0(76 jars inlib/, legacy key gone);java -classpath 'lib/*' com.intoolswetrust.jsignpdf.Bootstrap --versionprintsJSignPdf version 3.1.0; a signature request signed with clickToSign returned 200 and the validation endpoint reports the signature asadbe.pkcs7.detached, RSA-SHA256, valid.🤖 AI
Assisted by Claude Code (claude-fable-5-1); I reviewed and tested every change.
JSignPdf 3.x features worth a look (not implemented here)
--list-engines,-eng): OpenPDF stays the default; the new EU DSS engine produces PAdES signatures at the ETSI baseline levels B, T, LT and LTA, which OpenPDF cannot create.--enable-stdin-passwords): used by this pull request through the wrapper.--overwritereplaces existing signatures instead of appending. LibreSign relies on appending, so nothing to do, but it is the switch to stay away from.--tsa-hash-algorithmdefaults toAppConfig.defaultTsaHashAlg()= SHA-256, which fixes the SHA-1 failure of TSA timestamping always fails with JSignPdf: --tsa-hash-algorithm is never passed, SHA-1 is used #8145; a configurable TSA hash in the TSA policy stays as the follow-up discussed there.--sig-field,--list-sig-fields), the feature the issue points at for pre-placed signature boxes; adebugoutput logging the certificate chain and every AIA/CRL/OCSP request, useful for TSA diagnostics;buffering.mode=tempto sign very large PDFs without a bigger heap.SHA256SUMS.txt): used by the installer here.