intoolswetrust / jsignpdf

PDF signing software written in Java. It supports visible signatures, timestamping, certificate verification and many other cool features
https://intoolswetrust.github.io/jsignpdf/
Other
308 stars 118 forks source link

PAdES B-LTA level support #46

Open JohnPlanetary opened 2 years ago

JohnPlanetary commented 2 years ago

It would be nice for JSignPDF to sign PDF files to conform to ETSI EN 319 142-1 V1.1.0 (2016-02) (PAdES digital signatures) ( https://www.etsi.org/deliver/etsi_en/319100_319199/31914201/01.01.00_30/en_31914201v010100v.pdf ) B-LTA level.

6 6.1. Signature levels d) B-LTA level provides requirements for the incorporation of electronic time-stamps that allow validation of the signature long time after its generation. This level aims to tackle the long term availability and integrity of the validation material.

kwart commented 2 years ago

Could you prepare a pull request with such a feature? This OpenPDF issue could be related: LibrePDF/OpenPDF#86

JohnPlanetary commented 2 years ago

I'm not a programmer, just a user. I did leave feedback on that issue topic, to bring attention again to it.

I did see here: https://github.com/LibrePDF/OpenPDF/releases/tag/openpdf-1.2.1 that seems to imply OpenPDF is able to produce PAdES Baseline Profiles B/T/LT/LTA with OpenPDF.

kwart commented 1 year ago

I've created a new repository for trying PAdES: https://github.com/intoolswetrust/jsignpdf-pades It doesn't have GUI, just the simple batch mode. It doesn't support visible signatures (yet). Could you give it a try? The snapshots are available in https://s01.oss.sonatype.org/content/repositories/snapshots/com/github/kwart/jsign/jsignpdf-pades-distribution/

JohnPlanetary commented 1 year ago

Hello @kwart ! First, let me thank you for trying to get these working!

I never used the batch mode. I've try to use it, but I'm not getting it to the B-LTA level, just to B-B level, but it doesn't try to get the CRL for the certificate so it will not even get LTV level for the digital signature. I wasn't able to get any sort of secure timestamp.

Can you provide me the proper command line, because I'm pretty sure it should be something wrong I'm doing, but because there wasn't any example on the help file on how to get timestamped in batch mode I did my best to try to find out.

Also to get PAdES B-LTA with LTV enabled it should try to get the CRL/ OCSP values for all certificates in the signature and timestamp chain, and also add an additional timestamp only (also with the CRL/ OCSP values included for LTV enabled) after applying the first digital certificate with the timestamp included.

I'm using Windows 10 Home OS. For the java I'm using: "Eclipse Temurin™" for Operating system: Windows; Architecture: x64; Package Type: JRE; Version: 19 (available here. https://adoptium.net/temurin/releases/?version=19 ) These version works just fine with the 2.2.0 version of JSignPDF GUI.

I've try: java -jar jsignpdf-pades.jar -tsh SHA512 -kst WINDOWS-MY C:\Users\Me\Desktop\mydocument.pdf -ha SHA512 -ts http://timestamp.digicert.com -crl -ocsp

but I get the error:

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -tsh SHA512 -kst WINDOWS-MY C:\Users\Me\Desktop\mydocument.pdf -ha SHA512 -ts http://timestamp.digicert.com -crl -ocsp
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file -tsh
SEVERE Error occured
eu.europa.esig.dss.model.DSSException: Unable to create FileDocument for File with name '-tsh'
        at eu.europa.esig.dss.model.FileDocument.<init>(FileDocument.java:66)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:146)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:78)

I also try: java -jar jsignpdf-pades.jar -ts http://timestamp.digicert.com -tsh SHA256 -kst WINDOWS-MY -ha SHA256 C:\Users\Me\Desktop\mydocument.pdf -crl -ocsp

It will give the error:

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -ts http://timestamp.digicert.com -tsh SHA256 -kst WINDOWS-MY -ha SHA256 C:\Users\Me\Desktop\mydocument.pdf -crl -ocsp
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file -ts
SEVERE Error occured
eu.europa.esig.dss.model.DSSException: Unable to create FileDocument for File with name '-ts'
        at eu.europa.esig.dss.model.FileDocument.<init>(FileDocument.java:66)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:146)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:78)
