/// <summary> /// Lookup and validate certificate against CDP URL inside the certificate. /// </summary> /// <param name="cert"></param> /// <returns></returns> public CertStatus ValidateCertificateAgainstCRL(System.Security.Cryptography.X509Certificates.X509Certificate2 cert) { var urls = ParseCDPUrls(cert); if (urls == null || urls.Count == 0 || urls.Count > 1) { return(CertStatus.Unknown(CertStatus.NoCrl)); } var crl = LoadCrl(urls[0]); if (crl.NextUpdate.Value < DateTime.UtcNow) { return(CertStatus.Unknown(CertStatus.BadCrl)); } var serialNumber = new BigInteger(cert.SerialNumber, 16); var entry = crl.GetRevokedCertificate(serialNumber); if (entry == null) { return(CertStatus.Good); } DerEnumerated reasonCode = null; try { reasonCode = DerEnumerated.GetInstance(entry.GetExtensionValue(X509Extensions.ReasonCode)); } catch { return(CertStatus.Unknown(CertStatus.BadRevocationReason)); } int?revocationReason = null; if (reasonCode != null) { revocationReason = reasonCode.Value.SignValue; } else { revocationReason = CrlReason.Unspecified; } DateTime revocationDate = entry.RevocationDate; return(CertStatus.Revoked(revocationDate.ToString("o"), revocationReason)); }
/// <summary> /// Validate a certificate against its AIA OCSP. /// </summary> /// <param name="cert"></param> /// <param name="aia"></param> /// <returns></returns> CertStatus Validate(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, AIA aia) { string hash = ComputeSHA1(System.Text.ASCIIEncoding.ASCII.GetBytes(aia.Issuer)); string filePath = IssuerCachedFolder + hash; //Check if aki is cached if (!IsIssuerCached(aia.Issuer)) { Download(aia.Issuer, filePath); if (!IsIssuerCached(aia.Issuer)) { return(CertStatus.Unknown(CertStatus.BadIssuer)); } } var issuerTemp = new System.Security.Cryptography.X509Certificates.X509Certificate2(filePath); var certParser = new Org.BouncyCastle.X509.X509CertificateParser(); var issuer = certParser.ReadCertificate(issuerTemp.RawData); var cert2Validate = certParser.ReadCertificate(cert.RawData); var id = new Org.BouncyCastle.Ocsp.CertificateID( Org.BouncyCastle.Ocsp.CertificateID.HashSha1, issuer, cert2Validate.SerialNumber); byte[] reqEnc = GenerateOCSPRequest(id, cert2Validate); byte[] resp = GetOCSPResponse(aia.Ocsp, reqEnc); //Extract the response OcspResp ocspResponse = new OcspResp(resp); BasicOcspResp basicOCSPResponse = (BasicOcspResp)ocspResponse.GetResponseObject(); SingleResp singResp = basicOCSPResponse.Responses[0]; //Validate ID var expectedId = singResp.GetCertID(); if (!expectedId.SerialNumber.Equals(id.SerialNumber)) { return(CertStatus.Unknown(CertStatus.BadSerial)); } if (!Org.BouncyCastle.Utilities.Arrays.AreEqual(expectedId.GetIssuerNameHash(), id.GetIssuerNameHash())) { return(CertStatus.Unknown(CertStatus.IssuerNotMatch)); } //Extract Status var certificateStatus = singResp.GetCertStatus(); if (certificateStatus == null) { return(CertStatus.Good); } if (certificateStatus is Org.BouncyCastle.Ocsp.RevokedStatus) { int revocationReason = ((Org.BouncyCastle.Ocsp.RevokedStatus)certificateStatus).RevocationReason; var revocationDate = ((Org.BouncyCastle.Ocsp.RevokedStatus)certificateStatus).RevocationTime; return(CertStatus.Revoked(revocationDate.ToString("o"), revocationReason)); } if (certificateStatus is Org.BouncyCastle.Ocsp.UnknownStatus) { return(CertStatus.Unknown()); } return(CertStatus.Unknown()); }