/// <summary>Verifies a single certificate against a key store (if present).</summary>
 /// <param name="signCert">the certificate to verify</param>
 /// <param name="issuerCert">the issuer certificate</param>
 /// <param name="signDate">the date the certificate needs to be valid</param>
 /// <returns>
 /// a list of <c>VerificationOK</c> objects.
 /// The list will be empty if the certificate couldn't be verified.
 /// </returns>
 public override IList <VerificationOK> Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime
                                               signDate)
 {
     // verify using the CertificateVerifier if root store is missing
     if (rootStore == null)
     {
         return(base.Verify(signCert, issuerCert, signDate));
     }
     try {
         IList <VerificationOK> result = new List <VerificationOK>();
         // loop over the trusted anchors in the root store
         foreach (X509Certificate anchor in SignUtils.GetCertificates(rootStore))
         {
             try {
                 signCert.Verify(anchor.GetPublicKey());
                 result.Add(new VerificationOK(signCert, this.GetType(), "Certificate verified against root store."));
                 result.AddAll(base.Verify(signCert, issuerCert, signDate));
                 return(result);
             }
             catch (GeneralSecurityException) {
                 continue;
             }
         }
         result.AddAll(base.Verify(signCert, issuerCert, signDate));
         return(result);
     }
     catch (GeneralSecurityException) {
         return(base.Verify(signCert, issuerCert, signDate));
     }
 }
        /// <summary>Verifies a time stamp against a KeyStore.</summary>
        /// <param name="ts">the time stamp</param>
        /// <param name="keystore">the <CODE>KeyStore</CODE></param>
        /// <param name="provider">the provider or <CODE>null</CODE> to use the BouncyCastle provider</param>
        /// <returns><CODE>true</CODE> is a certificate was found</returns>
        public static bool VerifyTimestampCertificates(TimeStampToken ts, List <X509Certificate> keystore)
        {
            IList <Exception> exceptionsThrown = new List <Exception>();

            try {
                foreach (X509Certificate certStoreX509 in SignUtils.GetCertificates(keystore))
                {
                    try {
                        SignUtils.IsSignatureValid(ts, certStoreX509);
                        return(true);
                    }
                    catch (Exception ex) {
                        exceptionsThrown.Add(ex);
                    }
                }
            }
            catch (Exception e) {
                exceptionsThrown.Add(e);
            }
            foreach (Exception ex in exceptionsThrown)
            {
                LOGGER.Error(ex.Message, ex);
            }
            return(false);
        }
Example #3
0
 /// <summary>Verifies an OCSP response against a KeyStore.</summary>
 /// <param name="ocsp">the OCSP response</param>
 /// <param name="keystore">the <CODE>KeyStore</CODE></param>
 /// <param name="provider">the provider or <CODE>null</CODE> to use the BouncyCastle provider</param>
 /// <returns><CODE>true</CODE> is a certificate was found</returns>
 public static bool VerifyOcspCertificates(BasicOcspResp ocsp, List <X509Certificate> keystore)
 {
     try {
         foreach (X509Certificate certStoreX509 in SignUtils.GetCertificates(keystore))
         {
             try {
                 return(SignUtils.IsSignatureValid(ocsp, certStoreX509));
             }
             catch (Exception) {
             }
         }
     }
     catch (Exception) {
     }
     return(false);
 }
Example #4
0
 /// <summary>Verifies a time stamp against a KeyStore.</summary>
 /// <param name="ts">the time stamp</param>
 /// <param name="keystore">the <CODE>KeyStore</CODE></param>
 /// <param name="provider">the provider or <CODE>null</CODE> to use the BouncyCastle provider</param>
 /// <returns><CODE>true</CODE> is a certificate was found</returns>
 public static bool VerifyTimestampCertificates(TimeStampToken ts, List <X509Certificate> keystore)
 {
     try {
         foreach (X509Certificate certStoreX509 in SignUtils.GetCertificates(keystore))
         {
             try {
                 SignUtils.IsSignatureValid(ts, certStoreX509);
                 return(true);
             }
             catch (Exception) {
             }
         }
     }
     catch (Exception) {
     }
     return(false);
 }
Example #5
0
 /// <summary>Checks if a CRL verifies against the issuer certificate or a trusted anchor.</summary>
 /// <param name="crl">the CRL</param>
 /// <param name="crlIssuer">the trusted anchor</param>
 /// <returns>true if the CRL can be trusted</returns>
 public virtual bool IsSignatureValid(X509Crl crl, X509Certificate crlIssuer)
 {
     // check if the CRL was issued by the issuer
     if (crlIssuer != null)
     {
         try {
             crl.Verify(crlIssuer.GetPublicKey());
             return(true);
         }
         catch (GeneralSecurityException) {
             LOGGER.Warn("CRL not issued by the same authority as the certificate that is being checked");
         }
     }
     // check the CRL against trusted anchors
     if (rootStore == null)
     {
         return(false);
     }
     try {
         // loop over the certificate in the key store
         foreach (X509Certificate anchor in SignUtils.GetCertificates(rootStore))
         {
             try {
                 // check if the crl was signed by a trusted party (indirect CRLs)
                 crl.Verify(anchor.GetPublicKey());
                 return(true);
             }
             catch (GeneralSecurityException) {
                 continue;
             }
         }
     }
     catch (GeneralSecurityException) {
         return(false);
     }
     return(false);
 }
        /// <summary>Verifies an OCSP response against a KeyStore.</summary>
        /// <param name="ocsp">the OCSP response</param>
        /// <param name="keystore">the <CODE>KeyStore</CODE></param>
        /// <param name="provider">the provider or <CODE>null</CODE> to use the BouncyCastle provider</param>
        /// <returns><CODE>true</CODE> is a certificate was found</returns>
        public static bool VerifyOcspCertificates(BasicOcspResp ocsp, List <X509Certificate> keystore)
        {
            IList <Exception> exceptionsThrown = new List <Exception>();

            try {
                foreach (X509Certificate certStoreX509 in SignUtils.GetCertificates(keystore))
                {
                    try {
                        return(SignUtils.IsSignatureValid(ocsp, certStoreX509));
                    }
                    catch (Exception ex) {
                        exceptionsThrown.Add(ex);
                    }
                }
            }
            catch (Exception e) {
                exceptionsThrown.Add(e);
            }
            foreach (Exception ex in exceptionsThrown)
            {
                LOGGER.Error(ex.Message, ex);
            }
            return(false);
        }
        /// <summary>Verifies a certificate chain against a KeyStore.</summary>
        /// <param name="certs">the certificate chain</param>
        /// <param name="keystore">the <CODE>KeyStore</CODE></param>
        /// <param name="crls">the certificate revocation list or <CODE>null</CODE></param>
        /// <param name="calendar">the date, shall not be null</param>
        /// <returns>
        /// <CODE>null</CODE> if the certificate chain could be validated or a
        /// <CODE>Object[]{cert,error}</CODE> where <CODE>cert</CODE> is the
        /// failed certificate and <CODE>error</CODE> 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);
        }
Example #8
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."
                                                        );
                    }
                }
            }
        }
Example #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</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();
        }