Mato-Z commented 1 year ago

@kwart Great work! Many many thanks I finally found a promising solution for signing according to AdES (DSS/eIDAS) with QESig (PKCS#11 private key on smartcard) that works on Linux. I tested your latest snapshot for PAdES on Ubuntu 22.04 and my results are: ./jsignpdf-pades.sh -da SHA256 -p11 pkcs11.cfg -kst PKCS11 -pl BASELINE_B document.pdf Looks OK. Validation with ETSI validator https://ec.europa.eu/digital-building-blocks/DSS/webapp-demo/validation without any problems. //EDIT: On the second attempt, the signature with the BASELINE-T format was already successful.

And signature with the BASELINE-T format the same errors like @JohnPlanetary

./jsignpdf-pades.sh -da SHA256 -p11 pkcs11.cfg -kst PKCS11 -ts MY_qualified_TSA -pl BASELINE_LT document.pdf
FINE PKCS11 provider registered with name SunPKCS11-JSignPdf
FINE PKCS11 provider registered with name JSignPKCS11-JSignPdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file testPodpis1.pdf
FINE Signature valid: true
FINE Removing security provider with name SunPKCS11-JSignPdf
FINE Removing security provider with name JSignPKCS11-JSignPdf
SEVERE Error occured
eu.europa.esig.dss.alert.exception.AlertException: Revocation data is missing for one or more certificate(s). [C-B9...: Revocation data is skipped for untrusted certificate chain!; C-27...: Revocation data is skipped for untrusted certificate chain!]
    at eu.europa.esig.dss.alert.handler.ThrowAlertExceptionHandler.process(ThrowAlertExceptionHandler.java:41)
    at eu.europa.esig.dss.alert.AbstractAlert.alert(AbstractAlert.java:52)
    at eu.europa.esig.dss.validation.SignatureValidationContext.checkAllRequiredRevocationDataPresent(SignatureValidationContext.java:922)
    at eu.europa.esig.dss.validation.SignedDocumentValidator.assertSignaturesValid(SignedDocumentValidator.java:560)
    at eu.europa.esig.dss.validation.SignedDocumentValidator.getValidationData(SignedDocumentValidator.java:525)
    at eu.europa.esig.dss.pades.validation.PDFDocumentValidator.getValidationData(PDFDocumentValidator.java:341)
    at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLT.extendSignatures(PAdESLevelBaselineLT.java:70)
    at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:82)
    at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:50)
    at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:222)
    at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:162)
    at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:78) 

Certificate is issued by a national authority (EU country) registered on the EUTL list... Thanks.

JohnPlanetary commented 1 year ago

I tried in Windows 10 x64 Home, and I was able to make the test PDF into: PAdES. B-T and PAdES: B-B, but not to PAdES: B-LT and also not: PAdES: B-LTA

I'm getting the following errors:

java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -ts http://timestamp.digicert.com -pl BASELINE_LT C:\Users\Me\Desktop\teste.pdf

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -ts http://timestamp.digicert.com -pl BASELINE_LT C:\Users\Me\Desktop\teste.pdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file C:\Users\Me\Desktop\teste.pdf
FINE Signature valid: true
SEVERE Error occured
eu.europa.esig.dss.alert.exception.AlertException: Revocation data is missing for one or more certificate(s). [C-281734D4592D1291D27190709CB510B07E22C405D5E0D6119B70E73589F98ACF: Revocation data is skipped for untrusted certificate chain!; C-33846B545A49C9BE4903C60E01713C1BD4E4EF31EA65CD95D69E62794F30B941: Revocation data is skipped for untrusted certificate chain!; C-C7F4E1BE32288920ABE2263ABE1AC4FC4FE6781C2D64D04C807557A023B5B6FA: Revocation data is skipped for untrusted certificate chain!; C-6F4B5D5136A66929620F6A0A952A09459037A0161202FBF6B5D40F3759B31474: Revocation data is skipped for untrusted certificate chain!]
        at eu.europa.esig.dss.alert.handler.ThrowAlertExceptionHandler.process(ThrowAlertExceptionHandler.java:41)
        at eu.europa.esig.dss.alert.AbstractAlert.alert(AbstractAlert.java:52)
        at eu.europa.esig.dss.validation.SignatureValidationContext.checkAllRequiredRevocationDataPresent(SignatureValidationContext.java:922)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.assertSignaturesValid(SignedDocumentValidator.java:560)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.getValidationData(SignedDocumentValidator.java:525)
        at eu.europa.esig.dss.pades.validation.PDFDocumentValidator.getValidationData(PDFDocumentValidator.java:341)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLT.extendSignatures(PAdESLevelBaselineLT.java:70)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:82)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:50)
        at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:222)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:162)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:78)

