There are two problems in your code that correctly make Adobe Reader report issues. I'm not sure yet, though, whether after fixing them Adobe Reader will be happy.
The issues in your work flow are:
- Certification signature as second signature
- PAdES ESIC extension only declared after first signature
Certification signature as second signature
First of all, your code applies a normal approval signature (PdfSigner.NOT_CERTIFIED
set by signer.SetCertificationLevel
) as first signature and then a certification signature (PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED
set by signer.SetCertificationLevel
) as second one.
This is not allowed. According to the PDF specification ISO 32000-1:
A PDF document may contain [...]
At most one certification signature (PDF 1.5). [...] The signature dictionary shall contain a signature reference dictionary (see Table 253) that has a DocMDP transform method. [...]
A document can contain only one signature field that contains a DocMDP transform method; it shall be the first signed field in the document.
(sections 12.8.1 and 12.8.2.2.1 of ISO 32000-1)
And according to ISO 32000-2:
A PDF document may contain the following standard types of signatures: [...]
One or more approval signatures (also known as recipient signatures). These shall follow the certification signature if one is present.
(section 12.8.1 of ISO 32000-2)
Either way, approval signatures must follow the certification signature, not precede it.
(The change between the specification versions most likely has been made to allow document time stamps to precede the certification signature.)
Thus, already immediately after the second signature had been applied, Adobe Reader should have complained!
There is a way, though, to change the certification level in a later approval signature: If your PDF validator supports ISO 32000-1 with Adobe Supplement with ExtensionLevel 3 or ISO 32000-2, FieldMDP transforms can be used to this effect.
Please read this answer for some information on this option.
PAdES ESIC extension only declared after first signature
Your first signature is applied without the document declaring that any PDF extensions apply. Thus, a PDF validator may assume that for signature validation the base ISO 32000-1 rules apply, in particular that a certification level of "no changes allowed" indeed means that no changes are allowed. Only if an appropriate extension is declared and the PDF validator supports it, this rule may differ. In particular
- ESIC extension level 1 (as per ETSI TS 102 778-4 and EN 319 142-1) or
- ADBE extension level 5 (as per ETSI TS 102 778-4) or
- ADBE extension level 8 (as per ETSI EN 319 142-1)
should indicate that, as ISO 32000-2 meanwhile puts it,
Changes to a PDF that are incremental updates which include only the data necessary to add DSS’s and/or document timestamps to the document shall not be considered as changes to the document
The LTV adding code of iText in your PDFs then declares an ESIC extension level 5. I'm not sure where that comes from, whether there is another TS or EN mentioning that level or whether the ESIC and ADBE levels have been mishmashed.
Thus, already with your first signature you should declare one of the extensions mentioned above.
If document
is your PdfDocument
instance before or while you apply the first signature (you may have to retrieve it from your PdfSigner signer
using signer.GetDocument()
), you can declare an extension like this:
PdfDeveloperExtension extension = new iText.Kernel.Pdf.PdfDeveloperExtension
(PdfName.ESIC, PdfName.Pdf_Version_1_7, 1);
document.GetCatalog().AddDeveloperExtension(extension);
Alternatively your should set your PDF version to 2.0 when signing. This may cause other issues, though.