private void SignUsingEstEIDCard2(string filename, string outfile) { statusHandler(Resources.VERIFYING_DOCUMENT, false); AcroFields af = this.reader.AcroFields; ArrayList names = af.GetSignatureNames(); bool nextRevision = ((names != null) && (names.Count > 0)); // already signed ? if (nextRevision) { // pick always first signature string name = (string)names[0]; PdfPKCS7 pkc7 = af.VerifySignature(name); bool verify = pkc7.Verify(); if (!verify) { string who = PdfPKCS7.GetSubjectFields(pkc7.SigningCertificate).GetField("CN"); throw new DocVerifyException(Resources.DOC_VERIFY_FAILED + who); } } statusHandler(Resources.CONNECTING_SMARTCARD, false); // open EstEID EstEIDReader estEidReader = new EstEIDReader(); string pkcs11_lib = conf.PKCS11DriverPath; bool b = estEidReader.Open(pkcs11_lib); if (b == false) { throw new Exception(Resources.PKCS11_OPEN); } statusHandler(Resources.READ_CERTS, false); PKCS11Signer signer = LocateSigner(estEidReader); Org.BouncyCastle.X509.X509Certificate[] chain = X509Utils.LoadCertificate(signer.Cert.RawData); statusHandler(Resources.VERIFYING_OCSP, false); OCSPClientEstEID ocspClient = OCSPClient(chain[0]); if (ocspClient == null) { throw new Exception(this.lastError); } byte[] ocsp = ocspClient.GetEncoded(); if (ocsp == null) { throw new RevocationException(ocspClient.lastError); } X509Certificate2 card = signer.Cert; Oid oid = card.SignatureAlgorithm; if (oid.Value != PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id) { throw new Exception(Resources.INVALID_CERT); } PdfReader reader = new PdfReader(filename); Document document = new Document(reader.GetPageSizeWithRotation(1)); PdfStamper stp = PdfStamper.CreateSignature(reader, new FileStream(outfile, FileMode.Create), '\0', null, nextRevision); if (metadata != null) { stp.XmpMetadata = metadata.getStreamedMetaData(); } PdfSignatureAppearance sap = stp.SignatureAppearance; if (appearance.Visible) { if (appearance.SigLocation.UseSector) { appearance.SigLocation.Bounds = document.PageSize; } sap.SetVisibleSignature(appearance.SigLocation, (int)appearance.Page, null); } sap.SignDate = DateTime.Now; sap.SetCrypto(null, chain, null, null); sap.Reason = (appearance.Reason.Length > 0) ? appearance.Reason : null; sap.Location = (appearance.Location.Length > 0) ? appearance.Location : null; sap.Contact = (appearance.Contact.Length > 0) ? appearance.Contact : null; sap.Acro6Layers = true; sap.Render = appearance.SignatureRender; sap.Layer2Text = appearance.SignatureText(sap.SignDate, chain[0]); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_SHA1); dic.Date = new PdfDate(sap.SignDate); dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"); if (sap.Reason != null) { dic.Reason = sap.Reason; } if (sap.Location != null) { dic.Location = sap.Location; } if (sap.Contact != null) { dic.Contact = sap.Contact; } sap.CryptoDictionary = dic; sap.SetExternalDigest(new byte[SIGNATURE_LENGTH], new byte[Digest.SHA1_LENGTH], "RSA"); // expect 6K to be enough if TSA response, else 2K ? int csize = (stamp != null) ? 1024 * 6 : 1024 * 2; Hashtable exc = new Hashtable(); exc[PdfName.CONTENTS] = csize * 2 + 2; sap.PreClose(exc); // compute hash based on PDF bytes byte[] digest = ComputeHash(estEidReader, sap); statusHandler(Resources.ADD_SIGNATURE, false); // sign hash byte[] rsadata = EstEIDCardSign(estEidReader, signer, digest); // if null, user requested Cancel if (rsadata == null) { throw new Exception(Resources.CARD_INTERNAL_ERROR); } // create PKCS#7 envelope PdfPKCS7 pk7 = new PdfPKCS7(null, chain, null, "SHA1", true); pk7.SetExternalDigest(rsadata, digest, "RSA"); byte[] pk = pk7.GetEncodedPKCS7(); // user wants to add TSA response ? if (stamp != null && pk != null) { statusHandler(Resources.TSA_REQUEST, false); pk = TimestampAuthorityResponse(estEidReader, pk); } // PKCS#7 bytes too large ? if (pk.Length >= csize) { throw new Exception(Resources.MEMORY_ERROR); } byte[] outc = new byte[csize]; PdfDictionary dic2 = new PdfDictionary(); Array.Copy(pk, 0, outc, 0, pk.Length); dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); sap.Close(dic2); }
public bool Sign(string iSignReason, string iSignContact, string iSignLocation, bool visible, string iImageString) { string vCertificatesPath = "CN=" + CertificatesName; #region Geting Certs X509Store store = new X509Store(_storedName, _storedLocation); StorePermission sp = new StorePermission(PermissionState.Unrestricted); sp.Flags = StorePermissionFlags.OpenStore; sp.Assert(); store.Open(OpenFlags.MaxAllowed); X509Certificate2 cert = null; int i = 0; while ((i < store.Certificates.Count) && (cert == null)) { if (store.Certificates[i].Subject.ToUpper().Contains(vCertificatesPath)) { cert = store.Certificates[i]; } else { i++; } } store.Close(); if (cert == null) { throw new CryptographicException("Certificate is NULL. Certificate can not be found"); } Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser(); var cerRawData = cert.RawData; var certificates = cp.ReadCertificate(cerRawData); Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { certificates }; var chainFirst = GetChainBouncyCastle(cert); #endregion Geting Certs PdfReader reader = null; if (string.IsNullOrEmpty(inputPdfFileString)) { reader = new PdfReader(inputPdfStream); } else { reader = new PdfReader(this.inputPdfFileString); } if (outputPdfStream == null && string.IsNullOrEmpty(outputPdfFileString) == false) { outputPdfStream = new FileStream(this.outputPdfFileString, FileMode.OpenOrCreate, FileAccess.Write); } if (reader != null && outputPdfStream != null) { #region Standard Signing PdfStamper vStamper = PdfStamper.CreateSignature(reader, outputPdfStream, '\0', null, false); vStamper.MoreInfo = this.settingMetadata.GetMetaDataHashtable(); vStamper.XmpMetadata = this.settingMetadata.GetStreamedMetaData(); PdfSignatureAppearance vSignatureAppearance = vStamper.SignatureAppearance; vSignatureAppearance.SetCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED); vSignatureAppearance.SignDate = SignDate; vSignatureAppearance.Reason = iSignReason; vSignatureAppearance.Contact = iSignContact; vSignatureAppearance.Location = iSignLocation; vSignatureAppearance.Acro6Layers = true; vSignatureAppearance.Render = PdfSignatureAppearance.SignatureRender.Description; if (visible) { vSignatureAppearance.SetVisibleSignature( new iTextSharp.text.Rectangle(ImageLocation.Width, ImageLocation.Height, ImageLocation.Width + ImageSize.Width, ImageLocation.Height + ImageSize.Height), 1, null); if (File.Exists(iImageString)) { iTextSharp.text.Image vImage = iTextSharp.text.Image.GetInstance(iImageString); vSignatureAppearance.Image = vImage; } } vSignatureAppearance.SetExternalDigest(new byte[128], new byte[20], "RSA"); #endregion Standard Signing #region Self Signed Mode PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1); dic.Date = new PdfDate(vSignatureAppearance.SignDate); var vName = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"); dic.Name = vName; if (vSignatureAppearance.Reason != null) { dic.Reason = vSignatureAppearance.Reason; } if (vSignatureAppearance.Location != null) { dic.Location = vSignatureAppearance.Location; } vSignatureAppearance.CryptoDictionary = dic; int csize = 4000; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = csize * 2 + 2; vSignatureAppearance.PreClose(new Hashtable(exc)); HashAlgorithm sha = new SHA1CryptoServiceProvider(); Stream s = vSignatureAppearance.RangeStream; int read = 0; byte[] buff = new byte[8192]; while ((read = s.Read(buff, 0, 8192)) > 0) { sha.TransformBlock(buff, 0, read, buff, 0); } sha.TransformFinalBlock(buff, 0, 0); byte[] pk = SignMsg(sha.Hash, cert, false); byte[] outc = new byte[csize]; PdfDictionary dic2 = new PdfDictionary(); Array.Copy(pk, 0, outc, 0, pk.Length); dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); vSignatureAppearance.Close(dic2); #endregion Self Signed Mode if (vSignatureAppearance.IsPreClosed() == false) { vStamper.Close(); } reader.Close(); return(true); } return(false); }