java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -ts http://timestamp.digicert.com -pl BASELINE_LTA C:\Users\Me\Desktop\teste.pdf

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -ts http://timestamp.digicert.com -pl BASELINE_LTA C:\Users\Me\Desktop\teste.pdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file C:\Users\Me\Desktop\teste.pdf
FINE Signature valid: true
SEVERE Error occured
eu.europa.esig.dss.alert.exception.AlertException: Revocation data is missing for one or more certificate(s). [C-281734D4592D1291D27190709CB510B07E22C405D5E0D6119B70E73589F98ACF: Revocation data is skipped for untrusted certificate chain!; C-33846B545A49C9BE4903C60E01713C1BD4E4EF31EA65CD95D69E62794F30B941: Revocation data is skipped for untrusted certificate chain!; C-C7F4E1BE32288920ABE2263ABE1AC4FC4FE6781C2D64D04C807557A023B5B6FA: Revocation data is skipped for untrusted certificate chain!; C-6F4B5D5136A66929620F6A0A952A09459037A0161202FBF6B5D40F3759B31474: Revocation data is skipped for untrusted certificate chain!]
        at eu.europa.esig.dss.alert.handler.ThrowAlertExceptionHandler.process(ThrowAlertExceptionHandler.java:41)
        at eu.europa.esig.dss.alert.AbstractAlert.alert(AbstractAlert.java:52)
        at eu.europa.esig.dss.validation.SignatureValidationContext.checkAllRequiredRevocationDataPresent(SignatureValidationContext.java:922)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.assertSignaturesValid(SignedDocumentValidator.java:560)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.getValidationData(SignedDocumentValidator.java:525)
        at eu.europa.esig.dss.pades.validation.PDFDocumentValidator.getValidationData(PDFDocumentValidator.java:341)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLT.extendSignatures(PAdESLevelBaselineLT.java:70)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:82)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLTA.extendSignatures(PAdESLevelBaselineLTA.java:50)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLTA.extendSignatures(PAdESLevelBaselineLTA.java:34)
        at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:222)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:162)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:78)

Not sure what is going on. I'm using my own ECC curve (just ECC P521 root and user certificate ECC P521 bellow it, with online CRL file and CRT reference for the programs to be able to get the root certificate), the stable version 2.2.0 is working just fine with them.

Mato-Z commented 1 year ago

On the second attempt, the signature with the BASELINE-T format was already successful. I am sorry.

./jsignpdf-pades.sh -da SHA256 -p11 pkcs11.cfg -kst PKCS11 -ts MY_qualified_TSA -pl BASELINE_T document.pdf
FINE PKCS11 provider registered with name SunPKCS11-JSignPdf
FINE PKCS11 provider registered with name JSignPKCS11-JSignPdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file testPodpis1.pdf
FINE Signature valid: true
FINE Removing security provider with name SunPKCS11-JSignPdf
FINE Removing security provider with name JSignPKCS11-JSignPdf

And signature with the BASELINE-T format the same errors like @JohnPlanetary

