Example #1
0
        private static void VerifyArguments(XmlSignatureAppearance sap, IExternalSignature externalSignature)
        {
            if (sap.GetXmlLocator() == null)
            {
                throw new DocumentException(MessageLocalization.GetComposedMessage("xmllocator.cannot.be.null"));
            }
            if (!externalSignature.GetHashAlgorithm().Equals(SecurityConstants.SHA1))
            {
                throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("support.only.sha1.hash.algorithm"));
            }

            if (!externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.RSA) &&
                !externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.DSA))
            {
                throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("support.only.rsa.and.dsa.algorithms"));
            }
        }
        /**
         * Signs the xml using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param keyInfo KeyInfo for verification
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        //public static void SignXmlDSig(XmlSignatureAppearance sap, IExternalSignature externalSignature, KeyInfoClause keyInfo) {

        //    VerifyArguments(sap, externalSignature);
        //    List<XmlElement> references = new List<XmlElement>(1);
        //    references.Add(GenerateContentReference(sap.GetXmlLocator().GetDocument(), sap, null));
                
        //    XmlElement signature = GenerateSignatureElement(sap.GetXmlLocator(), null, false);
        //    Sign(signature, sap.GetXmlLocator(), externalSignature, references, null, keyInfo);
        //    sap.Close();    
        //}

        /**
         * Signs the xml with XAdES BES using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param chain the certificate chain
         * @param includeSignaturePolicy if true SignaturePolicyIdentifier will be included (XAdES-EPES)
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        //public static void SignXades(XmlSignatureAppearance sap, IExternalSignature externalSignature, X509Certificate[] chain,
        //    bool includeSignaturePolicy) {

        //    VerifyArguments(sap, externalSignature);
        //    String contentReferenceId = SecurityConstants.Reference_ + GetRandomId();
        //    String signedPropertiesId = SecurityConstants.SignedProperties_ + GetRandomId();
        //    String signatureId = SecurityConstants.Signature_ + GetRandomId();

        //    XmlDocument doc = sap.GetXmlLocator().GetDocument();
        //    KeyInfoClause keyInfo = GenerateKeyInfo(chain, sap);
        //    List<XmlElement> references = new List<XmlElement>(2);
            
        //    XmlElement signature = GenerateSignatureElement(sap.GetXmlLocator(), signatureId, true);
        //    String[] signaturePolicy = null;
        //    if(includeSignaturePolicy) {
        //        signaturePolicy = new String[2];
        //        if(externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.RSA)) {
        //            signaturePolicy[0] = SecurityConstants.OID_RSA_SHA1;
        //            signaturePolicy[1] = SecurityConstants.OID_RSA_SHA1_DESC;
        //        }
        //        else {
        //            signaturePolicy[0] = SecurityConstants.OID_DSA_SHA1;
        //            signaturePolicy[1] = SecurityConstants.OID_DSA_SHA1_DESC;
        //        }
        //    }

        //    XmlElement signedProperty;
        //    XmlElement dsObject = GenerateXadesObject(sap, signatureId, contentReferenceId, signedPropertiesId, signaturePolicy, out signedProperty);
            
        //    references.Add(GenerateCustomReference(doc, signedProperty, "#" + signedPropertiesId, SecurityConstants.SignedProperties_Type, null));
        //    references.Add(GenerateContentReference(doc, sap, contentReferenceId));

        //    Sign(signature, sap.GetXmlLocator(), externalSignature, references, dsObject, keyInfo);

        //    sap.Close();
        //}

        /**
         * Signs the xml with XAdES BES using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param chain the certificate chain
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        //public static void SignXadesBes(XmlSignatureAppearance sap, IExternalSignature externalSignature, X509Certificate[] chain) {
        //    SignXades(sap, externalSignature, chain, false);
        //}

        /**
         * Signs the xml with XAdES BES using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param chain the certificate chain
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        //public static void SignXadesEpes(XmlSignatureAppearance sap, IExternalSignature externalSignature, X509Certificate[] chain) {
        //    SignXades(sap, externalSignature, chain, true);
        //}

        /**
         * Signs the xml using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param chain the certificate chain
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        //public static void SignXmlDSig(XmlSignatureAppearance sap,
        //    IExternalSignature externalSignature, X509Certificate[] chain) {
        //    SignXmlDSig(sap, externalSignature, new KeyInfoX509Data(chain[0].GetEncoded()));
        //}

        /**
         * Signs the xml using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param publicKey PublicKey for verification
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        //public static void SignXmlDSig(XmlSignatureAppearance sap,
        //    IExternalSignature externalSignature, AsymmetricAlgorithm publicKey) {
        //    SignXmlDSig(sap, externalSignature, GenerateKeyInfo(publicKey));
        //}

        private static void VerifyArguments(XmlSignatureAppearance sap, IExternalSignature externalSignature) {
            if (sap.GetXmlLocator() == null)
                throw new DocumentException(MessageLocalization.GetComposedMessage("xmllocator.cannot.be.null"));
            if (!externalSignature.GetHashAlgorithm().Equals(SecurityConstants.SHA1))
                throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("support.only.sha1.hash.algorithm"));

            if (!externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.RSA)
                && !externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.DSA))
                throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("support.only.rsa.and.dsa.algorithms"));
        }
        /**
         * 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);
        }
Example #5
0
        /// <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;
        }