/// <summary>Return the issuer of the given CRL as an X509Principal.</summary> public static X509Name GetIssuerX509Principal( X509Crl crl) { try { TbsCertificateList tbsCertList = TbsCertificateList.GetInstance( Asn1Object.FromByteArray(crl.GetTbsCertList())); return tbsCertList.Issuer; } catch (Exception e) { throw new CrlException("Could not extract issuer", e); } }
public override bool Equals( object obj) { if (obj == this) { return(true); } X509Crl other = obj as X509Crl; if (other == null) { return(false); } return(c.Equals(other.c)); // NB: May prefer this implementation of Equals if more than one certificate implementation in play //return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded()); }
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); }
/** * Obtain and validate the certification path for the complete CRL issuer. * If a key usage extension is present in the CRL issuer's certificate, * verify that the cRLSign bit is set. * * @param crl CRL which contains revocation information for the certificate * <code>cert</code>. * @param cert The attribute certificate or certificate to check if it is * revoked. * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>. * @param defaultCRLSignKey The public key of the issuer certificate * <code>defaultCRLSignCert</code>. * @param paramsPKIX paramsPKIX PKIX parameters. * @param certPathCerts The certificates on the certification path. * @return A <code>Set</code> with all keys of possible CRL issuer * certificates. * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or * some error occurs. */ internal static ISet ProcessCrlF( X509Crl crl, object cert, X509Certificate defaultCRLSignCert, AsymmetricKeyParameter defaultCRLSignKey, PkixParameters paramsPKIX, IList certPathCerts) { // (f) // get issuer from CRL X509CertStoreSelector selector = new X509CertStoreSelector(); try { selector.Subject = crl.IssuerDN; } catch (IOException e) { throw new Exception( "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e); } // get CRL signing certs IList coll = Platform.CreateArrayList(); try { CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetStores())); CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetAdditionalStores())); } catch (Exception e) { throw new Exception("Issuer certificate for CRL cannot be searched.", e); } coll.Add(defaultCRLSignCert); IEnumerator cert_it = coll.GetEnumerator(); IList validCerts = Platform.CreateArrayList(); IList validKeys = Platform.CreateArrayList(); while (cert_it.MoveNext()) { X509Certificate signingCert = (X509Certificate)cert_it.Current; /* * CA of the certificate, for which this CRL is checked, has also * signed CRL, so skip the path validation, because is already done */ if (signingCert.Equals(defaultCRLSignCert)) { validCerts.Add(signingCert); validKeys.Add(defaultCRLSignKey); continue; } try { // CertPathBuilder builder = CertPathBuilder.GetInstance("PKIX"); PkixCertPathBuilder builder = new PkixCertPathBuilder(); selector = new X509CertStoreSelector(); selector.Certificate = signingCert; PkixParameters temp = (PkixParameters)paramsPKIX.Clone(); temp.SetTargetCertConstraints(selector); PkixBuilderParameters parameters = (PkixBuilderParameters) PkixBuilderParameters.GetInstance(temp); /* * if signingCert is placed not higher on the cert path a * dependency loop results. CRL for cert is checked, but * signingCert is needed for checking the CRL which is dependent * on checking cert because it is higher in the cert path and so * signing signingCert transitively. so, revocation is disabled, * forgery attacks of the CRL are detected in this outer loop * for all other it must be enabled to prevent forgery attacks */ if (certPathCerts.Contains(signingCert)) { parameters.IsRevocationEnabled = false; } else { parameters.IsRevocationEnabled = true; } IList certs = builder.Build(parameters).CertPath.Certificates; validCerts.Add(signingCert); validKeys.Add(PkixCertPathValidatorUtilities.GetNextWorkingKey(certs, 0)); } catch (PkixCertPathBuilderException e) { throw new Exception("Internal error.", e); } catch (PkixCertPathValidatorException e) { throw new Exception("Public key of issuer certificate of CRL could not be retrieved.", e); } //catch (Exception e) //{ // throw new Exception(e.Message); //} } ISet checkKeys = new HashSet(); Exception lastException = null; for (int i = 0; i < validCerts.Count; i++) { X509Certificate signCert = (X509Certificate)validCerts[i]; bool[] keyusage = signCert.GetKeyUsage(); if (keyusage != null && (keyusage.Length < 7 || !keyusage[CRL_SIGN])) { lastException = new Exception( "Issuer certificate key usage extension does not permit CRL signing."); } else { checkKeys.Add(validKeys[i]); } } if ((checkKeys.Count == 0) && lastException == null) { throw new Exception("Cannot find a valid issuer certificate."); } if ((checkKeys.Count == 0) && lastException != null) { throw lastException; } return checkKeys; }
internal static ReasonsMask ProcessCrlD( X509Crl crl, DistributionPoint dp) //throws AnnotatedException { IssuingDistributionPoint idp = null; try { idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint)); } catch (Exception e) { throw new Exception("issuing distribution point extension could not be decoded.", e); } // (d) (1) if (idp != null && idp.OnlySomeReasons != null && dp.Reasons != null) { return new ReasonsMask(dp.Reasons.IntValue).Intersect(new ReasonsMask(idp.OnlySomeReasons .IntValue)); } // (d) (4) if ((idp == null || idp.OnlySomeReasons == null) && dp.Reasons == null) { return ReasonsMask.AllReasons; } // (d) (2) and (d)(3) ReasonsMask dpReasons = null; if (dp.Reasons == null) { dpReasons = ReasonsMask.AllReasons; } else { dpReasons = new ReasonsMask(dp.Reasons.IntValue); } ReasonsMask idpReasons = null; if (idp == null) { idpReasons = ReasonsMask.AllReasons; } else { idpReasons = new ReasonsMask(idp.OnlySomeReasons.IntValue); } return dpReasons.Intersect(idpReasons); }
/** * If the complete CRL includes an issuing distribution point (IDP) CRL * extension check the following: * <p> * (i) If the distribution point name is present in the IDP CRL extension * and the distribution field is present in the DP, then verify that one of * the names in the IDP matches one of the names in the DP. If the * distribution point name is present in the IDP CRL extension and the * distribution field is omitted from the DP, then verify that one of the * names in the IDP matches one of the names in the cRLIssuer field of the * DP. * </p> * <p> * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL * extension, verify that the certificate does not include the basic * constraints extension with the cA boolean asserted. * </p> * <p> * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL * extension, verify that the certificate includes the basic constraints * extension with the cA boolean asserted. * </p> * <p> * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted. * </p> * * @param dp The distribution point. * @param cert The certificate. * @param crl The CRL. * @throws AnnotatedException if one of the conditions is not met or an error occurs. */ internal static void ProcessCrlB2( DistributionPoint dp, object cert, X509Crl crl) { IssuingDistributionPoint idp = null; try { idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint)); } catch (Exception e) { throw new Exception("0 Issuing distribution point extension could not be decoded.", e); } // (b) (2) (i) // distribution point name is present if (idp != null) { if (idp.DistributionPoint != null) { // make list of names DistributionPointName dpName = IssuingDistributionPoint.GetInstance(idp).DistributionPoint; IList names = Platform.CreateArrayList(); if (dpName.PointType == DistributionPointName.FullName) { GeneralName[] genNames = GeneralNames.GetInstance(dpName.Name).GetNames(); for (int j = 0; j < genNames.Length; j++) { names.Add(genNames[j]); } } if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer) { Asn1EncodableVector vec = new Asn1EncodableVector(); try { IEnumerator e = Asn1Sequence.GetInstance( Asn1Sequence.FromByteArray(crl.IssuerDN.GetEncoded())).GetEnumerator(); while (e.MoveNext()) { vec.Add((Asn1Encodable)e.Current); } } catch (IOException e) { throw new Exception("Could not read CRL issuer.", e); } vec.Add(dpName.Name); names.Add(new GeneralName(X509Name.GetInstance(new DerSequence(vec)))); } bool matches = false; // verify that one of the names in the IDP matches one // of the names in the DP. if (dp.DistributionPointName != null) { dpName = dp.DistributionPointName; GeneralName[] genNames = null; if (dpName.PointType == DistributionPointName.FullName) { genNames = GeneralNames.GetInstance(dpName.Name).GetNames(); } if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer) { if (dp.CrlIssuer != null) { genNames = dp.CrlIssuer.GetNames(); } else { genNames = new GeneralName[1]; try { genNames[0] = new GeneralName( PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert)); } catch (IOException e) { throw new Exception("Could not read certificate issuer.", e); } } for (int j = 0; j < genNames.Length; j++) { IEnumerator e = Asn1Sequence.GetInstance(genNames[j].Name.ToAsn1Object()).GetEnumerator(); Asn1EncodableVector vec = new Asn1EncodableVector(); while (e.MoveNext()) { vec.Add((Asn1Encodable)e.Current); } vec.Add(dpName.Name); genNames[j] = new GeneralName(X509Name.GetInstance(new DerSequence(vec))); } } if (genNames != null) { for (int j = 0; j < genNames.Length; j++) { if (names.Contains(genNames[j])) { matches = true; break; } } } if (!matches) { throw new Exception( "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } } // verify that one of the names in // the IDP matches one of the names in the cRLIssuer field of // the DP else { if (dp.CrlIssuer == null) { throw new Exception("Either the cRLIssuer or the distributionPoint field must " + "be contained in DistributionPoint."); } GeneralName[] genNames = dp.CrlIssuer.GetNames(); for (int j = 0; j < genNames.Length; j++) { if (names.Contains(genNames[j])) { matches = true; break; } } if (!matches) { throw new Exception( "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); } } } BasicConstraints bc = null; try { bc = BasicConstraints.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue( (IX509Extension)cert, X509Extensions.BasicConstraints)); } catch (Exception e) { throw new Exception("Basic constraints extension could not be decoded.", e); } //if (cert is X509Certificate) { // (b) (2) (ii) if (idp.OnlyContainsUserCerts && ((bc != null) && bc.IsCA())) { throw new Exception("CA Cert CRL only contains user certificates."); } // (b) (2) (iii) if (idp.OnlyContainsCACerts && (bc == null || !bc.IsCA())) { throw new Exception("End CRL only contains CA certificates."); } } // (b) (2) (iv) if (idp.OnlyContainsAttributeCerts) { throw new Exception("onlyContainsAttributeCerts boolean is asserted."); } } }
/** * If the DP includes cRLIssuer, then verify that the issuer field in the * complete CRL matches cRLIssuer in the DP and that the complete CRL * contains an * g distribution point extension with the indirectCRL * boolean asserted. Otherwise, verify that the CRL issuer matches the * certificate issuer. * * @param dp The distribution point. * @param cert The certificate ot attribute certificate. * @param crl The CRL for <code>cert</code>. * @throws AnnotatedException if one of the above conditions does not apply or an error * occurs. */ internal static void ProcessCrlB1( DistributionPoint dp, object cert, X509Crl crl) { Asn1Object idp = PkixCertPathValidatorUtilities.GetExtensionValue( crl, X509Extensions.IssuingDistributionPoint); bool isIndirect = false; if (idp != null) { if (IssuingDistributionPoint.GetInstance(idp).IsIndirectCrl) { isIndirect = true; } } byte[] issuerBytes = crl.IssuerDN.GetEncoded(); bool matchIssuer = false; if (dp.CrlIssuer != null) { GeneralName[] genNames = dp.CrlIssuer.GetNames(); for (int j = 0; j < genNames.Length; j++) { if (genNames[j].TagNo == GeneralName.DirectoryName) { try { if (Arrays.AreEqual(genNames[j].Name.ToAsn1Object().GetEncoded(), issuerBytes)) { matchIssuer = true; } } catch (IOException e) { throw new Exception( "CRL issuer information from distribution point cannot be decoded.", e); } } } if (matchIssuer && !isIndirect) { throw new Exception("Distribution point contains cRLIssuer field but CRL is not indirect."); } if (!matchIssuer) { throw new Exception("CRL issuer of CRL does not match CRL issuer of distribution point."); } } else { if (crl.IssuerDN.Equivalent(PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert), true)) { matchIssuer = true; } } if (!matchIssuer) { throw new Exception("Cannot find matching CRL issuer for certificate."); } }
internal static void ProcessCrlJ( DateTime validDate, X509Crl completecrl, object cert, CertStatus certStatus) { if (certStatus.Status == CertStatus.Unrevoked) { PkixCertPathValidatorUtilities.GetCertStatus(validDate, completecrl, cert, certStatus); } }
internal static void ProcessCrlI( DateTime validDate, X509Crl deltacrl, object cert, CertStatus certStatus, PkixParameters pkixParams) { if (pkixParams.IsUseDeltasEnabled && deltacrl != null) { PkixCertPathValidatorUtilities.GetCertStatus(validDate, deltacrl, cert, certStatus); } }
/** * If use-deltas is set, verify the issuer and scope of the delta CRL. * * @param deltaCRL The delta CRL. * @param completeCRL The complete CRL. * @param pkixParams The PKIX paramaters. * @throws AnnotatedException if an exception occurs. */ internal static void ProcessCrlC( X509Crl deltaCRL, X509Crl completeCRL, PkixParameters pkixParams) { if (deltaCRL == null) return; IssuingDistributionPoint completeidp = null; try { completeidp = IssuingDistributionPoint.GetInstance( PkixCertPathValidatorUtilities.GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint)); } catch (Exception e) { throw new Exception("000 Issuing distribution point extension could not be decoded.", e); } if (pkixParams.IsUseDeltasEnabled) { // (c) (1) if (!deltaCRL.IssuerDN.Equivalent(completeCRL.IssuerDN, true)) throw new Exception("Complete CRL issuer does not match delta CRL issuer."); // (c) (2) IssuingDistributionPoint deltaidp = null; try { deltaidp = IssuingDistributionPoint.GetInstance( PkixCertPathValidatorUtilities.GetExtensionValue(deltaCRL, X509Extensions.IssuingDistributionPoint)); } catch (Exception e) { throw new Exception( "Issuing distribution point extension from delta CRL could not be decoded.", e); } if (!Platform.Equals(completeidp, deltaidp)) { throw new Exception( "Issuing distribution point extension from delta CRL and complete CRL does not match."); } // (c) (3) Asn1Object completeKeyIdentifier = null; try { completeKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue( completeCRL, X509Extensions.AuthorityKeyIdentifier); } catch (Exception e) { throw new Exception( "Authority key identifier extension could not be extracted from complete CRL.", e); } Asn1Object deltaKeyIdentifier = null; try { deltaKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue( deltaCRL, X509Extensions.AuthorityKeyIdentifier); } catch (Exception e) { throw new Exception( "Authority key identifier extension could not be extracted from delta CRL.", e); } if (completeKeyIdentifier == null) throw new Exception("CRL authority key identifier is null."); if (deltaKeyIdentifier == null) throw new Exception("Delta CRL authority key identifier is null."); if (!completeKeyIdentifier.Equals(deltaKeyIdentifier)) { throw new Exception( "Delta CRL authority key identifier does not match complete CRL authority key identifier."); } } }
internal static ISet ProcessCrlA1i( DateTime currentDate, PkixParameters paramsPKIX, X509Certificate cert, X509Crl crl) { ISet deltaSet = new HashSet(); if (paramsPKIX.IsUseDeltasEnabled) { CrlDistPoint freshestCRL = null; try { freshestCRL = CrlDistPoint.GetInstance( PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.FreshestCrl)); } catch (Exception e) { throw new Exception("Freshest CRL extension could not be decoded from certificate.", e); } if (freshestCRL == null) { try { freshestCRL = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.FreshestCrl)); } catch (Exception e) { throw new Exception("Freshest CRL extension could not be decoded from CRL.", e); } } if (freshestCRL != null) { try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(freshestCRL, paramsPKIX); } catch (Exception e) { throw new Exception( "No new delta CRL locations could be added from Freshest CRL extension.", e); } // get delta CRL(s) try { deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl)); } catch (Exception e) { throw new Exception("Exception obtaining delta CRLs.", e); } } } return deltaSet; }
internal static ISet[] ProcessCrlA1ii( DateTime currentDate, PkixParameters paramsPKIX, X509Certificate cert, X509Crl crl) { ISet deltaSet = new HashSet(); X509CrlStoreSelector crlselect = new X509CrlStoreSelector(); crlselect.CertificateChecking = cert; try { IList issuer = Platform.CreateArrayList(); issuer.Add(crl.IssuerDN); crlselect.Issuers = issuer; } catch (IOException e) { throw new Exception("Cannot extract issuer from CRL." + e, e); } crlselect.CompleteCrlEnabled = true; ISet completeSet = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate); if (paramsPKIX.IsUseDeltasEnabled) { // get delta CRL(s) try { deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl)); } catch (Exception e) { throw new Exception("Exception obtaining delta CRLs.", e); } } return new ISet[]{ completeSet, deltaSet }; }
private static bool isDeltaCrl( X509Crl crl) { ISet critical = crl.GetCriticalExtensionOids(); return critical.Contains(X509Extensions.DeltaCrlIndicator.Id); }
/** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @param completeCRL The complete CRL the delta CRL is for. * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs. * @throws Exception if an exception occurs while picking the delta * CRLs. */ internal static ISet GetDeltaCrls( DateTime currentDate, PkixParameters paramsPKIX, X509Crl completeCRL) { X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector(); // 5.2.4 (a) try { IList deltaSelectIssuer = Platform.CreateArrayList(); deltaSelectIssuer.Add(completeCRL.IssuerDN); deltaSelect.Issuers = deltaSelectIssuer; } catch (IOException e) { new Exception("Cannot extract issuer from CRL.", e); } BigInteger completeCRLNumber = null; try { Asn1Object asn1Object = GetExtensionValue(completeCRL, X509Extensions.CrlNumber); if (asn1Object != null) { completeCRLNumber = CrlNumber.GetInstance(asn1Object).PositiveValue; } } catch (Exception e) { throw new Exception( "CRL number extension could not be extracted from CRL.", e); } // 5.2.4 (b) byte[] idp = null; try { Asn1Object obj = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint); if (obj != null) { idp = obj.GetDerEncoded(); } } catch (Exception e) { throw new Exception( "Issuing distribution point extension value could not be read.", e); } // 5.2.4 (d) deltaSelect.MinCrlNumber = (completeCRLNumber == null) ? null : completeCRLNumber.Add(BigInteger.One); deltaSelect.IssuingDistributionPoint = idp; deltaSelect.IssuingDistributionPointEnabled = true; // 5.2.4 (c) deltaSelect.MaxBaseCrlNumber = completeCRLNumber; // find delta CRLs ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate); ISet result = new HashSet(); foreach (X509Crl crl in temp) { if (isDeltaCrl(crl)) { result.Add(crl); } } return result; }
internal static void GetCertStatus( DateTime validDate, X509Crl crl, Object cert, CertStatus certStatus) { X509Crl bcCRL = null; try { bcCRL = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Sequence.FromByteArray(crl.GetEncoded()))); } catch (Exception exception) { throw new Exception("Bouncy Castle X509Crl could not be created.", exception); } X509CrlEntry crl_entry = (X509CrlEntry)bcCRL.GetRevokedCertificate(GetSerialNumber(cert)); if (crl_entry == null) return; X509Name issuer = GetIssuerPrincipal(cert); if (issuer.Equivalent(crl_entry.GetCertificateIssuer(), true) || issuer.Equivalent(crl.IssuerDN, true)) { DerEnumerated reasonCode = null; if (crl_entry.HasExtensions) { try { reasonCode = DerEnumerated.GetInstance( GetExtensionValue(crl_entry, X509Extensions.ReasonCode)); } catch (Exception e) { new Exception( "Reason code CRL entry extension could not be decoded.", e); } } // for reason keyCompromise, caCompromise, aACompromise or // unspecified if (!(validDate.Ticks < crl_entry.RevocationDate.Ticks) || reasonCode == null || reasonCode.Value.TestBit(0) || reasonCode.Value.TestBit(1) || reasonCode.Value.TestBit(2) || reasonCode.Value.TestBit(8)) { if (reasonCode != null) // (i) or (j) (1) { certStatus.Status = reasonCode.Value.Sign; } else // (i) or (j) (2) { certStatus.Status = CrlReason.Unspecified; } certStatus.RevocationDate = new DateTimeObject(crl_entry.RevocationDate); } } }
/** * Add the CRLEntry objects contained in a previous CRL. * * @param other the X509Crl to source the other entries from. */ public void AddCrl( X509Crl other) { if (other == null) throw new ArgumentNullException("other"); ISet revocations = other.GetRevokedCertificates(); if (revocations != null) { foreach (X509CrlEntry entry in revocations) { try { tbsGen.AddCrlEntry( Asn1Sequence.GetInstance( Asn1Object.FromByteArray(entry.GetEncoded()))); } catch (IOException e) { throw new CrlException("exception processing encoding of CRL", e); } } } }