/** * 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; }
/** * Checks a certificate if it is revoked. * * @param paramsPKIX PKIX parameters. * @param cert Certificate to check if it is revoked. * @param validDate The date when the certificate revocation status should be * checked. * @param sign The issuer certificate of the certificate <code>cert</code>. * @param workingPublicKey The public key of the issuer certificate <code>sign</code>. * @param certPathCerts The certificates of the certification path. * @throws AnnotatedException if the certificate is revoked or the status cannot be checked * or some error occurs. */ protected static void CheckCrls( PkixParameters paramsPKIX, X509Certificate cert, DateTime validDate, X509Certificate sign, AsymmetricKeyParameter workingPublicKey, IList certPathCerts) { Exception lastException = null; CrlDistPoint crldp = null; try { crldp = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CrlDistributionPoints)); } catch (Exception e) { throw new Exception("CRL distribution point extension could not be read.", e); } try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX); } catch (Exception e) { throw new Exception( "No additional CRL locations could be decoded from CRL distribution point extension.", e); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); bool validCrlFound = false; // for each distribution point if (crldp != null) { DistributionPoint[] dps = null; try { dps = crldp.GetDistributionPoints(); } catch (Exception e) { throw new Exception("Distribution points could not be read.", e); } if (dps != null) { for (int i = 0; i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons; i++) { PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone(); try { CheckCrl(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (Exception e) { lastException = e; } } } } /* * If the revocation status has not been determined, repeat the process * above with any available CRLs not specified in a distribution point * but issued by the certificate issuer. */ if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons) { try { /* * assume a DP with both the reasons and the cRLIssuer fields * omitted and a distribution point name of the certificate * issuer. */ Asn1Object issuer = null; try { issuer = new Asn1InputStream(cert.IssuerDN.GetEncoded()).ReadObject(); } catch (Exception e) { throw new Exception("Issuer from certificate for CRL could not be reencoded.", e); } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.DirectoryName, issuer))), null, null); PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone(); CheckCrl(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (Exception e) { lastException = e; } } if (!validCrlFound) { throw lastException; } if (certStatus.Status != CertStatus.Unrevoked) { // TODO This format is forced by the NistCertPath tests string formattedDate = certStatus.RevocationDate.Value.ToString( "G", System.util.Util.GetStandartEnUSLocale()); string message = "Certificate revocation after " + formattedDate; message += ", reason: " + CrlReasons[certStatus.Status]; throw new Exception(message); } if (!reasonsMask.IsAllReasons && certStatus.Status == CertStatus.Unrevoked) { certStatus.Status = CertStatus.Undetermined; } if (certStatus.Status == CertStatus.Undetermined) { throw new Exception("Certificate status could not be determined."); } }
/** * Checks if an attribute certificate is revoked. * * @param attrCert Attribute certificate to check if it is revoked. * @param paramsPKIX PKIX parameters. * @param issuerCert The issuer certificate of the attribute certificate * <code>attrCert</code>. * @param validDate The date when the certificate revocation status should * be checked. * @param certPathCerts The certificates of the certification path to be * checked. * * @throws CertPathValidatorException if the certificate is revoked or the * status cannot be checked or some error occurs. */ internal static void CheckCrls( IX509AttributeCertificate attrCert, PkixParameters paramsPKIX, X509Certificate issuerCert, DateTime validDate, IList certPathCerts) { if (paramsPKIX.IsRevocationEnabled) { // check if revocation is available if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) == null) { CrlDistPoint crldp = null; try { crldp = CrlDistPoint.GetInstance( PkixCertPathValidatorUtilities.GetExtensionValue( attrCert, X509Extensions.CrlDistributionPoints)); } catch (Exception e) { throw new PkixCertPathValidatorException( "CRL distribution point extension could not be read.", e); } try { PkixCertPathValidatorUtilities .AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX); } catch (Exception e) { throw new PkixCertPathValidatorException( "No additional CRL locations could be decoded from CRL distribution point extension.", e); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); Exception lastException = null; bool validCrlFound = false; // for each distribution point if (crldp != null) { DistributionPoint[] dps = null; try { dps = crldp.GetDistributionPoints(); } catch (Exception e) { throw new PkixCertPathValidatorException( "Distribution points could not be read.", e); } try { for (int i = 0; i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons; i++) { PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX .Clone(); CheckCrl(dps[i], attrCert, paramsPKIXClone, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } } catch (Exception e) { lastException = new Exception( "No valid CRL for distribution point found.", e); } } /* * If the revocation status has not been determined, repeat the * process above with any available CRLs not specified in a * distribution point but issued by the certificate issuer. */ if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons) { try { /* * assume a DP with both the reasons and the cRLIssuer * fields omitted and a distribution point name of the * certificate issuer. */ Asn1Object issuer = null; try { issuer = new Asn1InputStream( attrCert.Issuer.GetPrincipals()[0].GetEncoded()).ReadObject(); } catch (Exception e) { throw new Exception( "Issuer from certificate for CRL could not be reencoded.", e); } DistributionPoint dp = new DistributionPoint( new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.DirectoryName, issuer))), null, null); PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX.Clone(); CheckCrl(dp, attrCert, paramsPKIXClone, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (Exception e) { lastException = new Exception( "No valid CRL for distribution point found.", e); } } if (!validCrlFound) { throw new PkixCertPathValidatorException( "No valid CRL found.", lastException); } if (certStatus.Status != CertStatus.Unrevoked) { // TODO This format is forced by the NistCertPath tests string formattedDate = certStatus.RevocationDate.Value.ToString( "G", new CultureInfo("en-us")); string message = "Attribute certificate revocation after " + formattedDate; message += ", reason: " + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status]; throw new PkixCertPathValidatorException(message); } if (!reasonsMask.IsAllReasons && certStatus.Status == CertStatus.Unrevoked) { certStatus.Status = CertStatus.Undetermined; } if (certStatus.Status == CertStatus.Undetermined) { throw new PkixCertPathValidatorException( "Attribute certificate status could not be determined."); } } else { if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null || attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null) { throw new PkixCertPathValidatorException( "No rev avail extension is set, but also an AC revocation pointer."); } } } }
/** * Checks if an attribute certificate is revoked. * * @param attrCert Attribute certificate to check if it is revoked. * @param paramsPKIX PKIX parameters. * @param issuerCert The issuer certificate of the attribute certificate * <code>attrCert</code>. * @param validDate The date when the certificate revocation status should * be checked. * @param certPathCerts The certificates of the certification path to be * checked. * * @throws CertPathValidatorException if the certificate is revoked or the * status cannot be checked or some error occurs. */ internal static void CheckCrls( IX509AttributeCertificate attrCert, PkixParameters paramsPKIX, X509Certificate issuerCert, DateTime validDate, IList certPathCerts) { if (!paramsPKIX.IsRevocationEnabled) { return; } // check if revocation is available if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null) { if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null || attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null) { throw new PkixCertPathValidatorException( "No rev avail extension is set, but also an AC revocation pointer."); } return; } CrlDistPoint crldp = null; try { crldp = CrlDistPoint.GetInstance( PkixCertPathValidatorUtilities.GetExtensionValue( attrCert, X509Extensions.CrlDistributionPoints)); } catch (Exception e) { throw new PkixCertPathValidatorException( "CRL distribution point extension could not be read.", e); } try { PkixCertPathValidatorUtilities .AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX); } catch (Exception e) { throw new PkixCertPathValidatorException( "No additional CRL locations could be decoded from CRL distribution point extension.", e); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); Exception lastException = null; bool validCrlFound = false; // for each distribution point if (crldp != null) { DistributionPoint[] dps = null; try { dps = crldp.GetDistributionPoints(); } catch (Exception e) { throw new PkixCertPathValidatorException( "Distribution points could not be read.", e); } try { for (int i = 0; i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons; i++) { PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX .Clone(); CheckCrl(dps[i], attrCert, paramsPKIXClone, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } } catch (Exception e) { lastException = new Exception( "No valid CRL for distribution point found.", e); } } /* * If the revocation status has not been determined, repeat the * process above with any available CRLs not specified in a * distribution point but issued by the certificate issuer. */ if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons) { try { /* * assume a DP with both the reasons and the cRLIssuer * fields omitted and a distribution point name of the * certificate issuer. */ X509Name issuer; try { issuer = X509Name.GetInstance(attrCert.Issuer.GetPrincipals()[0].GetEncoded()); } catch (Exception e) { throw new Exception( "Issuer from certificate for CRL could not be reencoded.", e); } DistributionPoint dp = new DistributionPoint( new DistributionPointName(0, new GeneralNames( new GeneralName(GeneralName.DirectoryName, issuer))), null, null); PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone(); CheckCrl(dp, attrCert, paramsPKIXClone, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); validCrlFound = true; } catch (Exception e) { lastException = new Exception( "No valid CRL for distribution point found.", e); } } if (!validCrlFound) { throw new PkixCertPathValidatorException( "No valid CRL found.", lastException); } if (certStatus.Status != CertStatus.Unrevoked) { // This format is enforced by the NistCertPath tests string formattedDate = certStatus.RevocationDate.Value.ToString( "ddd MMM dd HH:mm:ss K yyyy"); string message = "Attribute certificate revocation after " + formattedDate; message += ", reason: " + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status]; throw new PkixCertPathValidatorException(message); } if (!reasonsMask.IsAllReasons && certStatus.Status == CertStatus.Unrevoked) { certStatus.Status = CertStatus.Undetermined; } if (certStatus.Status == CertStatus.Undetermined) { throw new PkixCertPathValidatorException( "Attribute certificate status could not be determined."); } }
internal static void CheckCrls(IX509AttributeCertificate attrCert, PkixParameters paramsPKIX, X509Certificate issuerCert, DateTime validDate, IList certPathCerts) { if (paramsPKIX.IsRevocationEnabled) { if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) == null) { CrlDistPoint crlDistPoint = null; try { crlDistPoint = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(attrCert, X509Extensions.CrlDistributionPoints)); } catch (Exception cause) { throw new PkixCertPathValidatorException("CRL distribution point extension could not be read.", cause); } try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crlDistPoint, paramsPKIX); } catch (Exception cause2) { throw new PkixCertPathValidatorException("No additional CRL locations could be decoded from CRL distribution point extension.", cause2); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); Exception cause3 = null; bool flag = false; if (crlDistPoint != null) { DistributionPoint[] array = null; try { array = crlDistPoint.GetDistributionPoints(); } catch (Exception cause4) { throw new PkixCertPathValidatorException("Distribution points could not be read.", cause4); } try { int num = 0; while (num < array.Length && certStatus.Status == 11 && !reasonsMask.IsAllReasons) { PkixParameters paramsPKIX2 = (PkixParameters)paramsPKIX.Clone(); Rfc3281CertPathUtilities.CheckCrl(array[num], attrCert, paramsPKIX2, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); flag = true; num++; } } catch (Exception innerException) { cause3 = new Exception("No valid CRL for distribution point found.", innerException); } } if (certStatus.Status == 11 && !reasonsMask.IsAllReasons) { try { Asn1Object name = null; try { name = new Asn1InputStream(attrCert.Issuer.GetPrincipals()[0].GetEncoded()).ReadObject(); } catch (Exception innerException2) { throw new Exception("Issuer from certificate for CRL could not be reencoded.", innerException2); } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(new GeneralName(4, name))), null, null); PkixParameters paramsPKIX3 = (PkixParameters)paramsPKIX.Clone(); Rfc3281CertPathUtilities.CheckCrl(dp, attrCert, paramsPKIX3, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); flag = true; } catch (Exception innerException3) { cause3 = new Exception("No valid CRL for distribution point found.", innerException3); } } if (!flag) { throw new PkixCertPathValidatorException("No valid CRL found.", cause3); } if (certStatus.Status != 11) { string str = certStatus.RevocationDate.Value.ToString("ddd MMM dd HH:mm:ss K yyyy"); string text = "Attribute certificate revocation after " + str; text = text + ", reason: " + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status]; throw new PkixCertPathValidatorException(text); } if (!reasonsMask.IsAllReasons && certStatus.Status == 11) { certStatus.Status = 12; } if (certStatus.Status == 12) { throw new PkixCertPathValidatorException("Attribute certificate status could not be determined."); } } else if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null || attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null) { throw new PkixCertPathValidatorException("No rev avail extension is set, but also an AC revocation pointer."); } } }