/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.SetVisibleSignature(new Rectangle(0,0,0,0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary<PdfName,int> exc = new Dictionary<PdfName,int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = DigestUtilities.GetDigest(tsa.GetDigestAlgorithm()); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken = tsa.GetTimeStampToken(tsImprint); if (contentEstimated + 2 < tsToken.Length) throw new Exception("Not enough space"); byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL5); sap.SetVisibleSignature(new Rectangle(0, 0, 0, 0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = tsa.GetMessageDigest(); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken; try { tsToken = tsa.GetTimeStampToken(tsImprint); } catch (Exception e) { throw new GeneralSecurityException(e.Message); } //TODO jbonilla Validar para el TSA de Certificado que devuelve un valor muy grande. if (contentEstimated + 2 < tsToken.Length) { throw new IOException("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.SetVisibleSignature(new Rectangle(0, 0, 0, 0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = tsa.GetMessageDigest(); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken = tsa.GetTimeStampToken(tsImprint); if (contentEstimated + 2 < tsToken.Length) { throw new Exception("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL5); sap.SetVisibleSignature(new Rectangle(0,0,0,0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary<PdfName,int> exc = new Dictionary<PdfName,int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = tsa.GetMessageDigest(); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken; try { tsToken = tsa.GetTimeStampToken(tsImprint); } catch(Exception e) { throw new GeneralSecurityException(e.Message); } //TODO jbonilla Validar para el TSA de Certificado que devuelve un valor muy grande. if (contentEstimated + 2 < tsToken.Length) throw new IOException("Not enough space"); byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
private void CompletionPdf(byte[] invoiceMemoryStream, List <FileStream> attachmentFiles, string fileName) { var reader = new PdfReader(invoiceMemoryStream); var document = new Document(reader.GetPageSizeWithRotation(1)); var pdfMerge = new MemoryStream(); var pdfCopyProvider = new PdfCopy(document, pdfMerge); document.Open(); var pages = new List <PdfImportedPage>(); GetAllPages(reader, pdfCopyProvider, pages); foreach (var attachmentReader in attachmentFiles.Select(attachmentFile => new PdfReader(attachmentFile))) { GetAllPages(attachmentReader, pdfCopyProvider, pages); attachmentReader.Close(); } foreach (var pdfImportedPage in pages) { pdfCopyProvider.AddPage(pdfImportedPage); } document.Close(); reader.Close(); pdfCopyProvider.Close(); pdfMerge.Seek(0, SeekOrigin.Begin); var readerWithoutSign = new PdfReader(pdfMerge); var finalOutput = new FileStream(fileName, FileMode.Create, FileAccess.Write); var tsa = new TsaClientBouncyCastle("https://freetsa.org/tsr"); int contentEstimated = (int)pdfMerge.Length; var st = PdfStamper.CreateSignature(readerWithoutSign, finalOutput, '\0', null, true); var sap = st.SignatureAppearance; var cert = new Cert("EFZ.pfx", "Lea10985"); sap.SetCrypto(cert.Akp, cert.Chain, null, PdfSignatureAppearance.SelfSigned); sap.Reason = "Archived digital signature"; sap.Contact = "EFZ"; sap.Location = "EFZ"; sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED; sap.SetCrypto(null, cert.Chain, null, PdfSignatureAppearance.VerisignSigned); var dic = new PdfSignature(PdfName.AdobePpklite, PdfName.AdbePkcs7Detached); dic.Put(PdfName.TYPE, PdfName.Stamp); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; var exc = new Dictionary <PdfName, int>(); exc[PdfName.Contents] = contentEstimated * 2 + 2; sap.PreClose(new Hashtable(exc)); var sgn = new PdfPkcs7(cert.Akp, cert.Chain, null, "SHA1", false); var data = sap.RangeStream; var messageDigest = DigestUtilities.GetDigest("SHA1"); byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); var cal = DateTime.UtcNow; byte[] tsToken = tsa.GetTimeStampToken(null, tsImprint); byte[] ocsp = null; if (cert.Chain.Length >= 2) { String url = PdfPkcs7.GetOcspurl(cert.Chain[0]); if (url != null && url.Length > 0) { ocsp = new OcspClientBouncyCastle(cert.Chain[0], cert.Chain[1], url).GetEncoded(); } } byte[] sh = sgn.GetAuthenticatedAttributeBytes(tsImprint, cal, ocsp); sgn.Update(sh, 0, sh.Length); byte[] encodedSig = sgn.GetEncodedPkcs7(tsImprint, cal, tsa, ocsp); if (contentEstimated + 2 < encodedSig.Length) { throw new Exception("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); var dic2 = new PdfDictionary(); dic2.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); finalOutput.Close(); finalOutput.Dispose(); }
public void GetSignatureDictionary(PdfSignature sig) { sig.Put(PdfName.Name, new PdfString(fullName)); }