// // the actual LTV enabling methods // void addLtvForChain(X509Certificate certificate, IOcspClient ocspClient, ICrlClient crlClient, PdfName key) { if (seenCertificates.Contains(certificate)) { return; } seenCertificates.Add(certificate); ValidationData validationData = new ValidationData(); while (certificate != null) { // Console.WriteLine(certificate.SubjectDN); X509Certificate issuer = getIssuerCertificate(certificate); validationData.certs.Add(certificate.GetEncoded()); byte[] ocspResponse = ocspClient.GetEncoded(certificate, issuer, null); if (ocspResponse != null) { // Console.WriteLine(" with OCSP response"); validationData.ocsps.Add(ocspResponse); X509Certificate ocspSigner = getOcspSignerCertificate(ocspResponse); ////if (ocspSigner != null) ////{ //// Console.WriteLine(" signed by {0}\n", ocspSigner.SubjectDN); ////} addLtvForChain(ocspSigner, ocspClient, crlClient, getOcspHashKey(ocspResponse)); } else { ICollection <byte[]> crl = crlClient.GetEncoded(certificate, null); if (crl != null && crl.Count > 0) { //Console.WriteLine(" with {0} CRLs\n", crl.Count); foreach (byte[] crlBytes in crl) { validationData.crls.Add(crlBytes); addLtvForChain(null, ocspClient, crlClient, getCrlHashKey(crlBytes)); } } } certificate = issuer; } validated[key] = validationData; }
/** * Add verification for a particular signature * @param signatureName the signature to validate (it may be a timestamp) * @param ocsp the interface to get the OCSP * @param crl the interface to get the CRL * @param certOption * @param level the validation options to include * @param certInclude * @return true if a validation was generated, false otherwise * @throws Exception */ virtual public bool AddVerification(String signatureName, IOcspClient ocsp, ICrlClient crl, CertificateOption certOption, Level level, CertificateInclusion certInclude) { if (used) throw new InvalidOperationException(MessageLocalization.GetComposedMessage("verification.already.output")); PdfPKCS7 pk = acroFields.VerifySignature(signatureName); LOGGER.Info("Adding verification for " + signatureName); X509Certificate[] xc = pk.Certificates; X509Certificate cert; X509Certificate signingCert = pk.SigningCertificate; ValidationData vd = new ValidationData(); for (int k = 0; k < xc.Length; ++k) { cert = xc[k]; LOGGER.Info("Certificate: " + cert.SubjectDN); if (certOption == CertificateOption.SIGNING_CERTIFICATE && !cert.Equals(signingCert)) { continue; } byte[] ocspEnc = null; if (ocsp != null && level != Level.CRL) { ocspEnc = ocsp.GetEncoded(cert, GetParent(cert, xc), null); if (ocspEnc != null) { vd.ocsps.Add(BuildOCSPResponse(ocspEnc)); LOGGER.Info("OCSP added"); } } if (crl != null && (level == Level.CRL || level == Level.OCSP_CRL || (level == Level.OCSP_OPTIONAL_CRL && ocspEnc == null))) { ICollection<byte[]> cims = crl.GetEncoded(xc[k], null); if (cims != null) { foreach (byte[] cim in cims) { bool dup = false; foreach (byte[] b in vd.crls) { if (Arrays.AreEqual(b, cim)) { dup = true; break; } } if (!dup) { vd.crls.Add(cim); LOGGER.Info("CRL added"); } } } } if (certInclude == CertificateInclusion.YES) { vd.certs.Add(xc[k].GetEncoded()); } } if (vd.crls.Count == 0 && vd.ocsps.Count == 0) return false; validated[GetSignatureHashKey(signatureName)] = vd; return true; }
/** * Signs the document using the detached mode, CMS or CAdES equivalent. * @param sap the PdfSignatureAppearance * @param externalSignature the interface providing the actual signing * @param chain the certificate chain * @param crlList the CRL list * @param ocspClient the OCSP client * @param tsaClient the Timestamp client * @param provider the provider or null * @param estimatedSize the reserved size for the signature. It will be estimated if 0 * @param cades true to sign CAdES equivalent PAdES-BES, false to sign CMS * @throws DocumentException * @throws IOException * @throws GeneralSecurityException * @throws NoSuchAlgorithmException * @throws Exception */ public static void SignDetached(PdfSignatureAppearance sap, IExternalSignature externalSignature, ICollection<X509Certificate> chain, ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, CryptoStandard sigtype) { List<X509Certificate> certa = new List<X509Certificate>(chain); ICollection<byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < certa.Count) crlBytes = ProcessCrl(certa[i++], crlList); if (estimatedSize == 0) { estimatedSize = 8192; if (crlBytes != null) { foreach (byte[] element in crlBytes) { estimatedSize += element.Length + 10; } } if (ocspClient != null) estimatedSize += 4192; if (tsaClient != null) estimatedSize += 4192; } sap.Certificate = certa[0]; if(sigtype == CryptoStandard.CADES) sap.AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL2); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, sigtype == CryptoStandard.CADES ? PdfName.ETSI_CADES_DETACHED : PdfName.ADBE_PKCS7_DETACHED); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.SignatureCreator = sap.SignatureCreator; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this sap.CryptoDictionary = dic; Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); DateTime cal = DateTime.Now; byte[] ocsp = null; if (chain.Count >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded(certa[0], certa[1], null); } byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize < encodedSig.Length) throw new IOException("Not enough space"); byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs the document using the detached mode, CMS or CAdES equivalent. * @param sap the PdfSignatureAppearance * @param externalSignature the interface providing the actual signing * @param chain the certificate chain * @param crlList the CRL list * @param ocspClient the OCSP client * @param tsaClient the Timestamp client * @param provider the provider or null * @param estimatedSize the reserved size for the signature. It will be estimated if 0 * @param cades true to sign CAdES equivalent PAdES-BES, false to sign CMS * @throws DocumentException * @throws IOException * @throws GeneralSecurityException * @throws NoSuchAlgorithmException * @throws Exception */ public static void SignDetached(PdfSignatureAppearance sap, IExternalSignature externalSignature, ICollection <X509Certificate> chain, ICollection <ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, CryptoStandard sigtype) { List <X509Certificate> certa = new List <X509Certificate>(chain); ICollection <byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < certa.Count) { crlBytes = ProcessCrl(certa[i++], crlList); } if (estimatedSize == 0) { estimatedSize = 8192; if (crlBytes != null) { foreach (byte[] element in crlBytes) { estimatedSize += element.Length + 10; } } if (ocspClient != null) { estimatedSize += 4192; } if (tsaClient != null) { estimatedSize += 4192; } } sap.Certificate = certa[0]; PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, sigtype == CryptoStandard.CADES ? PdfName.ETSI_CADES_DETACHED : PdfName.ADBE_PKCS7_DETACHED); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); DateTime cal = DateTime.Now; byte[] ocsp = null; if (chain.Count >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded(certa[0], certa[1], null); } byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize + 2 < encodedSig.Length) { throw new IOException("Not enough space"); } byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Add verification for a particular signature * @param signatureName the signature to validate (it may be a timestamp) * @param ocsp the interface to get the OCSP * @param crl the interface to get the CRL * @param certOption * @param level the validation options to include * @param certInclude * @return true if a validation was generated, false otherwise * @throws Exception */ public bool AddVerification(String signatureName, IOcspClient ocsp, ICrlClient crl, CertificateOption certOption, Level level, CertificateInclusion certInclude) { if (used) { throw new InvalidOperationException(MessageLocalization.GetComposedMessage("verification.already.output")); } PdfPKCS7 pk = acroFields.VerifySignature(signatureName); LOGGER.Info("Adding verification for " + signatureName); X509Certificate[] xc = pk.Certificates; X509Certificate cert; X509Certificate signingCert = pk.SigningCertificate; ValidationData vd = new ValidationData(); for (int k = 0; k < xc.Length; ++k) { cert = xc[k]; LOGGER.Info("Certificate: " + cert.SubjectDN); if (certOption == CertificateOption.SIGNING_CERTIFICATE && !cert.Equals(signingCert)) { continue; } byte[] ocspEnc = null; if (ocsp != null && level != Level.CRL) { ocspEnc = ocsp.GetEncoded(cert, GetParent(cert, xc), null); if (ocspEnc != null) { vd.ocsps.Add(BuildOCSPResponse(ocspEnc)); LOGGER.Info("OCSP added"); } } if (crl != null && (level == Level.CRL || level == Level.OCSP_CRL || (level == Level.OCSP_OPTIONAL_CRL && ocspEnc == null))) { ICollection <byte[]> cims = crl.GetEncoded(xc[k], null); if (cims != null) { foreach (byte[] cim in cims) { bool dup = false; foreach (byte[] b in vd.crls) { if (Arrays.AreEqual(b, cim)) { dup = true; break; } } if (!dup) { vd.crls.Add(cim); LOGGER.Info("CRL added"); } } } } if (certInclude == CertificateInclusion.YES) { vd.certs.Add(xc[k].GetEncoded()); } } if (vd.crls.Count == 0 && vd.ocsps.Count == 0) { return(false); } validated[GetSignatureHashKey(signatureName)] = vd; return(true); }
/** * Add verification for a particular signature * @param signatureName the signature to validate (it may be a timestamp) * @param ocsp the interface to get the OCSP * @param crl the interface to get the CRL * @param certOption * @param level the validation options to include * @param certInclude * @return true if a validation was generated, false otherwise * @throws Exception */ public bool AddVerification(String signatureName, IOcspClient ocsp, ICrlClient crl, CertificateOption certOption, Level level, CertificateInclusion certInclude) { if (used) throw new InvalidOperationException(MessageLocalization.GetComposedMessage("verification.already.output")); PdfPKCS7 pk = acroFields.VerifySignature(signatureName); X509Certificate[] xc = pk.SignCertificateChain; ValidationData vd = new ValidationData(); for (int k = 0; k < xc.Length; ++k) { byte[] ocspEnc = null; if (ocsp != null && level != Level.CRL && k < xc.Length - 1) { ocspEnc = ocsp.GetEncoded(xc[k], xc[k + 1], null); if (ocspEnc != null) vd.ocsps.Add(BuildOCSPResponse(ocspEnc)); } if (crl != null && (level == Level.CRL || level == Level.OCSP_CRL || (level == Level.OCSP_OPTIONAL_CRL && ocspEnc == null))) { byte[] cim = crl.GetEncoded(xc[k], null); if (cim != null) { bool dup = false; foreach (byte[] b in vd.crls) { if (Arrays.AreEqual(b, cim)) { dup = true; break; } } if (!dup) vd.crls.Add(cim); } } if (certOption == CertificateOption.SIGNING_CERTIFICATE) break; } if (vd.crls.Count == 0 && vd.ocsps.Count == 0) return false; if (certInclude == CertificateInclusion.YES) { foreach (X509Certificate c in xc) { vd.certs.Add(c.GetEncoded()); } } validated[GetSignatureHashKey(signatureName)] = vd; return true; }
/// <summary>Signs the document using the detached mode, CMS or CAdES equivalent.</summary> /// <remarks> /// Signs the document using the detached mode, CMS or CAdES equivalent. /// <br /><br /> /// NOTE: This method closes the underlying pdf document. This means, that current instance /// of PdfSigner cannot be used after this method call. /// </remarks> /// <param name="externalSignature">the interface providing the actual signing</param> /// <param name="chain">the certificate chain</param> /// <param name="crlList">the CRL list</param> /// <param name="ocspClient">the OCSP client</param> /// <param name="tsaClient">the Timestamp client</param> /// <param name="externalDigest">an implementation that provides the digest</param> /// <param name="estimatedSize">the reserved size for the signature. It will be estimated if 0</param> /// <param name="sigtype">Either Signature.CMS or Signature.CADES</param> /// <exception cref="System.IO.IOException"/> /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/> public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain, ICollection <ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, PdfSigner.CryptoStandard sigtype) { if (closed) { throw new PdfException(PdfException.ThisInstanceOfPdfSignerAlreadyClosed); } ICollection <byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < chain.Length) { crlBytes = ProcessCrl(chain[i++], crlList); } if (estimatedSize == 0) { estimatedSize = 8192; if (crlBytes != null) { foreach (byte[] element in crlBytes) { estimatedSize += element.Length + 10; } } if (ocspClient != null) { estimatedSize += 4192; } if (tsaClient != null) { estimatedSize += 4192; } } PdfSignatureAppearance appearance = GetSignatureAppearance(); appearance.SetCertificate(chain[0]); if (sigtype == PdfSigner.CryptoStandard.CADES) { AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL2); } PdfSignature dic = new PdfSignature(PdfName.Adobe_PPKLite, sigtype == PdfSigner.CryptoStandard.CADES ? PdfName .ETSI_CAdES_DETACHED : PdfName.Adbe_pkcs7_detached); dic.SetReason(appearance.GetReason()); dic.SetLocation(appearance.GetLocation()); dic.SetSignatureCreator(appearance.GetSignatureCreator()); dic.SetContact(appearance.GetContact()); dic.SetDate(new PdfDate(GetSignDate())); // time-stamp will over-rule this cryptoDictionary = dic; IDictionary <PdfName, int?> exc = new Dictionary <PdfName, int?>(); exc[PdfName.Contents] = estimatedSize * 2 + 2; PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7((ICipherParameters)null, chain, hashAlgorithm, false); Stream data = GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, SignUtils.GetMessageDigest(hashAlgorithm)); byte[] ocsp = null; if (chain.Length >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded((X509Certificate)chain[0], (X509Certificate)chain[1], null); } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize < encodedSig.Length) { throw new System.IO.IOException("Not enough space"); } byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true)); Close(dic2); closed = true; }
/** * Add verification for a particular signature * @param signatureName the signature to validate (it may be a timestamp) * @param ocsp the interface to get the OCSP * @param crl the interface to get the CRL * @param certOption * @param level the validation options to include * @param certInclude * @return true if a validation was generated, false otherwise * @throws Exception */ public bool AddVerification(String signatureName, IOcspClient ocsp, ICrlClient crl, CertificateOption certOption, Level level, CertificateInclusion certInclude) { if (used) { throw new InvalidOperationException(MessageLocalization.GetComposedMessage("verification.already.output")); } PdfPKCS7 pk = acroFields.VerifySignature(signatureName); X509Certificate[] xc = pk.SignCertificateChain; ValidationData vd = new ValidationData(); for (int k = 0; k < xc.Length; ++k) { byte[] ocspEnc = null; if (ocsp != null && level != Level.CRL && k < xc.Length - 1) { ocspEnc = ocsp.GetEncoded(xc[k], xc[k + 1], null); if (ocspEnc != null) { vd.ocsps.Add(BuildOCSPResponse(ocspEnc)); } } if (crl != null && (level == Level.CRL || level == Level.OCSP_CRL || (level == Level.OCSP_OPTIONAL_CRL && ocspEnc == null))) { ICollection <byte[]> cims = crl.GetEncoded((X509Certificate)xc[k], null); if (cims != null) { foreach (byte[] cim in cims) { bool dup = false; foreach (byte[] b in vd.crls) { if (Arrays.AreEqual(b, cim)) { dup = true; break; } } if (!dup) { vd.crls.Add(cim); } } } } if (certOption == CertificateOption.SIGNING_CERTIFICATE) { break; } } if (vd.crls.Count == 0 && vd.ocsps.Count == 0) { return(false); } if (certInclude == CertificateInclusion.YES) { foreach (X509Certificate c in xc) { vd.certs.Add(c.GetEncoded()); } } validated[GetSignatureHashKey(signatureName)] = vd; return(true); }
/// <summary>Add verification for a particular signature.</summary> /// <param name="signatureName">the signature to validate (it may be a timestamp)</param> /// <param name="ocsp">the interface to get the OCSP</param> /// <param name="crl">the interface to get the CRL</param> /// <param name="certOption">options as to how many certificates to include</param> /// <param name="level">the validation options to include</param> /// <param name="certInclude">certificate inclusion options</param> /// <returns>true if a validation was generated, false otherwise</returns> /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/> /// <exception cref="System.IO.IOException"/> public virtual bool AddVerification(String signatureName, IOcspClient ocsp, ICrlClient crl, LtvVerification.CertificateOption certOption, LtvVerification.Level level, LtvVerification.CertificateInclusion certInclude) { if (used) { throw new InvalidOperationException(PdfException.VerificationAlreadyOutput); } PdfPKCS7 pk = sgnUtil.VerifySignature(signatureName); LOGGER.Info("Adding verification for " + signatureName); X509Certificate[] xc = pk.GetCertificates(); X509Certificate cert; X509Certificate signingCert = pk.GetSigningCertificate(); LtvVerification.ValidationData vd = new LtvVerification.ValidationData(); for (int k = 0; k < xc.Length; ++k) { cert = (X509Certificate)xc[k]; LOGGER.Info("Certificate: " + cert.SubjectDN); if (certOption == LtvVerification.CertificateOption.SIGNING_CERTIFICATE && !cert.Equals(signingCert)) { continue; } byte[] ocspEnc = null; if (ocsp != null && level != LtvVerification.Level.CRL) { ocspEnc = ocsp.GetEncoded(cert, GetParent(cert, xc), null); if (ocspEnc != null) { vd.ocsps.Add(BuildOCSPResponse(ocspEnc)); LOGGER.Info("OCSP added"); } } if (crl != null && (level == LtvVerification.Level.CRL || level == LtvVerification.Level.OCSP_CRL || (level == LtvVerification.Level.OCSP_OPTIONAL_CRL && ocspEnc == null))) { ICollection <byte[]> cims = crl.GetEncoded(cert, null); if (cims != null) { foreach (byte[] cim in cims) { bool dup = false; foreach (byte[] b in vd.crls) { if (JavaUtil.ArraysEquals(b, cim)) { dup = true; break; } } if (!dup) { vd.crls.Add(cim); LOGGER.Info("CRL added"); } } } } if (certInclude == LtvVerification.CertificateInclusion.YES) { vd.certs.Add(cert.GetEncoded()); } } if (vd.crls.Count == 0 && vd.ocsps.Count == 0) { return(false); } validated.Put(GetSignatureHashKey(signatureName), vd); return(true); }