/**
         *
         * Checks a distribution point for revocation information for the
         * certificate <code>attrCert</code>.
         *
         * @param dp The distribution point to consider.
         * @param attrCert The attribute certificate which should be checked.
         * @param paramsPKIX PKIX parameters.
         * @param validDate The date when the certificate revocation status should
         *            be checked.
         * @param issuerCert Certificate to check if it is revoked.
         * @param reasonMask The reasons mask which is already checked.
         * @param certPathCerts The certificates of the certification path to be
         *            checked.
         * @throws Exception if the certificate is revoked or the status
         *             cannot be checked or some error occurs.
         */
        private static void CheckCrl(
            DistributionPoint dp,
            IX509AttributeCertificate attrCert,
            PkixParameters paramsPKIX,
            DateTime validDate,
            X509Certificate issuerCert,
            CertStatus certStatus,
            ReasonsMask reasonMask,
            IList certPathCerts)
        {
            /*
             * 4.3.6 No Revocation Available
             *
             * The noRevAvail extension, defined in [X.509-2000], allows an AC
             * issuer to indicate that no revocation information will be made
             * available for this AC.
             */
            if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
            {
                return;
            }

            DateTime currentDate = DateTime.UtcNow;

            if (validDate.CompareTo(currentDate) > 0)
            {
                throw new Exception("Validation time is in future.");
            }

            // (a)

            /*
             * We always get timely valid CRLs, so there is no step (a) (1).
             * "locally cached" CRLs are assumed to be in getStore(), additional
             * CRLs must be enabled in the ExtendedPkixParameters and are in
             * getAdditionalStore()
             */
            ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert,
                                                                       currentDate, paramsPKIX);
            bool      validCrlFound = false;
            Exception lastException = null;

            IEnumerator crl_iter = crls.GetEnumerator();

            while (crl_iter.MoveNext() &&
                   certStatus.Status == CertStatus.Unrevoked &&
                   !reasonMask.IsAllReasons)
            {
                try
                {
                    X509Crl crl = (X509Crl)crl_iter.Current;

                    // (d)
                    ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp);

                    // (e)

                    /*
                     * The reasons mask is updated at the end, so only valid CRLs
                     * can update it. If this CRL does not contain new reasons it
                     * must be ignored.
                     */
                    if (!interimReasonsMask.HasNewReasons(reasonMask))
                    {
                        continue;
                    }

                    // (f)
                    ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert,
                                                                     null, null, paramsPKIX, certPathCerts);
                    // (g)
                    AsymmetricKeyParameter pubKey = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys);

                    X509Crl deltaCRL = null;

                    if (paramsPKIX.IsUseDeltasEnabled)
                    {
                        // get delta CRLs
                        ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(
                            currentDate, paramsPKIX, crl);
                        // we only want one valid delta CRL
                        // (h)
                        deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, pubKey);
                    }

                    /*
                     * CRL must be be valid at the current time, not the validation
                     * time. If a certificate is revoked with reason keyCompromise,
                     * cACompromise, it can be used for forgery, also for the past.
                     * This reason may not be contained in older CRLs.
                     */

                    /*
                     * in the chain model signatures stay valid also after the
                     * certificate has been expired, so they do not have to be in
                     * the CRL vality time
                     */
                    if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel)
                    {
                        /*
                         * if a certificate has expired, but was revoked, it is not
                         * more in the CRL, so it would be regarded as valid if the
                         * first check is not done
                         */
                        if (attrCert.NotAfter.CompareTo(crl.ThisUpdate) < 0)
                        {
                            throw new Exception(
                                      "No valid CRL for current time found.");
                        }
                    }

                    Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, crl);

                    // (b) (2)
                    Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, crl);

                    // (c)
                    Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX);

                    // (i)
                    Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL,
                                                         attrCert, certStatus, paramsPKIX);

                    // (j)
                    Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, attrCert,
                                                         certStatus);

                    // (k)
                    if (certStatus.Status == CrlReason.RemoveFromCrl)
                    {
                        certStatus.Status = CertStatus.Unrevoked;
                    }

                    // update reasons mask
                    reasonMask.AddReasons(interimReasonsMask);
                    validCrlFound = true;
                }
                catch (Exception e)
                {
                    lastException = e;
                }
            }
            if (!validCrlFound)
            {
                throw lastException;
            }
        }
        /**
         * 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.");
                    }
                }
            }
        }
Exemple #3
0
        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.SignValue;
                    }
                    else                     // (i) or (j) (2)
                    {
                        certStatus.Status = CrlReason.Unspecified;
                    }
                    certStatus.RevocationDate = new DateTimeObject(crl_entry.RevocationDate);
                }
            }
        }