./jsignpdf-pades.sh -da SHA256 -p11 pkcs11.cfg -kst PKCS11 -ts MY_qualified_TSA -pl BASELINE_LT document.pdf
FINE PKCS11 provider registered with name SunPKCS11-JSignPdf
FINE PKCS11 provider registered with name JSignPKCS11-JSignPdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file testPodpis1.pdf
FINE Signature valid: true
FINE Removing security provider with name SunPKCS11-JSignPdf
FINE Removing security provider with name JSignPKCS11-JSignPdf
SEVERE Error occured
eu.europa.esig.dss.alert.exception.AlertException: Revocation data is missing for one or more certificate(s). [C-B9...: Revocation data is skipped for untrusted certificate chain!; C-27...: Revocation data is skipped for untrusted certificate chain!]
    at eu.europa.esig.dss.alert.handler.ThrowAlertExceptionHandler.process(ThrowAlertExceptionHandler.java:41)
    at eu.europa.esig.dss.alert.AbstractAlert.alert(AbstractAlert.java:52)
    at eu.europa.esig.dss.validation.SignatureValidationContext.checkAllRequiredRevocationDataPresent(SignatureValidationContext.java:922)
    at eu.europa.esig.dss.validation.SignedDocumentValidator.assertSignaturesValid(SignedDocumentValidator.java:560)
    at eu.europa.esig.dss.validation.SignedDocumentValidator.getValidationData(SignedDocumentValidator.java:525)
    at eu.europa.esig.dss.pades.validation.PDFDocumentValidator.getValidationData(PDFDocumentValidator.java:341)
    at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLT.extendSignatures(PAdESLevelBaselineLT.java:70)
    at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:82)
    at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:50)
    at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:222)
    at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:162)
    at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:78) 

Certificate is issued by a national authority (EU country) registered on the EUTL list... Thanks.

kwart commented 1 year ago

Thanks, guys, for sharing all the information. I'm looking into the missing revocation data issue now.

kwart commented 1 year ago

I've added some new config parameters.

  Options:
    --digest-algorithm, -da
      Digest algorithm used in the signature
      Default: SHA256
      Possible Values: [SHA1, SHA224, SHA256, SHA384, SHA512, SHA3_224, SHA3_256, SHA3_384, SHA3_512, SHAKE128, SHAKE256, SHAKE256_512, RIPEMD160, MD2, MD5, WHIRLPOOL]
    --disable-critical-extensions-check
      Don't check if all certificate critical extensions are known
      Default: false
    --disable-key-usage-check
      Don't check certificate key-usage field in the keystore
      Default: false
    --disable-validity-check
      Don't check certificate validity in the keystore
      Default: false
    --help, -h
      Prints this help
    --key-alias, -ka
      Key alias to be used for signing
    --key-password, -kp
      Key password
    --keystore-file, -ksf
      Keystore file to be used
    --keystore-password, -ksp
      KeyStore password
    --keystore-type, -kst
      Keystore type to be loaded
    --list-keys, -lk
      Command listing signing key aliases in the specified keystore
      Default: false
    --list-keystore-types, -lkt
      Command listing available keystore types
      Default: false
    --out-directory, -d
      Directory to write the signed PDFs to. If not provided, the source 
      directory of input PDF file is used.
    --out-suffix, -os
      Signed file suffix to be attached to the original name
      Default: _signed
    --pades-level, -pl
      PAdES level
      Default: BASELINE_B
      Possible Values: [BASELINE_B, BASELINE_T, BASELINE_LT, BASELINE_LTA]
    --pkcs11-config, -p11
      Config file for SunPKCS11 and JSignPKCS11 providers
    --trust-certificate-file
      File path to a trusted X.509 certificate
      Default: []
    --trust-certificate-url
      URL to a trusted X.509 certificate
      Default: []
    --trust-keystore-file
      File path to a truststore
    --trust-keystore-password
      Truststore password
    --trust-keystore-type
      Truststore type
      Default: pkcs12
    --trust-lotl-url
      URL to a List Of Trusted Lists
      Default: []
    --trust-use-default-lotl
      Use default List Of Trusted Lists (EU)
      Default: false
    --tsa-key-file, -tskf
      KeyStore file for TSA client-certificate authentication
    --tsa-key-file-type, -tskt
      KeyStore type for TSA client-certificate authentication
    --tsa-key-password, -tskp
      KeyStore password for TSA client-certificate authentication
    --tsa-password, -tsp
      Password for TSA Basic authentication
    --tsa-policy-oid
      TSA policy OID
    --tsa-server-url, -ts
      Timestamp server URL
    --tsa-user, -tsu
      Username for TSA Basic authentication
    -P11
      PKCS11 provider configuration parameter
      Syntax: -P11key=value
      Default: {}

You don't need to provide PKCS11 config file directly, but the properties can be specified on the command line too:

./jsignpdf-pades.sh -P11library=/usr/lib/libeToken.so -P11slot=0 -P11name=test -kst JSIGNPKCS11 -ksp 12345678 ...

I'm not able to test it today with a valid certificate. But I hope something like the following could work:

