private void UpdateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) { PdfArray b = v.GetAsArray(PdfName.BYTERANGE); RandomAccessFileOrArray rf = reader.SafeFile; try { rf.ReOpen(); byte[] buf = new byte[8192]; for (int k = 0; k < b.Size; ++k) { int start = b.GetAsNumber(k).IntValue; int length = b.GetAsNumber(++k).IntValue; rf.Seek(start); while (length > 0) { int rd = rf.Read(buf, 0, Math.Min(length, buf.Length)); if (rd <= 0) break; length -= rd; pkcs7.Update(buf, 0, rd); } } } finally { try{rf.Close();}catch{} } }
private void UpdateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) { PdfArray b = (PdfArray)PdfReader.GetPdfObject(v.Get(PdfName.BYTERANGE)); RandomAccessFileOrArray rf = reader.SafeFile; try { rf.ReOpen(); byte[] buf = new byte[8192]; ArrayList ar = b.ArrayList; for (int k = 0; k < ar.Count; ++k) { int start = ((PdfNumber)ar[k]).IntValue; int length = ((PdfNumber)ar[++k]).IntValue; rf.Seek(start); while (length > 0) { int rd = rf.Read(buf, 0, Math.Min(length, buf.Length)); if (rd <= 0) break; length -= rd; pkcs7.Update(buf, 0, rd); } } } finally { try{rf.Close();}catch{} } }
public void Sign(PDFSignatureAP sigAP, bool encrypt, PDFEncryption enc) { byte[] ownerPassword = null; if (!string.IsNullOrEmpty(enc.OwnerPwd)) { ownerPassword = DocWriter.GetISOBytes(enc.OwnerPwd); } PdfReader reader = new PdfReader(this.inputPDF, ownerPassword); FileStream fs = new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write); PdfStamper st; if (this.myCert == null) //No signature just write meta-data and quit { st = new PdfStamper(reader, fs); } else { st = PdfStamper.CreateSignature(reader, fs, '\0', null, sigAP.Multi); } if (encrypt && enc != null) enc.Encrypt(st); //st.SetEncryption(PdfWriter.STRENGTH128BITS, "user", "owner", PdfWriter.ALLOW_COPY); st.MoreInfo = this.metadata.getMetaData(); st.XmpMetadata = this.metadata.getStreamedMetaData(); if (this.myCert == null) //No signature just write meta-data and quit { st.Close(); return; } PdfSignatureAppearance sap = st.SignatureAppearance; //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED); sap.Reason = sigAP.SigReason; sap.Contact = sigAP.SigContact; sap.Location = sigAP.SigLocation; if (sigAP.Visible) { iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page); sap.Image = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData); sap.Layer2Text = sigAP.CustomText; sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, null); } // Remove yellow question mark (green check mark is still used though) //sap.GetLayer(1); // The first signature is a certification //if (!sigAP.Multi) //{ // //sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED; // sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING; //} PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); PdfPKCS7 sgn = new PdfPKCS7(this.myCert.Akp, this.myCert.Chain, null, "SHA-256", false); IDigest messageDigest = DigestUtilities.GetDigest("SHA-256"); // change for itextsharp-all-5.2.1 Stream data = sap.GetRangeStream(); byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); DateTime cal = DateTime.Now; byte[] ocsp = null; if (this.myCert.Chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]); if (url != null && url.Length > 0) { //ocsp = new OcspClientBouncyCastle(this.myCert.Chain[0], this.myCert.Chain[1], url).GetEncoded(); // change for itextsharp-all-5.2.1 ocsp = new OcspClientBouncyCastle().GetEncoded(this.myCert.Chain[0], this.myCert.Chain[1], url); } } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); byte[] paddedSig = new byte[contentEstimated]; if (this.myCert.Tsc != null) { byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp); System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) throw new Exception("Not enough space for signature"); } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) throw new Exception("Not enough space for signature"); } PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); //// Lock all fields after signing (backport from iText 5.4.4) - wrong - doesn't work //PdfDictionary lockDic = new PdfDictionary(new PdfName("SigFieldLock")); //lockDic.Put(PdfName.ACTION, new PdfName("All")); //lockDic.Put(PdfName.P, new PdfNumber(1)); //dic2.Put(PdfName.LOCK, lockDic); sap.Close(dic2); //st.Close(); }
public void ProcessFile(string infile, string outfile) { PdfReader reader = new PdfReader(infile); FileStream fs = new FileStream(outfile, FileMode.Create, FileAccess.Write); PdfStamper st = PdfStamper.CreateSignature(reader, fs, '\0'); PdfSignatureAppearance sap = st.SignatureAppearance; SignatureDataHandler.SetMetadata(config, st); /*var meta = config.Metadata; if (meta != null && meta.Count > 0) { //st.MoreInfo = new Hashtable(meta); st.MoreInfo = meta; st.XmpMetadata = config.GetStreamedMetaData(); }*/ //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.SetCrypto(null, CertReader.Chain, null, PdfSignatureAppearance.WINCER_SIGNED); SignatureDataHandler.SetAppearance(config, sap); ///// PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) var exc = new Dictionary<PdfName, int>(); //var exc = new Hashtable(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); PdfPKCS7 sgn = new PdfPKCS7(CertReader.Akp, CertReader.Chain, null, "SHA1", false); IDigest messageDigest = DigestUtilities.GetDigest("SHA1"); //Stream data = sap.RangeStream; Stream data = sap.GetRangeStream(); byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); DateTime cal = DateTime.Now; byte[] ocsp = null; if (CertReader.Chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(CertReader.Chain[0]); if (!string.IsNullOrEmpty(url)) ocsp = new OcspClientBouncyCastle().GetEncoded(CertReader.Chain[0], CertReader.Chain[1], url); //ocsp = new OcspClientBouncyCastle(CertReader.Chain[0], CertReader.Chain[1], url).GetEncoded(); } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); byte[] paddedSig = new byte[contentEstimated]; if (config.Stamp) { ITSAClient tsc = GetTsaClient(); byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, tsc, ocsp); System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) throw new Exception("Not enough space for signature"); } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) throw new Exception("Not enough space for signature"); } PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }