Ejemplo n.º 1
0
 /// <summary>Verifies a certificate against a single OCSP response</summary>
 /// <param name="ocspResp">the OCSP response</param>
 /// <param name="signCert">the certificate that needs to be checked</param>
 /// <param name="issuerCert">the certificate of CA</param>
 /// <param name="signDate">sign date</param>
 /// <returns>
 ///
 /// <see langword="true"/>
 /// , in case successful check, otherwise false.
 /// </returns>
 /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/>
 /// <exception cref="System.IO.IOException"/>
 public virtual bool Verify(BasicOcspResp ocspResp, X509Certificate signCert, X509Certificate issuerCert, DateTime
                            signDate)
 {
     if (ocspResp == null)
     {
         return(false);
     }
     // Getting the responses
     SingleResp[] resp = ocspResp.Responses;
     for (int i = 0; i < resp.Length; i++)
     {
         // check if the serial number corresponds
         if (!signCert.SerialNumber.Equals(resp[i].GetCertID().SerialNumber))
         {
             continue;
         }
         // check if the issuer matches
         try {
             if (issuerCert == null)
             {
                 issuerCert = signCert;
             }
             if (!SignUtils.CheckIfIssuersMatch(resp[i].GetCertID(), issuerCert))
             {
                 LOGGER.Info("OCSP: Issuers doesn't match.");
                 continue;
             }
         }
         catch (OcspException) {
             continue;
         }
         // check if the OCSP response was valid at the time of signing
         if (resp[i].NextUpdate == null)
         {
             DateTime nextUpdate = SignUtils.Add180Sec(resp[i].ThisUpdate);
             LOGGER.Info(MessageFormatUtil.Format("No 'next update' for OCSP Response; assuming {0}", nextUpdate));
             if (signDate.After(nextUpdate))
             {
                 LOGGER.Info(MessageFormatUtil.Format("OCSP no longer valid: {0} after {1}", signDate, nextUpdate));
                 continue;
             }
         }
         else
         {
             if (signDate.After(resp[i].NextUpdate))
             {
                 LOGGER.Info(MessageFormatUtil.Format("OCSP no longer valid: {0} after {1}", signDate, resp[i].NextUpdate));
                 continue;
             }
         }
         // check the status of the certificate
         Object status = resp[i].GetCertStatus();
         if (status == CertificateStatus.Good)
         {
             // check if the OCSP response was genuine
             IsValidResponse(ocspResp, issuerCert);
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Verifies if an OCSP response is genuine
        /// If it doesn't verify against the issuer certificate and response's certificates, it may verify
        /// using a trusted anchor or cert.
        /// </summary>
        /// <param name="ocspResp">the OCSP response</param>
        /// <param name="issuerCert">the issuer certificate</param>
        /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/>
        /// <exception cref="System.IO.IOException"/>
        public virtual void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert)
        {
            //OCSP response might be signed by the issuer certificate or
            //the Authorized OCSP responder certificate containing the id-kp-OCSPSigning extended key usage extension
            X509Certificate responderCert = null;

            //first check if the issuer certificate signed the response
            //since it is expected to be the most common case
            if (IsSignatureValid(ocspResp, issuerCert))
            {
                responderCert = issuerCert;
            }
            //if the issuer certificate didn't sign the ocsp response, look for authorized ocsp responses
            // from properties or from certificate chain received with response
            if (responderCert == null)
            {
                if (ocspResp.GetCerts() != null)
                {
                    //look for existence of Authorized OCSP responder inside the cert chain in ocsp response
                    IEnumerable <X509Certificate> certs = SignUtils.GetCertsFromOcspResponse(ocspResp);
                    foreach (X509Certificate cert in certs)
                    {
                        IList keyPurposes = null;
                        try {
                            keyPurposes = cert.GetExtendedKeyUsage();
                            if ((keyPurposes != null) && keyPurposes.Contains(id_kp_OCSPSigning) && IsSignatureValid(ocspResp, cert))
                            {
                                responderCert = cert;
                                break;
                            }
                        }
                        catch (CertificateParsingException) {
                        }
                    }
                    // Certificate signing the ocsp response is not found in ocsp response's certificate chain received
                    // and is not signed by the issuer certificate.
                    if (responderCert == null)
                    {
                        throw new VerificationException(issuerCert, "OCSP response could not be verified");
                    }
                }
                else
                {
                    //certificate chain is not present in response received
                    //try to verify using rootStore
                    if (rootStore != null)
                    {
                        try {
                            foreach (X509Certificate anchor in SignUtils.GetCertificates(rootStore))
                            {
                                if (IsSignatureValid(ocspResp, anchor))
                                {
                                    responderCert = anchor;
                                    break;
                                }
                            }
                        }
                        catch (Exception) {
                            responderCert = (X509Certificate)null;
                        }
                    }
                    // OCSP Response does not contain certificate chain, and response is not signed by any
                    // of the rootStore or the issuer certificate.
                    if (responderCert == null)
                    {
                        throw new VerificationException(issuerCert, "OCSP response could not be verified");
                    }
                }
            }
            //check "This certificate MUST be issued directly by the CA that issued the certificate in question".
            responderCert.Verify(issuerCert.GetPublicKey());
            // validating ocsp signers certificate
            // Check if responders certificate has id-pkix-ocsp-nocheck extension,
            // in which case we do not validate (perform revocation check on) ocsp certs for lifetime of certificate
            if (responderCert.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNocheck.Id) == null)
            {
                X509Crl crl;
                try {
                    crl = CertificateUtil.GetCRL(responderCert);
                }
                catch (Exception) {
                    crl = (X509Crl)null;
                }
                if (crl != null && crl is X509Crl)
                {
                    CRLVerifier crlVerifier = new CRLVerifier(null, null);
                    crlVerifier.SetRootStore(rootStore);
                    crlVerifier.SetOnlineCheckingAllowed(onlineCheckingAllowed);
                    crlVerifier.Verify((X509Crl)crl, responderCert, issuerCert, DateTimeUtil.GetCurrentUtcTime());
                    return;
                }
            }
            //check if lifetime of certificate is ok
            responderCert.CheckValidity();
        }
Ejemplo n.º 3
0
 /// <summary>Creates a MessageDigest object that can be used to create a hash.</summary>
 /// <param name="hashAlgorithm">the algorithm you want to use to create a hash</param>
 /// <param name="provider">the provider you want to use to create the hash</param>
 /// <returns>a MessageDigest object</returns>
 /// <exception cref="Org.BouncyCastle.Security.SecurityUtilityException"/>
 /// <exception cref="Java.Security.NoSuchProviderException"/>
 public static IDigest GetMessageDigest(String hashAlgorithm)
 {
     return(SignUtils.GetMessageDigest(hashAlgorithm));
 }
Ejemplo n.º 4
0
 public void CertificateIsNullTest()
 {
     NUnit.Framework.Assert.That(() => {
         SignUtils.HasUnsupportedCriticalExtension(null);
     }, NUnit.Framework.Throws.TypeOf <ArgumentException>());;
 }
Ejemplo n.º 5
0
 /// <summary>Gets the MessageDigest to digest the data imprint</summary>
 /// <returns>the digest algorithm name</returns>
 /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/>
 public virtual IDigest GetMessageDigest()
 {
     return(SignUtils.GetMessageDigest(digestAlgorithm));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates a
 /// <see cref="PrivateKeySignature"/>
 /// instance.
 /// </summary>
 /// <param name="pk">
 /// A
 /// <see cref="Org.BouncyCastle.Crypto.ICipherParameters"/>
 /// object.
 /// </param>
 /// <param name="hashAlgorithm">A hash algorithm (e.g. "SHA-1", "SHA-256",...).</param>
 /// <param name="provider">A security provider (e.g. "BC").</param>
 public PrivateKeySignature(ICipherParameters pk, String hashAlgorithm)
 {
     this.pk                  = pk;
     this.hashAlgorithm       = DigestAlgorithms.GetDigest(DigestAlgorithms.GetAllowedDigest(hashAlgorithm));
     this.encryptionAlgorithm = SignUtils.GetPrivateKeyAlgorithm(pk);
 }
Ejemplo n.º 7
0
        internal virtual SignaturePolicyIdentifier ToSignaturePolicyIdentifier()
        {
            String algId = DigestAlgorithms.GetAllowedDigest(this.policyDigestAlgorithm);

            if (algId == null || algId.Length == 0)
            {
                throw new ArgumentException("Invalid policy hash algorithm");
            }
            SignaturePolicyIdentifier signaturePolicyIdentifier = null;
            SigPolicyQualifierInfo    spqi = null;

            if (this.policyUri != null && this.policyUri.Length > 0)
            {
                spqi = new SigPolicyQualifierInfo(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdSpqEtsUri, new DerIA5String
                                                      (this.policyUri));
            }
            signaturePolicyIdentifier = new SignaturePolicyIdentifier(new SignaturePolicyId(DerObjectIdentifier.GetInstance
                                                                                                (new DerObjectIdentifier(this.policyIdentifier.Replace("urn:oid:", ""))), new OtherHashAlgAndValue(new
                                                                                                                                                                                                   AlgorithmIdentifier(new DerObjectIdentifier(algId)), new DerOctetString(this.policyHash)), SignUtils.CreateSigPolicyQualifiers
                                                                                                (spqi)));
            return(signaturePolicyIdentifier);
        }
Ejemplo n.º 8
0
        /// <summary>Constructs appearance (top-level) for a signature.</summary>
        /// <remarks>
        /// Constructs appearance (top-level) for a signature.
        /// <p>
        /// Consult <A HREF="http://partners.adobe.com/asn/developer/pdfs/tn/PPKAppearances.pdf">PPKAppearances.pdf</A>
        /// for further details.
        /// </remarks>
        /// <returns>a top-level signature appearance</returns>
        /// <exception cref="System.IO.IOException"/>
        protected internal virtual PdfFormXObject GetAppearance()
        {
            PdfCanvas canvas;

            if (IsInvisible())
            {
                PdfFormXObject appearance = new PdfFormXObject(new Rectangle(0, 0));
                appearance.MakeIndirect(document);
                return(appearance);
            }
            if (n0 == null && !reuseAppearance)
            {
                CreateBlankN0();
            }
            if (n2 == null)
            {
                n2 = new PdfFormXObject(rect);
                n2.MakeIndirect(document);
                String text;
                if (layer2Text == null)
                {
                    StringBuilder buf = new StringBuilder();
                    buf.Append("Digitally signed by ");
                    String name = null;
                    CertificateInfo.X500Name x500name = CertificateInfo.GetSubjectFields((X509Certificate)signCertificate);
                    if (x500name != null)
                    {
                        name = x500name.GetField("CN");
                        if (name == null)
                        {
                            name = x500name.GetField("E");
                        }
                    }
                    if (name == null)
                    {
                        name = "";
                    }
                    buf.Append(name).Append('\n');
                    buf.Append("Date: ").Append(SignUtils.DateToString(signDate));
                    if (reason != null)
                    {
                        buf.Append('\n').Append(reasonCaption).Append(reason);
                    }
                    if (location != null)
                    {
                        buf.Append('\n').Append(locationCaption).Append(location);
                    }
                    text = buf.ToString();
                }
                else
                {
                    text = layer2Text;
                }
                if (image != null)
                {
                    if (imageScale == 0)
                    {
                        canvas = new PdfCanvas(n2, document);
                        canvas.AddImage(image, rect.GetWidth(), 0, 0, rect.GetHeight(), 0, 0);
                    }
                    else
                    {
                        float usableScale = imageScale;
                        if (imageScale < 0)
                        {
                            usableScale = Math.Min(rect.GetWidth() / image.GetWidth(), rect.GetHeight() / image.GetHeight());
                        }
                        float w = image.GetWidth() * usableScale;
                        float h = image.GetHeight() * usableScale;
                        float x = (rect.GetWidth() - w) / 2;
                        float y = (rect.GetHeight() - h) / 2;
                        canvas = new PdfCanvas(n2, document);
                        canvas.AddImage(image, w, 0, 0, h, x, y);
                    }
                }
                PdfFont font;
                if (layer2Font == null)
                {
                    font = PdfFontFactory.CreateFont();
                }
                else
                {
                    font = layer2Font;
                }
                Rectangle dataRect      = null;
                Rectangle signatureRect = null;
                if (renderingMode == PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION || renderingMode == PdfSignatureAppearance.RenderingMode
                    .GRAPHIC_AND_DESCRIPTION && this.signatureGraphic != null)
                {
                    if (rect.GetHeight() > rect.GetWidth())
                    {
                        signatureRect = new Rectangle(MARGIN, rect.GetHeight() / 2, rect.GetWidth() - 2 * MARGIN, rect.GetHeight()
                                                      / 2);
                        dataRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() / 2 - 2 * MARGIN);
                    }
                    else
                    {
                        // origin is the bottom-left
                        signatureRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() / 2 - 2 * MARGIN, rect.GetHeight() - 2 * MARGIN
                                                      );
                        dataRect = new Rectangle(rect.GetWidth() / 2 + MARGIN / 2, MARGIN, rect.GetWidth() / 2 - MARGIN, rect.GetHeight
                                                     () - 2 * MARGIN);
                    }
                }
                else
                {
                    if (renderingMode == PdfSignatureAppearance.RenderingMode.GRAPHIC)
                    {
                        if (signatureGraphic == null)
                        {
                            throw new InvalidOperationException("A signature image must be present when rendering mode is graphic. Use setSignatureGraphic()"
                                                                );
                        }
                        signatureRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() - 2 * MARGIN);
                    }
                    else
                    {
                        // take all space available
                        dataRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() * (1 - TOP_SECTION
                                                                                                                   ) - 2 * MARGIN);
                    }
                }
                switch (renderingMode)
                {
                case PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION: {
                    String signedBy = CertificateInfo.GetSubjectFields((X509Certificate)signCertificate).GetField("CN");
                    if (signedBy == null)
                    {
                        signedBy = CertificateInfo.GetSubjectFields((X509Certificate)signCertificate).GetField("E");
                    }
                    if (signedBy == null)
                    {
                        signedBy = "";
                    }
                    AddTextToCanvas(signedBy, font, signatureRect);
                    break;
                }

                case PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION: {
                    if (signatureGraphic == null)
                    {
                        throw new InvalidOperationException("A signature image must be present when rendering mode is graphic and description. Use setSignatureGraphic()"
                                                            );
                    }
                    float imgWidth = signatureGraphic.GetWidth();
                    if (imgWidth == 0)
                    {
                        imgWidth = signatureRect.GetWidth();
                    }
                    float imgHeight = signatureGraphic.GetHeight();
                    if (imgHeight == 0)
                    {
                        imgHeight = signatureRect.GetHeight();
                    }
                    float multiplierH = signatureRect.GetWidth() / signatureGraphic.GetWidth();
                    float multiplierW = signatureRect.GetHeight() / signatureGraphic.GetHeight();
                    float multiplier  = Math.Min(multiplierH, multiplierW);
                    imgWidth  *= multiplier;
                    imgHeight *= multiplier;
                    float x = signatureRect.GetRight() - imgWidth;
                    float y = signatureRect.GetBottom() + (signatureRect.GetHeight() - imgHeight) / 2;
                    canvas = new PdfCanvas(n2, document);
                    canvas.AddImage(signatureGraphic, imgWidth, 0, 0, imgHeight, x, y);
                    break;
                }

                case PdfSignatureAppearance.RenderingMode.GRAPHIC: {
                    float imgWidth_1 = signatureGraphic.GetWidth();
                    if (imgWidth_1 == 0)
                    {
                        imgWidth_1 = signatureRect.GetWidth();
                    }
                    float imgHeight_1 = signatureGraphic.GetHeight();
                    if (imgHeight_1 == 0)
                    {
                        imgHeight_1 = signatureRect.GetHeight();
                    }
                    float multiplierH_1 = signatureRect.GetWidth() / signatureGraphic.GetWidth();
                    float multiplierW_1 = signatureRect.GetHeight() / signatureGraphic.GetHeight();
                    float multiplier_1  = Math.Min(multiplierH_1, multiplierW_1);
                    imgWidth_1  *= multiplier_1;
                    imgHeight_1 *= multiplier_1;
                    float x_1 = signatureRect.GetLeft() + (signatureRect.GetWidth() - imgWidth_1) / 2;
                    float y_1 = signatureRect.GetBottom() + (signatureRect.GetHeight() - imgHeight_1) / 2;
                    canvas = new PdfCanvas(n2, document);
                    canvas.AddImage(signatureGraphic, imgWidth_1, 0, 0, imgHeight_1, x_1, y_1);
                    break;
                }
                }
                if (renderingMode != PdfSignatureAppearance.RenderingMode.GRAPHIC)
                {
                    AddTextToCanvas(text, font, dataRect);
                }
            }
            int       rotation = document.GetPage(page).GetRotation();
            Rectangle rotated  = new Rectangle(rect);

            if (topLayer == null)
            {
                topLayer = new PdfFormXObject(rotated);
                topLayer.MakeIndirect(document);
                canvas = new PdfCanvas(topLayer, document);
                if (rotation == 90)
                {
                    canvas.ConcatMatrix(0, 1, -1, 0, rect.GetHeight(), 0);
                }
                else
                {
                    if (rotation == 180)
                    {
                        canvas.ConcatMatrix(-1, 0, 0, -1, rect.GetWidth(), rect.GetHeight());
                    }
                    else
                    {
                        if (rotation == 270)
                        {
                            canvas.ConcatMatrix(0, -1, 1, 0, 0, rect.GetWidth());
                        }
                    }
                }
                if (reuseAppearance)
                {
                    PdfAcroForm    acroForm = PdfAcroForm.GetAcroForm(document, true);
                    PdfFormField   field    = acroForm.GetField(fieldName);
                    PdfStream      stream   = field.GetWidgets()[0].GetAppearanceDictionary().GetAsStream(PdfName.N);
                    PdfFormXObject xobj     = new PdfFormXObject(stream);
                    if (stream != null)
                    {
                        topLayer.GetResources().AddForm(xobj, new PdfName("n0"));
                        PdfCanvas canvas1 = new PdfCanvas(topLayer, document);
                        canvas1.AddXObject(xobj, 1, 0, 0, 1, 0, 0);
                    }
                    else
                    {
                        reuseAppearance = false;
                        if (n0 == null)
                        {
                            CreateBlankN0();
                        }
                    }
                }
                if (!reuseAppearance)
                {
                    topLayer.GetResources().AddForm(n0, new PdfName("n0"));
                    PdfCanvas canvas1 = new PdfCanvas(topLayer, document);
                    canvas1.AddXObject(n0, 1, 0, 0, 1, 0, 0);
                }
                topLayer.GetResources().AddForm(n2, new PdfName("n2"));
                PdfCanvas canvas1_1 = new PdfCanvas(topLayer, document);
                canvas1_1.AddXObject(n2, 1, 0, 0, 1, 0, 0);
            }
            PdfFormXObject napp = new PdfFormXObject(rotated);

            napp.MakeIndirect(document);
            napp.GetResources().AddForm(topLayer, new PdfName("FRM"));
            canvas = new PdfCanvas(napp, document);
            canvas.AddXObject(topLayer, 0, 0);
            return(napp);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Verifies if an OCSP response is genuine
        /// If it doesn't verify against the issuer certificate and response's certificates, it may verify
        /// using a trusted anchor or cert.
        /// </summary>
        /// <param name="ocspResp">the OCSP response</param>
        /// <param name="issuerCert">the issuer certificate. This certificate is considered trusted and valid by this method.
        ///     </param>
        /// <param name="signDate">sign date</param>
        public virtual void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert, DateTime signDate)
        {
            // OCSP response might be signed by the issuer certificate or
            // the Authorized OCSP responder certificate containing the id-kp-OCSPSigning extended key usage extension
            X509Certificate responderCert = null;

            // first check if the issuer certificate signed the response
            // since it is expected to be the most common case
            if (IsSignatureValid(ocspResp, issuerCert))
            {
                responderCert = issuerCert;
            }
            // if the issuer certificate didn't sign the ocsp response, look for authorized ocsp responses
            // from properties or from certificate chain received with response
            if (responderCert == null)
            {
                if (ocspResp.GetCerts() != null)
                {
                    //look for existence of Authorized OCSP responder inside the cert chain in ocsp response
                    IEnumerable <X509Certificate> certs = SignUtils.GetCertsFromOcspResponse(ocspResp);
                    foreach (X509Certificate cert in certs)
                    {
                        IList keyPurposes = null;
                        try {
                            keyPurposes = cert.GetExtendedKeyUsage();
                            if ((keyPurposes != null) && keyPurposes.Contains(id_kp_OCSPSigning) && IsSignatureValid(ocspResp, cert))
                            {
                                responderCert = cert;
                                break;
                            }
                        }
                        catch (CertificateParsingException) {
                        }
                    }
                    // Certificate signing the ocsp response is not found in ocsp response's certificate chain received
                    // and is not signed by the issuer certificate.
                    if (responderCert == null)
                    {
                        throw new VerificationException(issuerCert, "OCSP response could not be verified");
                    }
                    // RFC 6960 4.2.2.2. Authorized Responders:
                    // "Systems relying on OCSP responses MUST recognize a delegation certificate as being issued
                    // by the CA that issued the certificate in question only if the delegation certificate and the
                    // certificate being checked for revocation were signed by the same key."
                    // and
                    // "This certificate MUST be issued directly by the CA that is identified in the request"
                    responderCert.Verify(issuerCert.GetPublicKey());
                    // check if lifetime of certificate is ok
                    responderCert.CheckValidity(signDate);
                    // validating ocsp signers certificate
                    // Check if responders certificate has id-pkix-ocsp-nocheck extension,
                    // in which case we do not validate (perform revocation check on) ocsp certs for lifetime of certificate
                    if (responderCert.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNocheck.Id) == null)
                    {
                        X509Crl crl;
                        try {
                            // TODO should also check for Authority Information Access according to RFC6960 4.2.2.2.1. "Revocation Checking of an Authorized Responder"
                            // TODO should also respect onlineCheckingAllowed property?
                            crl = CertificateUtil.GetCRL(responderCert);
                        }
                        catch (Exception) {
                            crl = (X509Crl)null;
                        }
                        if (crl != null && crl is X509Crl)
                        {
                            CRLVerifier crlVerifier = new CRLVerifier(null, null);
                            crlVerifier.SetRootStore(rootStore);
                            crlVerifier.SetOnlineCheckingAllowed(onlineCheckingAllowed);
                            if (!crlVerifier.Verify((X509Crl)crl, responderCert, issuerCert, signDate))
                            {
                                throw new VerificationException(issuerCert, "Authorized OCSP responder certificate was revoked.");
                            }
                        }
                        else
                        {
                            ILog logger = LogManager.GetLogger(typeof(iText.Signatures.OCSPVerifier));
                            logger.Error("Authorized OCSP responder certificate revocation status cannot be checked");
                        }
                    }
                }
                else
                {
                    // TODO throw exception starting from iText version 7.2, but only after OCSPVerifier would allow explicit setting revocation check end points/provide revocation data
                    // throw new VerificationException(issuerCert, "Authorized OCSP responder certificate revocation status cannot be checked.");
                    // certificate chain is not present in response received
                    // try to verify using rootStore according to RFC 6960 2.2. Response:
                    // "The key used to sign the response MUST belong to one of the following:
                    // - ...
                    // - a Trusted Responder whose public key is trusted by the requestor;
                    // - ..."
                    if (rootStore != null)
                    {
                        try {
                            foreach (X509Certificate anchor in SignUtils.GetCertificates(rootStore))
                            {
                                if (IsSignatureValid(ocspResp, anchor))
                                {
                                    // certificate from the root store is considered trusted and valid by this method
                                    responderCert = anchor;
                                    break;
                                }
                            }
                        }
                        catch (Exception) {
                            responderCert = (X509Certificate)null;
                        }
                    }
                    if (responderCert == null)
                    {
                        throw new VerificationException(issuerCert, "OCSP response could not be verified: it does not contain certificate chain and response is not signed by issuer certificate or any from the root store."
                                                        );
                    }
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>Verifies a certificate chain against a KeyStore.</summary>
        /// <param name="certs">the certificate chain</param>
        /// <param name="keystore">the <c>KeyStore</c></param>
        /// <param name="crls">the certificate revocation list or <c>null</c></param>
        /// <param name="calendar">the date, shall not be null</param>
        /// <returns>
        /// empty list if the certificate chain could be validated or a
        /// <c>Object[]{cert,error}</c> where <c>cert</c> is the
        /// failed certificate and <c>error</c> is the error message
        /// </returns>
        public static IList <VerificationException> VerifyCertificates(X509Certificate[] certs, List <X509Certificate>
                                                                       keystore, ICollection <X509Crl> crls, DateTime calendar)
        {
            IList <VerificationException> result = new List <VerificationException>();

            for (int k = 0; k < certs.Length; ++k)
            {
                X509Certificate cert = (X509Certificate)certs[k];
                String          err  = VerifyCertificate(cert, crls, calendar);
                if (err != null)
                {
                    result.Add(new VerificationException(cert, err));
                }
                try {
                    foreach (X509Certificate certStoreX509 in SignUtils.GetCertificates(keystore))
                    {
                        try {
                            if (VerifyCertificate(certStoreX509, crls, calendar) != null)
                            {
                                continue;
                            }
                            try {
                                cert.Verify(certStoreX509.GetPublicKey());
                                return(result);
                            }
                            catch (Exception) {
                                continue;
                            }
                        }
                        catch (Exception) {
                        }
                    }
                }
                catch (Exception) {
                }
                int j;
                for (j = 0; j < certs.Length; ++j)
                {
                    if (j == k)
                    {
                        continue;
                    }
                    X509Certificate certNext = (X509Certificate)certs[j];
                    try {
                        cert.Verify(certNext.GetPublicKey());
                        break;
                    }
                    catch (Exception) {
                    }
                }
                if (j == certs.Length)
                {
                    result.Add(new VerificationException(cert, "Cannot be verified against the KeyStore or the certificate chain"
                                                         ));
                }
            }
            if (result.Count == 0)
            {
                result.Add(new VerificationException((X509Certificate)null, "Invalid state. Possible circular certificate chain"
                                                     ));
            }
            return(result);
        }
Ejemplo n.º 11
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.ThisInstanceOfPdfSignerIsAlreadyClosed);
            }
            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;
        }