/// <summary> /// Validates the cert with the provided crl responses. /// </summary> /// <param name="certificate">The cert to validate</param> /// <param name="issuer">The issuer of the cert to validate</param> /// <param name="validationTime">The time on which the cert was needed to validated</param> /// <param name="certLists">The list of crls to use</param> /// <returns>The crl response that was used, <c>null</c> if none used</returns> /// <exception cref="RevocationException{T}">When the certificate was revoked on the provided time</exception> /// <exception cref="RevocationUnknownException">When the certificate (or the crl) can't be validated</exception> public static BCAX.CertificateList Verify(this X509Certificate2 certificate, X509Certificate2 issuer, DateTime validationTime, IList <BCAX.CertificateList> certLists) { DateTime minTime = validationTime - ClockSkewness; DateTime maxTime = validationTime + ClockSkewness; BCX.X509Certificate certificateBC = DotNetUtilities.FromX509Certificate(certificate); BCX.X509Certificate issuerBC = DotNetUtilities.FromX509Certificate(issuer); ValueWithRef <BCX.X509Crl, BCAX.CertificateList> crlWithOrg = certLists .Select((c) => new ValueWithRef <BCX.X509Crl, BCAX.CertificateList>(new BCX.X509Crl(c), c)) //convert, keep orginal .Where((c) => c.Value.IssuerDN.Equals(certificateBC.IssuerDN)) .Where((c) => c.Value.ThisUpdate >= minTime || (c.Value.NextUpdate != null && c.Value.NextUpdate.Value >= minTime)) .OrderByDescending((c) => c.Value.ThisUpdate) .FirstOrDefault(); if (crlWithOrg == null) { return(null); } BCX.X509Crl crl = crlWithOrg.Value; BCAX.CertificateList certList = crlWithOrg.Reference; //check the signature (no need the check the issuer here) try { crl.Verify(issuerBC.GetPublicKey()); } catch (Exception e) { throw new RevocationUnknownException("The CRL has an invalid signature", e); } //check the signer (only the part relevant for CRL) if (!issuerBC.GetKeyUsage()[6]) { throw new RevocationUnknownException("The CRL was signed with a certificate that isn't allowed to sign CRLs"); } //check if the certificate is revoked BCX.X509CrlEntry crlEntry = crl.GetRevokedCertificate(certificateBC.SerialNumber); if (crlEntry != null) { trace.TraceEvent(TraceEventType.Verbose, 0, "CRL indicates that {0} is revoked on {1}", certificate.Subject, crlEntry.RevocationDate); if (maxTime >= crlEntry.RevocationDate) { throw new RevocationException <BCAX.CertificateList>(certList, "The certificate was revoked on " + crlEntry.RevocationDate.ToString("o")); } } return(certList); }
internal static AsymmetricKeyParameter ProcessCrlG( X509Crl crl, ISet keys) { Exception lastException = null; foreach (AsymmetricKeyParameter key in keys) { try { crl.Verify(key); return key; } catch (Exception e) { lastException = e; } } throw new Exception("Cannot verify CRL.", lastException); }
/** * Checks if a CRL verifies against the issuer certificate or a trusted anchor. * @param crl the CRL * @param crlIssuer the trusted anchor * @return true if the CRL can be trusted */ public 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 (certificates == null) return false; try { // loop over the certificate in the key store foreach (X509Certificate anchor in certificates) { try { crl.Verify(anchor.GetPublicKey()); return true; } catch (GeneralSecurityException) {} } } catch (GeneralSecurityException) { return false; } return false; }
private bool IsCRLOK(X509Crl x509crl, X509Certificate issuerCertificate, DateTime validationDate) { if (issuerCertificate == null) { throw new ArgumentNullException("Must provide a issuer certificate to validate the signature" ); } if (!x509crl.IssuerDN.Equals(issuerCertificate.SubjectDN)) { LOG.Warn("The CRL must be signed by the issuer (" + issuerCertificate.SubjectDN + " ) but instead is signed by " + x509crl.IssuerDN); return false; } try { x509crl.Verify(issuerCertificate.GetPublicKey()); } catch (Exception e) { LOG.Warn("The signature verification for CRL cannot be performed : " + e.Message ); return false; } DateTime thisUpdate = x509crl.ThisUpdate; LOG.Info("validation date: " + validationDate); LOG.Info("CRL this update: " + thisUpdate); // if (thisUpdate.after(validationDate)) { // LOG.warning("CRL too young"); // return false; // } LOG.Info("CRL next update: " + x509crl.NextUpdate); if (x509crl.NextUpdate != null && validationDate.CompareTo(x509crl.NextUpdate.Value) > 0) //jbonilla After { LOG.Info("CRL too old"); return false; } // assert cRLSign KeyUsage bit if (null == issuerCertificate.GetKeyUsage()) { LOG.Warn("No KeyUsage extension for CRL issuing certificate"); return false; } if (false == issuerCertificate.GetKeyUsage()[6]) { LOG.Warn("cRLSign bit not set for CRL issuing certificate"); return false; } return true; }