Using the MySigner.SignedDeferred method (MySigner extends the PdfSigner class as described here) I am able to digitally sign the document with an invisible signature which Adobe Reader validates in the signature panel.
However, when I try to attach an in-document signature visualization to an existing signature as described here, The generated pdf then has a signature panel banner that reads "Signed and all signature are valid but with unsigned changes".
I find this perplexing since before signer.SignExternalContainer is called I do not change the Certification Level, thus ensuring it defaults and thus is Not at a level of certified with no changes allowed.
pdf screenshot in Adobe Reader
Also the original stamping properties to generate the unsigned PDF (source) uses AppendMode.
Here is the relevant C# code:
PdfReader readerPrepped2 = new PdfReader(pathDestination);
PdfWriter pdfWriter2 = new PdfWriter(pathDestination2);
PdfDocument pdfDocument = new PdfDocument(readerPrepped2, pdfWriter2, new StampingProperties().UseAppendMode());
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDocument, false);
foreach (String name in signatureUtil.GetSignatureNames())
{
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(name);
X509Certificate signerCert = x509Certificate3;
String signerName = CertificateInfo.GetSubjectFields(signerCert).GetField("CN");
String issuer = CertificateInfo.GetIssuerFields(signerCert).GetField("CN");
var date = pkcs7.GetSignDate().ToString();
PdfFormField field = acroForm.GetField("Signature");
PdfFont font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
field.SetFont(font);
field.SetFontSize(5);
field.SetModified();
field.SetVisibility(4);
foreach (PdfWidgetAnnotation pdfWidgetAnnotation in field.GetWidgets())
{
pdfWidgetAnnotation.SetRectangle(new PdfArray(new Rectangle(36, 348, 236, 428)));
// pdfWidgetAnnotation.SetColor([])
PdfFormXObject form = new PdfFormXObject(new Rectangle(200, 80));
// form.SetModified();
Canvas canvas = new Canvas(form, pdfDocument);
//canvas.SetStrokeColor(ColorConstants.RED);
canvas.SetFontSize(6);
canvas.Add(new Paragraph().SetItalic().Add("Signed by:"));
canvas.Add(new Paragraph()/*.SetBold()*/.Add(signerName));
canvas.Add(new Paragraph().SetItalic().Add("Date:"));
canvas.Add(new Paragraph()/*.SetBold()*/.Add(date));
canvas.Add(new Paragraph().SetItalic().Add("Issuer:"));
canvas.Add(new Paragraph()/*.SetBold()*/.Add(issuer));
pdfWidgetAnnotation.SetNormalAppearance(form.GetPdfObject());
}
}
pdfDocument.SetCloseWriter(true);
pdfDocument.SetCloseReader(false);
pdfDocument.Close();
I tried extending the PDFSigner class with a new class called MySigner so as to avoid adding entries to the structure tree. I also tried explcitly designating the CERTIFICATION_LEVEL as PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS (to no avail as Adobe does not recognize the pdf as digitally signed at all in this scenario). I also tried toggling .SetModified on form and field.