public void AddField(String src, String dest) { PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest)); // Create a signature form field PdfSignatureFormField field = PdfFormField.CreateSignature(pdfDoc, new Rectangle(72, 632, 200, 100)); field.SetFieldName(SIGNAME); field.GetWidgets()[0].SetHighlightMode(PdfAnnotation.HIGHLIGHT_OUTLINE).SetFlags(PdfAnnotation.PRINT); PdfAcroForm.GetAcroForm(pdfDoc, true).AddField(field); pdfDoc.Close(); }
/// <summary>This is the first method to be called when using external signatures.</summary> /// <remarks> /// This is the first method to be called when using external signatures. The general sequence is: /// preClose(), getDocumentBytes() and close(). /// <p> /// <CODE>exclusionSizes</CODE> must contain at least /// the <CODE>PdfName.CONTENTS</CODE> key with the size that it will take in the /// document. Note that due to the hex string coding this size should be byte_size*2+2. /// </remarks> /// <param name="exclusionSizes"> /// Map with names and sizes to be excluded in the signature /// calculation. The key is a PdfName and the value an Integer. At least the /Contents must be present /// </param> /// <exception cref="System.IO.IOException">on error</exception> protected internal virtual void PreClose(IDictionary <PdfName, int?> exclusionSizes) { if (preClosed) { throw new PdfException(PdfException.DocumentAlreadyPreClosed); } // TODO: add mergeVerification functionality preClosed = true; PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(document, true); SignatureUtil sgnUtil = new SignatureUtil(document); String name = GetFieldName(); bool fieldExist = sgnUtil.DoesSignatureFieldExist(name); acroForm.SetSignatureFlags(PdfAcroForm.SIGNATURE_EXIST | PdfAcroForm.APPEND_ONLY); PdfSigFieldLockDictionary fieldLock = null; if (cryptoDictionary == null) { throw new PdfException(PdfException.NoCryptoDictionaryDefined); } cryptoDictionary.GetPdfObject().MakeIndirect(document); if (fieldExist) { PdfSignatureFormField sigField = (PdfSignatureFormField)acroForm.GetField(fieldName); sigField.Put(PdfName.V, cryptoDictionary.GetPdfObject()); fieldLock = sigField.GetSigFieldLockDictionary(); if (fieldLock == null && this.fieldLock != null) { this.fieldLock.GetPdfObject().MakeIndirect(document); sigField.Put(PdfName.Lock, this.fieldLock.GetPdfObject()); fieldLock = this.fieldLock; } sigField.Put(PdfName.P, document.GetPage(appearance.GetPageNumber()).GetPdfObject()); sigField.Put(PdfName.V, cryptoDictionary.GetPdfObject()); PdfObject obj = sigField.GetPdfObject().Get(PdfName.F); int flags = 0; if (obj != null && obj.IsNumber()) { flags = ((PdfNumber)obj).IntValue(); } flags |= PdfAnnotation.LOCKED; sigField.Put(PdfName.F, new PdfNumber(flags)); PdfDictionary ap = new PdfDictionary(); ap.Put(PdfName.N, appearance.GetAppearance().GetPdfObject()); sigField.Put(PdfName.AP, ap); sigField.SetModified(); } else { PdfWidgetAnnotation widget = new PdfWidgetAnnotation(appearance.GetPageRect()); widget.SetFlags(PdfAnnotation.PRINT | PdfAnnotation.LOCKED); PdfSignatureFormField sigField = PdfFormField.CreateSignature(document); sigField.SetFieldName(name); sigField.Put(PdfName.V, cryptoDictionary.GetPdfObject()); sigField.AddKid(widget); if (this.fieldLock != null) { this.fieldLock.GetPdfObject().MakeIndirect(document); sigField.Put(PdfName.Lock, this.fieldLock.GetPdfObject()); fieldLock = this.fieldLock; } int pagen = appearance.GetPageNumber(); widget.SetPage(document.GetPage(pagen)); PdfDictionary ap = widget.GetAppearanceDictionary(); if (ap == null) { ap = new PdfDictionary(); widget.Put(PdfName.AP, ap); } ap.Put(PdfName.N, appearance.GetAppearance().GetPdfObject()); acroForm.AddField(sigField, document.GetPage(pagen)); if (acroForm.GetPdfObject().IsIndirect()) { acroForm.SetModified(); } else { //Acroform dictionary is a Direct dictionary, //for proper flushing, catalog needs to be marked as modified document.GetCatalog().SetModified(); } } exclusionLocations = new Dictionary <PdfName, PdfLiteral>(); PdfLiteral lit = new PdfLiteral(80); exclusionLocations[PdfName.ByteRange] = lit; cryptoDictionary.Put(PdfName.ByteRange, lit); foreach (KeyValuePair <PdfName, int?> entry in exclusionSizes) { PdfName key = entry.Key; lit = new PdfLiteral((int)entry.Value); exclusionLocations[key] = lit; cryptoDictionary.Put(key, lit); } if (certificationLevel > 0) { AddDocMDP(cryptoDictionary); } if (fieldLock != null) { AddFieldMDP(cryptoDictionary, fieldLock); } if (signatureEvent != null) { signatureEvent.GetSignatureDictionary(cryptoDictionary); } if (certificationLevel > 0) { // add DocMDP entry to root PdfDictionary docmdp = new PdfDictionary(); docmdp.Put(PdfName.DocMDP, cryptoDictionary.GetPdfObject()); document.GetCatalog().Put(PdfName.Perms, docmdp); document.GetCatalog().SetModified(); } cryptoDictionary.GetPdfObject().Flush(false); document.Close(); range = new long[exclusionLocations.Count * 2]; long byteRangePosition = exclusionLocations.Get(PdfName.ByteRange).GetPosition(); exclusionLocations.JRemove(PdfName.ByteRange); int idx = 1; foreach (PdfLiteral lit1 in exclusionLocations.Values) { long n = lit1.GetPosition(); range[idx++] = n; range[idx++] = lit1.GetBytesCount() + n; } iText.IO.Util.JavaUtil.Sort(range, 1, range.Length - 1); for (int k = 3; k < range.Length - 2; k += 2) { range[k] -= range[k - 1]; } if (tempFile == null) { bout = temporaryOS.ToArray(); range[range.Length - 1] = bout.Length - range[range.Length - 2]; MemoryStream bos = new MemoryStream(); PdfOutputStream os = new PdfOutputStream(bos); os.Write('['); for (int k_1 = 0; k_1 < range.Length; ++k_1) { os.WriteLong(range[k_1]).Write(' '); } os.Write(']'); System.Array.Copy(bos.ToArray(), 0, bout, (int)byteRangePosition, bos.Length); } else { try { raf = FileUtil.GetRandomAccessFile(tempFile); long len = raf.Length; range[range.Length - 1] = len - range[range.Length - 2]; MemoryStream bos = new MemoryStream(); PdfOutputStream os = new PdfOutputStream(bos); os.Write('['); for (int k_1 = 0; k_1 < range.Length; ++k_1) { os.WriteLong(range[k_1]).Write(' '); } os.Write(']'); raf.Seek(byteRangePosition); raf.Write(bos.ToArray(), 0, (int)bos.Length); } catch (System.IO.IOException e) { try { raf.Close(); } catch (Exception) { } try { tempFile.Delete(); } catch (Exception) { } throw; } } }