title: Signing existing PDF document sometimes causes a corrupt file
body: <p>I am writing a demo proof of concept to add electronic signatures to existing PDFs. I am running into one weird problem that I don't get. It seems that adding the signature to some documents works fine while adding one to others does not work and a corrupt file is generated that Adobe Reader can not open.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using iText;
  using iText.Kernel.Pdf;
  using System.IO;
  using iText.Layout;
  using iText.Layout.Element;
  using iText.Kernel.Geom;
  using Org.BouncyCastle.Crypto.Tls;
  using iText.Signatures;
  using System.Collections.ObjectModel;
  using Org.BouncyCastle.Pkcs;
  using System.Security.Cryptography.X509Certificates;
  using Org.BouncyCastle.Crypto;
  using System.Security.Cryptography;
  using Org.BouncyCastle.Crypto.Parameters;
  using Org.BouncyCastle.Math;
  using iText.IO.Image;
  
  namespace LTVSkilrikjaDemo
  {
      class Program
      {
          static void Main(string[] args)
          {
              string welcomeText = "Welcome to LTVSkilríkjaDemotolid!";
              string pressEnterToTry = "Commands: 's' - sign, 'stop' - stops the programme";
              Console.WriteLine(welcomeText);
              Console.WriteLine(pressEnterToTry);
  
              // Base directory prepared
              string basedir = AppDomain.CurrentDomain.BaseDirectory;
              int index = basedir.IndexOf(@"bin\");
              basedir = basedir.Remove(index);
  
              string readString = Console.ReadLine().ToLower();
  
              while(!readString.Equals("stop"))
              {
                  if(readString.Equals("c"))
                  {
                      string inFile = "Infile2.pdf";
                      string outFile = "Outfile2.pdf";
  
                      // Open PDF document and decide where to write the new document
                      PdfWorker worker = new PdfWorker();
                      worker.ReadPdf(basedir + "App_Data\\InFiles\\" + inFile, basedir + "App_Data\\OutFiles\\" + outFile);
  
                      // Start working on certificate
                      X509Store store = new X509Store("My");
  
                      store.Open(OpenFlags.ReadOnly);
  
                      Collection&lt;Org.BouncyCastle.X509.X509Certificate&gt; xcertificates = new Collection&lt;Org.BouncyCastle.X509.X509Certificate&gt;();
  
                      foreach (X509Certificate2 mCert in store.Certificates)
                      {
                          if (mCert.Subject.IndexOf("CN=Róbert") &gt; -1)
                          {
                               xcertificates.Add(Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(mCert));
                          }
                      }
  
                      Org.BouncyCastle.X509.X509Certificate[] certificatesProcessed = new Org.BouncyCastle.X509.X509Certificate[xcertificates.Count];
                      for(int i = 0; i &lt; xcertificates.Count; i++)
                      {
                          certificatesProcessed[i] = xcertificates[i];
                      }
  
                      var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(store.Certificates[5].PrivateKey).Private;
  
                      try
                      {
                          worker.Sign(certificatesProcessed, pk, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CADES, "No apparent raisin!", "Lost in Iceland", null, null, null, 0, true, basedir);
                      }
                      catch(Exception ex)
                      {
                          Console.ForegroundColor = ConsoleColor.Red;
                          Console.WriteLine("Error! " + ex.Message + "\n\r" + ex.StackTrace);
                          if(ex.InnerException != null)
                          {
                              Console.WriteLine("Inner exception: " + ex.InnerException.Message);
                          }
                          Console.ForegroundColor = ConsoleColor.Gray;                      
                      }
                  }
                  else if(!readString.Equals("stop"))
                  {
                      Console.WriteLine("Command not understood. Understand only 's' and 'stop'.");
                  }
  
                  readString = Console.ReadLine();
              }
  
              Console.WriteLine("Goodbye!");
              System.Threading.Thread.Sleep(500);
  
          }
      }
  
      public class PdfWorker
      {
          private PdfDocument _document;
          private string _source;
          private string _dest;
  
          public void ReadPdf(string source, string dest)
          {
              _source = source;
              _dest = dest;
          }
  
          public void Sign(Org.BouncyCastle.X509.X509Certificate[] chain, Org.BouncyCastle.Crypto.ICipherParameters pk,
              string digestAlgorithm, PdfSigner.CryptoStandard subfilter, string reason, 
              string location, Collection&lt;ICrlClient&gt; crlList, IOcspClient ocspClient, ITSAClient tsaClient,
              int estimatedSize, bool initial, string baseDir)
          {
              File.Copy(_source, _dest, true);
              FileStream f = new FileStream(_dest, FileMode.Append);
              try
              {
  
                  PdfSigner signer = new PdfSigner(new PdfReader(_source), f, true);
                  _document = signer.GetDocument();
                  _document.AddNewPage();
  
                  // Work the last page
                  Rectangle pageSize = _document.GetLastPage().GetPageSizeWithRotation();
                  //PdfWriter w = _document.GetWriter();
                  //long currentPos = w.GetCurrentPos();
                  float llx = pageSize.GetWidth() - 350 - 20; //pageSize.GetWidth() / 2 - 350 / 2;
                  float lly = pageSize.GetHeight() - 50 - 20; // pageSize.GetHeight() / 2 - 150 / 2;
                  float urx = 350; //llx + 350;
                  float ury = 50; //lly + 150;
                  PdfSignatureAppearance appearance = signer.GetSignatureAppearance();
                  appearance.SetPageRect(new Rectangle(llx, lly, urx, ury));
                  appearance.SetReason(reason);
                  appearance.SetLocation(location);
  
                  byte[] imagebytes = File.ReadAllBytes(baseDir + "App_Data\\UndirskriftDemo.png");
                  // It is not possible to use the path as it contains Icelandic characters 
                  // which itext chokes on. We use byte array instead
                  ImageData imgData = ImageDataFactory.Create(imagebytes);
                  Image img = new Image(imgData);
                  img = img.ScaleToFit(350.0f, 50.0f);
                  appearance.SetImage(imgData);
  
                  int pageCount = _document.GetNumberOfPages();
  
                  // Creating the appearance
                  if(initial == true)
                  {
                      signer.SetCertificationLevel(PdfSigner.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
                  }
  
                  appearance.SetPageNumber(pageCount);
                  Rectangle rect = new Rectangle(10, 50, 350, 50);
                  appearance.SetPageRect(rect).SetPageNumber(pageCount);
                  appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
                  signer.SetFieldName(signer.GetNewSigFieldName());
  
                  // Creating the signature
              IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm);
  
                  signer.SignDetached(pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
  
                  Console.WriteLine("Signing successful!");
              }
              catch(Exception ex)
              {
                  throw ex;
              }
              finally
              {
                  _document.Close();
                  f.Close();
              }
          }
      }
  }
  </code></pre>
  
  <p>Please see the documents here then. Infile1.pdf I can not sign but Infile2.pdf is signed fine. Outfile1.pdf is the corrupt file.
  <a href="https://app.box.com/s/52jqe8qirl80km6hunxucs00dntx70o5" rel="nofollow noreferrer">https://app.box.com/s/52jqe8qirl80km6hunxucs00dntx70o5</a> </p>
  
  <p>What causes this? Is there something about the input PDF file or the above programme?</p>