... -pl BASELINE_LTA -ts  https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem --trust-use-default-lotl  /home/kwart/test.pdf
JohnPlanetary commented 1 year ago

Thanks for the update @kwart !

I've tried again: java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -pl BASELINE_LTA -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem C:\sign\SignPDFs\mydocument.pdf

But I still get the same error:

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -pl BASELINE_LTA -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem C:\sign\SignPDFs\mydocument.pdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file C:\sign\SignPDFs\mydocument.pdf
FINE Signature valid: true
SEVERE Error occured
eu.europa.esig.dss.alert.exception.AlertException: Revocation data is missing for one or more certificate(s). [C-6F4B5D5136A66929620F6A0A952A09459037A0161202FBF6B5D40F3759B31474: Revocation data is skipped for untrusted certificate chain!]
        at eu.europa.esig.dss.alert.handler.ThrowAlertExceptionHandler.process(ThrowAlertExceptionHandler.java:41)
        at eu.europa.esig.dss.alert.AbstractAlert.alert(AbstractAlert.java:52)
        at eu.europa.esig.dss.validation.SignatureValidationContext.checkAllRequiredRevocationDataPresent(SignatureValidationContext.java:922)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.assertSignaturesValid(SignedDocumentValidator.java:560)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.getValidationData(SignedDocumentValidator.java:525)
        at eu.europa.esig.dss.pades.validation.PDFDocumentValidator.getValidationData(PDFDocumentValidator.java:341)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLT.extendSignatures(PAdESLevelBaselineLT.java:70)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:82)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLTA.extendSignatures(PAdESLevelBaselineLTA.java:50)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLTA.extendSignatures(PAdESLevelBaselineLTA.java:34)
        at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:222)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:166)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:80)

I even added FreeTSA.org certificates: https://freetsa.org/files/tsa.crt https://freetsa.org/files/cacert.pem

