1
votes

I am signing a pdf with digital certificate using iText. Now I can sign, and add LTV, but CertificateLevel can just be:

signatureAppearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);

I just want to set PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED. The final result should look like this:

enter image description here

sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
MakeSignature.signDetached(signatureAppearance, privateKey, "SHA-512", chain, null, ocspClient, tsaClient, 0, MakeSignature.CryptoStandard.CADES);

If i use the above code to sign, then using AdobeLtvEnabling.java to add LTV will prompt the signature to be invalid when using ACROBAT check, because the file is modifying the unmodifiable PDF file when adding LTV. Thus, what can i do to approach the final effect.

2
What exactly is the problem, why don't you simply replace CERTIFIED_FORM_FILLING_AND_ANNOTATIONS by CERTIFIED_NO_CHANGES_ALLOWED? Does that have to do with your adding LTV?mkl
If i use CERTIFIED_NO_CHANGES_ALLOWED type, I can not add LTV for the signed pdf is not allowed to change. So, my problem is that i want to add LTV to a pdf and make the signed pdf with digital certificate can't be modify.Scott Andrew
Do you sign using CMS or CADES? And how do you add LTV information?mkl
AdobeLtvEnabling adobeLtvEnabling = new AdobeLtvEnabling(signature); adobeLtvEnabling.enable(ocspClient, oca);Scott Andrew
I just tested it and indeed, Adobe Acrobat does not appear to fully support PDF 2.0 or PAdES yet; in spite of the correct extensions set and only changes to the DSS being made, Acrobat rejects the additions.mkl

2 Answers

4
votes

To get a result like in your snapshot, i.e. both "No changes are allowed" and "Signature is LTV enabled" without any later signature or document timestamp, you have to

  • either already include all LTV material the Adobe validator requires into your original signed revision
  • or use a signing mode which allows you to append LTV material in spite of no changes being allowed.

Unfortunately the latter variant seems not yet to be properly supported by Adobe Acrobat Reader.

For details see the following sections.

Include all LTV material into the original signed revision

First of all, this is not always possible. If you want to have the LTV material in the original signed revision, it must be part of the signed data, so you have to collect it before signing. In many setups using remote signing services, though, you don't know which signing certificate exactly will be used before actually requesting the signature.

If it is possible, though, i.e. if you know the signing certificate in advance, you can use the class AdobeLtvEnabling from this stack overflow answer to include the information like this:

PdfStamper stamper = PdfStamper.createSignature(...);

AdobeLtvEnabling adobeLtvEnabling = new AdobeLtvEnabling(stamper);
OcspClient ocsp = new OcspClientBouncyCastle();
CrlClient crl = new CrlClientOnline();
adobeLtvEnabling.addLtvForChain(YOUR_SIGNER_CERTIFICATE, ocsp, crl, PdfName.A);
adobeLtvEnabling.outputDss();

[...preparing your signature...]
MakeSignature.signDetached(...);

(CreateSignatureComodo test testCreateLtvNoChangesAllowedCertification)

You might have to make the AdobeLtvEnabling methods addLtvForChain and outputDss public for this as AdobeLtvEnabling originally wsn't intended to be used like this.

The result:

screen shot

Use a signing mode which allows appending LTV material but nothing else

Alternatively you can sign your PDF in a way that allows later addition of LTV material in spite of a "no changes allowed" certification.

To start with, it is necessary to make use of a mechanism first specified for PAdES signatures if you want to add LTV material to a PDF after applying the signature it is meant for. While this mechanism has meanwhile been included in ISO 32000-2, it is not available in a plain ISO 32000-1 context. As your screenshot is of a Adobe Acrobat, though, that shouldn't be an issue for you.

This mechanism are the document security stores. Both the iText class LtvVerification and the class AdobeLtvEnabling from this stack overflow answer fill such stores in a PDF.

Is it allowed to add these document security stores in spite of a "no changes allowed" certification? — It depends...

If your PDF is a PDF-2.0: yes. ISO 32000-2 characterizes the changes allowed or disallowed by some certification like this:

Changes to a PDF that are incremental updates which include only the data necessary to add DSS’s 12.8.4.3, "Document Security Store (DSS)" and/or document timestamps 12.8.5, "Document timestamp (DTS) dictionary" to the document shall not be considered as changes to the document as defined in the choices below.

(ISO 32000-2, Table 257 — Entries in the DocMDP transform parameters dictionary)

If your PDF is a PDF-1.x with the PAdES extensions enabled: yes. ETSI EN 319 142-1 requires

DocMDP restrictions (see ISO 32000-1 1, clause 12.8.2.2) shall not apply to incremental updates to a PDF document containing a DSS dictionary and associated VRI, Certs, CRLs and OCSPs.

...

When evaluating the DocMDP restrictions (see ISO 32000-1 1, clause 12.8.2.2) the presence of a Document Time-stamp dictionary item shall be ignored.

(ETSI EN 319 142-1 V1.1.1, section 5.4 Validation data and archive validation data attributes)

If your PDF is a plain PDF-1.x, though: no!

If you want to use this option and add LTV information after signing, therefore, make sure your originally certified PDF is a PDF-2 or has at least the PAdES extensions enabled.

While iText 5 does not support PDF-2, creating a PAdES style signature with it adds the PAdES extensions.

Thus, if you certify PAdES-style, you should be able to LTV-enable the signature even if the certification is "no changes allowed".

Support by Adobe Acrobat Reader DC 2019.008.20080

Having done some tests extending a no-changes allowed certified PDF with only LTV information, the PDF being either marked as PDF-1.7 with the appropriate ETSI and Adobe extensions or as PDF-2.0, it appears that Adobe Acrobat supports neither ETSI EN 319 142-1 nor ISO 32000-2 fully yet: In all tests it considered the certification as broken, cf. CreateSignatureComodo test testCreateNoChangesAllowedCertificationAndLtv.

For the time being, therefore, to get a document with LTV enabled no-changes-allowed certification and to have Adobe Acrobat recognize this, one only has the first option above, i.e. including all LTV material into the original signed revision.

A work-around might be to create the certification with form-filling-allowed, then adding LTV information, and then signing with another (approval) signature which changes the document to no-changes-allowed via its field lock dictionary and its FieldMDP transform, cf. CreateSignatureComodo test testCreateCertificationAndLtvAndNoChangesAllowed. As the incremental update of that signature can be removed by a knowledgeable person, though, this is far from perfect.

The result for the work-around:

screen shot

0
votes

I'm using itextsharp and I guess the following will be useful for your Java code too.

If you call MakeSignature.SignDetached with CrlClient and OcspClient (instead of passing null as parameter), you'll get a LTV-enabled signature after the first step. Then you needn't do the second step to add a document timestamp after.

var stamper = PdfStamper.CreateSignature(reader, stream, '\0', null, true);
var appearance = stamper.SignatureAppearance;
appearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
...
var privateKey = ...
var chain = ...
var crlClient = new CrlClientOnline(chain);
var ocspClient = new OcspClientBouncyCastle();
var tsaClient = new TSAClientBouncyCastle("http://....");

MakeSignature.SignDetached(appearance, privateKey, chain, 
    new[] { crlClient }, 
    ocspClient,
    tsaClient, 
    0, 
    CryptoStandard.CMS);
stamper.Close();

Hope this works for you.