0

When I use ITextSharp to digitally sign a document that is already digitally signed using this code it invalidates the other signatures. If I digitally sign using a text or image it works fine. Is this an Adobe/Itextsharp limitation or is something wrong with the code?

public void SignWithLine(string pdfFilePath, string outputFilePath, LineAnnotation lineAnnotation)
{        
    double xStartPoint = 89.285969238281268, yStartPoint = 343.08978515624881, xEndPoint = 72.7515234375, yEndPoint = 496.03341796874878, lineStroke = .24;

    CertificateWrapper certificate = CertificateWrapper.GetCertificateInformationFromSignature(GetCertificateInformation());
    PdfReader reader = new PdfReader(pdfFilePath);
    PdfTemplate layer = null;
    using (PdfStamper signature = PdfStamper.CreateSignature(reader, null, '\0', outputFilePath, true))
    {
        PdfSignatureAppearance signatureAppearance = signature.SignatureAppearance;
        signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC;
        Rectangle rect = new Rectangle((float)Math.Min(xStartPoint, xEndPoint), (float)Math.Min(yStartPoint, yEndPoint), (float)Math.Min(xStartPoint, xEndPoint) + (float)Math.Abs(xEndPoint - xStartPoint), (float)Math.Min(yStartPoint, yEndPoint) + (float)Math.Abs(yEndPoint - yStartPoint));
        signatureAppearance.SetVisibleSignature(rect, lineAnnotation.PageIndex + 1, GetCertificateFieldName());
        layer = signatureAppearance.GetLayer(2);

        PdfContentByte cb = signature.GetUnderContent(lineAnnotation.PageIndex + 1);
        cb.SetLineWidth((float)lineStroke);
        cb.MoveTo((float)xStartPoint, (float)yStartPoint);
        cb.LineTo((float)(xEndPoint), (float)(yEndPoint));
        cb.Stroke();

        signatureAppearance.CertificationLevel = PdfSignatureAppearance.NOT_CERTIFIED;
        // Normal signature, not a certification
        MakeSignature.SignDetached(signatureAppearance, certificate.DigitalSignature, certificate.Chain, null, null, null, 0, true);

        signature.Close();
    }
}
Andrew
  • 1,963
  • 3
  • 25
  • 35
hawk
  • 1
  • Adobe protects the signatures. So if you try to resign a document the original signature gets removed. It is a security feature. – FeliceM Sep 25 '13 at 15:25

2 Answers2

1

signature is your PdfStamper. You draw a line on

PdfContentByte cb = signature.GetUnderContent(lineAnnotation.PageIndex + 1);

i.e. You draw it in the content stream of a page. This counts as a change of the page content and, therefore, is forbidden by the original signature. For details on the allowed changes cf. this answer.

Community
  • 1
  • 1
mkl
  • 90,588
  • 15
  • 125
  • 265
0

I found a way to do this by modifying the iTextSharp library.

// First I overloaded the SetVisibleSignature to pass a list of int

public void SetVisibleSignature(Rectangle pageRect, String fieldName, List pageList) { pages = pageList; // pages is a private List pages; ... }

// Secondly, in the PreClose event you update it as shown below

            sigField.Page = pagen;
            if (pagen != 0)
                writer.AddAnnotation(sigField, pagen);
           else if (pages != null && pages.Count > 0) 
                pages.ForEach(f => writer.AddAnnotation(sigField, f)); // this annotates all pages with the same signature
            else
                throw new DocumentException("No pages specified for signature.");
hawk
  • 1
  • *I found a way to do this* - your answer is about **showing your signature on multiple pages** but the question was about **invalidating signatures when using lines or rectangles**. Maybe you wanted to answer a different question? ... That being said, the PDF specification says "A given annotation dictionary shall be referenced from the Annots array of only one page" (section 12.5.2 of [ISO 32000-1](http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf)). Thus, PDF viewers may reject your PDFs as broken. And if they don't do now, future versions may well do. – mkl Oct 10 '13 at 07:51
  • 1
    Yes, I apologize. I thought I was answering a different question. – hawk Oct 11 '13 at 13:59