To the Eclipse Adoptium cert store, using the free & open source KeyStore Explorer (https://github.com/kaikramer/keystore-explorer) but nothing changed.

Where is JSignPDF-PADES checking the certificates to say the aren't trusted? Here they are both on the Windows Certificate Store, and on the Eclipse Adoptium cert store. I don't know where more to put them.

But eventually there should be some option to totally ignore the "untrusted" status, or to make them trusted immediately, because many Timestamp services around the world will never be trusted by default, even if they locally are totally legal or even mandatory.

kwart commented 1 year ago

IMO your problem is not with the trust of the TSA certificate but with the trust of the signing certificate. And there was also an issue in the code for LOTL handling.

The following command should work for the EU-trusted certs now:

jsignpdf-pades-0.1.0-SNAPSHOT/jsignpdf-pades.sh -P11library=/usr/lib/libeToken.so -P11slot=0 -P11name=test \
    -kst JSIGNPKCS11 -ksp 12345678 -pl BASELINE_LTA \
    -ts  https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem \
    --trust-use-default-lotl \
    /home/kwart/test.pdf

FINE PKCS11 provider registered with name SunPKCS11-test
FINE PKCS11 provider registered with name JSignPKCS11-test
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file /home/kwart/test.pdf
FINE Signature valid: true
FINE Removing security provider with name SunPKCS11-test
FINE Removing security provider with name JSignPKCS11-test
FINE Temporary PKCS11 config file was deleted.

or with the full LOTL URL specification:

jsignpdf-pades-0.1.0-SNAPSHOT/jsignpdf-pades.sh -P11library=/usr/lib/libeToken.so -P11slot=0 -P11name=test \
    -kst JSIGNPKCS11 -ksp 12345678 -pl BASELINE_LTA \
    -ts  https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem \
    --trust-lotl-url https://ec.europa.eu/tools/lotl/eu-lotl.xml \
    /home/kwart/test.pdf
JohnPlanetary commented 1 year ago

How can I force the Trust of the signing certificate? I have add it to both Windows Certificate Store and to Eclipse Adoptium certificates store. What else can I do?

kwart commented 1 year ago

You can provide a remote CA certificate URL:

jsignpdf-pades-0.1.0-SNAPSHOT/jsignpdf-pades.sh -P11library=/usr/lib/libeToken.so -P11slot=0 -P11name=test \
    -kst JSIGNPKCS11 -ksp 12345678 -pl BASELINE_LTA \
    -ts  https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem \
    --trust-certificate-url https://www.postsignum.cz/files/ca/postsignum_qca4_sub.pem \
    /home/kwart/test.pdf

or the local one:

wget https://www.postsignum.cz/files/ca/postsignum_qca4_sub.pem
jsignpdf-pades-0.1.0-SNAPSHOT/jsignpdf-pades.sh -P11library=/usr/lib/libeToken.so -P11slot=0 -P11name=test \
    -kst JSIGNPKCS11 -ksp 12345678 -pl BASELINE_LTA \
    -ts  https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem \
    --trust-certificate-file postsignum_qca4_sub.pem \
    /home/kwart/test.pdf
kwart commented 1 year ago

I though, the truststore option will work too, but it doesn't :thinking:

keytool -importcert -noprompt -alias ca -file postsignum_qca4_sub.pem -keystore keystore.p12 -storepass 123456 -storetype PKCS12
jsignpdf-pades-0.1.0-SNAPSHOT/jsignpdf-pades.sh -P11library=/usr/lib/libeToken.so -P11slot=0 -P11name=test \
    -kst JSIGNPKCS11 -ksp 12345678 -pl BASELINE_LTA \
    -ts  https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem \
    --trust-keystore-file keystore.p12 --trust-keystore-password 123456 --trust-keystore-type PKCS12 \
    /home/kwart/test.pdf
JohnPlanetary commented 1 year ago

Well, I've include the url for the CA Root Certificate, but I get the same error.

The CA certificate is at: http://myid.online.pt/myidrsarootg2.crt (PEM format) The CRL is at: http://myid.online.pt/myidrsarootg2.crl (DER format) I can create PAdES B-LTA documents in another program with my current configuration without any trouble, but not in these JSignPDF PAdES test version.

java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -pl BASELINE_LTA -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem --trust-certificate-url http://myid.online.pt/myidrsarootg2.crt C:\sign\SignPDFs\mydocument.pdf

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -pl BASELINE_LTA -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem --trust-certificate-url http://myid.online.pt/myidrsarootg2.crt C:\sign\SignPDFs\mydocument.pdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file C:\sign\SignPDFs\mydocument.pdf
FINE Signature valid: true
SEVERE Error occured
eu.europa.esig.dss.alert.exception.AlertException: Revocation data is missing for one or more certificate(s). [C-6F4B5D5136A66929620F6A0A952A09459037A0161202FBF6B5D40F3759B31474: Revocation data is skipped for untrusted certificate chain!]
        at eu.europa.esig.dss.alert.handler.ThrowAlertExceptionHandler.process(ThrowAlertExceptionHandler.java:41)
        at eu.europa.esig.dss.alert.AbstractAlert.alert(AbstractAlert.java:52)
        at eu.europa.esig.dss.validation.SignatureValidationContext.checkAllRequiredRevocationDataPresent(SignatureValidationContext.java:922)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.assertSignaturesValid(SignedDocumentValidator.java:560)
        at eu.europa.esig.dss.validation.SignedDocumentValidator.getValidationData(SignedDocumentValidator.java:525)
        at eu.europa.esig.dss.pades.validation.PDFDocumentValidator.getValidationData(PDFDocumentValidator.java:341)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLT.extendSignatures(PAdESLevelBaselineLT.java:70)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineT.extendSignatures(PAdESLevelBaselineT.java:82)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLTA.extendSignatures(PAdESLevelBaselineLTA.java:50)
        at eu.europa.esig.dss.pades.signature.PAdESLevelBaselineLTA.extendSignatures(PAdESLevelBaselineLTA.java:34)
        at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:222)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:166)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:80)

I also tried my National ID card (EU), but I get a (different) error:

java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -pl BASELINE_LTA -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem C:\sign\SignPDFs\mydocument.pdf

C:\Program Files\Eclipse Adoptium\jre-19.0.1.10-hotspot\bin>java -jar jsignpdf-pades.jar -da SHA256 -kst WINDOWS-MY -pl BASELINE_LTA -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem C:\sign\SignPDFs\mydocument.pdf
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
INFO Signing PDF file C:\sign\SignPDFs\mydocument.pdf
FINE Signature valid: true
SEVERE Error occured
eu.europa.esig.dss.model.DSSException: Unable to save a document. Reason : Can't write signature, not enough space; adjust it with SignatureOptions.setPreferredSignatureSize
        at eu.europa.esig.dss.pdf.pdfbox.PdfBoxSignatureService.saveDocumentIncrementally(PdfBoxSignatureService.java:422)
        at eu.europa.esig.dss.pdf.pdfbox.PdfBoxSignatureService.checkEncryptedAndSaveIncrementally(PdfBoxSignatureService.java:406)
        at eu.europa.esig.dss.pdf.pdfbox.PdfBoxSignatureService.signDocumentAndReturnDigest(PdfBoxSignatureService.java:230)
        at eu.europa.esig.dss.pdf.pdfbox.PdfBoxSignatureService.signDocument(PdfBoxSignatureService.java:166)
        at eu.europa.esig.dss.pdf.AbstractPDFSignatureService.sign(AbstractPDFSignatureService.java:294)
        at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:218)
        at com.github.intoolswetrust.jsignpdf.pades.Main.signFiles(Main.java:166)
        at com.github.intoolswetrust.jsignpdf.pades.Main.main(Main.java:80)
Caused by: java.io.IOException: Can't write signature, not enough space; adjust it with SignatureOptions.setPreferredSignatureSize
        at org.apache.pdfbox.pdfwriter.COSWriter.writeExternalSignature(COSWriter.java:845)
        at org.apache.pdfbox.pdfwriter.COSWriter.doWriteSignature(COSWriter.java:793)
        at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1199)
        at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:452)
        at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1435)
        at org.apache.pdfbox.pdmodel.PDDocument.saveIncremental(PDDocument.java:1412)
        at eu.europa.esig.dss.pdf.pdfbox.PdfBoxSignatureService.saveDocumentIncrementally(PdfBoxSignatureService.java:420)
        ... 7 more

I use the Windows Certificate store, to do the signing, but it goes to the chip in the card, and I get the proper request for the PIN, like in other applications. I think the CRL's of the national ID are many and big! It needs to allow a big file. They all have OCSP, but if they fail, or the program is not trying just OCSP, it will try to download the CRLs.

The current stable version of JSignPDF also gives me troubles with the National ID, I have to use " -Xmx2048m " to initiate the JSignPDF, but in these test version that trick is not working for me.

1) Root CA cert

2) Second CA Cert

http://ocsp.multicert.com/ocsp http://pkiroot.multicert.com/crl/root_mc_crl.crl

3) Certificate CA that signs the Final CA

http://trust.ecee.gov.pt/ecraiz.crt

http://ocsp.ecee.gov.pt

http://crls.ecee.gov.pt/crls/ARL.crl

4) Final CA that signs the certificate:

http://ocsp.root.cartaodecidadao.pt/publico/ocsp http://pki.cartaodecidadao.pt/publico/lrc/cc_ec_cidadao_crl004_crl.crl

5) On the certificate it self:

http://ocsp.asc.cartaodecidadao.pt/publico/ocsp

http://pki.cartaodecidadao.pt/publico/lrc/cc_sub-ec_cidadao_assinatura_crl0014_delta_p0004.crl

http://pki.cartaodecidadao.pt/publico/lrc/cc_sub-ec_cidadao_assinatura_crl0014_p0004.crl

Mato-Z commented 1 year ago

@kwart @JohnPlanetary Many thanks, for me it works perfectly! I tested it for BASELINE_LT: ./jsignpdf-pades.sh -da SHA256 -p11 pkcs11.cfg -kst PKCS11 -ts MY_TSA_URL -pl BASELINE_LT --trust-lotl-url https://ec.europa.eu/tools/lotl/eu-lotl.xml --trust-certificate-file MYeID_ROOT_CERT.der --trust-certificate-file MY_TSA_ROOT_CERT.pem.crt test.pdf

Mato-Z commented 1 year ago

@kwart @JohnPlanetary BASELINE-LTA works too, great, thanks a lot! And would it be possible to add just a separate timestamp?

JohnPlanetary commented 1 year ago

I tested again, but using ECC P-521 Root and signing certificate, and with that I was successful in signing up to PAdES B-LTA the PDF file, but the program isn't getting the CRL and OCSP values for both timestamps (incorporated in the first signing certificate and standalone one).

Also, the official national (EU) ID RSA 2048 bit SHA256 in the card, and my own Root and signing certificate with RSA 16384 bit SHA512 aren't working. I keep getting eu.europa.esig.dss.model.DSSException: Unable to save a document. Reason : Can't write signature, not enough space; adjust it with SignatureOptions.setPreferredSignatureSize error.

I'm guessing somewhere in the code it is needed to greatly increase the signaturesize, not sure if there is more than one setting for that [signing signature(s) and timestamping signature(s)] but they need to be increased otherwise will give error and will not sign the document. And to be clear, they both work in another application up to PAdES B-LTA without problems.

There isn't yet HASH command for the timestamp, correct? I was able to get SHA512 for the signature but the timestamp was SHA256. Most timestamp services use SHA256, but some also use SHA384 and even SHA512.

The only command that worked until now on my Windows Machine (PAdES B-LTA): java -jar C:\sign\signpdfs\jsignpdf-pades.jar -da SHA512 -kst WINDOWS-MY -ts https://freetsa.org/tsr --trust-certificate-url https://freetsa.org/files/cacert.pem -pl BASELINE_LTA --trust-certificate-url https://freetsa.org/files/tsa.crt --trust-certificate-file C:\sign\signpdfs\eccroot.crt C:\sign\signpdfs\test.pdf

Having to specify where the certificates are is kinda of problematic even for me, the program will need to somehow figure it out without the need for user intervention. Also many people won't be using certificates from the EU list, even if they are in EU, so it needs also to be sort out to make sure it will work both with EU official certificates and any other certificates including self made ones, so that it is as much future proof as possible.

NextTherapist commented 2 months ago

Unfortunately I fail when trying to produce an LTV signature with JSignPDF 2.2.2. And I assume it has to do with my certificate structure. My signature certificate is issued by an Intermediate CA, so for full LTV CRL information two CRLs need to be added to the signature (from Intermediate CA and from Root CA).

On my server all http requests are rerouted to https. In my signature certificate the Authority Information Access URL and the CRL URL are on https, but in the CA certificates they are not yet.

I get an LTV signature when signing with Adobe Reader, and the resulting files are about 50 KB bigger than the files from JSignPDF. Seems Adobe Reader can handle that http/https stuff, but JSignPDF has trouble with it.

JohnPlanetary commented 2 months ago

To get LTV status it needs to get CRL and or OCSP values from url's in the certificate chain of the digital certificate used to sign. You should try to see if you can install the Root and intermediate certificates used in the operating system and see if it helps the program to find the url's correctly. The Java program must have access to the Internet to get the data from CRL/ OCSP servers.

You can leave the Certification level at any other option other than "No change allow", to allow the pdf to receive that data that activates LTV from Adobe Acrobat Reader. You can see here: https://www.ssl.com/how-to/long-term-validation-ltv-of-pdf-digital-signatures-in-adobe-acrobat/#enable how to do it (is in the end of the article) on the Adobe Acrobat Reader. You need to save the file to keep that LTV enabled. Also, for some unknown reason to me, it doesn't always work, meaning, it may not work at all, or it will appear to work and a few days after you open the file again and the file isn't LTV enabled. I couldn't find why, shouldn't happen, but happens.

NextTherapist commented 2 months ago

You should try to see if you can install the Root and intermediate certificates used in the operating system and see if it helps the program to find the url's correctly.

They are installed and trusted in my Windows Certificate Store.

The Java program must have access to the Internet to get the data from CRL/ OCSP servers.

It has, since it gets a timestamp from a Sectigo server.

After signing I get a message like "loading CRL from ...", "size of the downloaded CRL...", but only for one CRL, and not for the other.

JohnPlanetary commented 2 months ago

CRL's and OCSP's servers all over the place do seem to have trouble from times to times, so it may just be that they aren't working, or the size of the file is really big! And takes a long time to download even if you have a fast connection because the server may be slow. In my national ID card it can make a 120 KB file have like 50 MB! It does take a while to download. If they would only use OCSP's servers I think the files would be smaller, but with CRL files they are usually much bigger. There is nothing I can do on the options for my use case, since in many cases there isn't even an OCSP server referenced in the intermediate and/ or final certificate.