Inheritance: X509ExtensionBase
        /// <summary>
        /// Import the specified certificate revocation list.
        /// </summary>
        /// <param name="crl">The certificate revocation list.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="crl"/> is <c>null</c>.
        /// </exception>
        public override void Import(X509Crl crl)
        {
            if (crl == null)
                throw new ArgumentNullException ("crl");

            crls.Add (crl);
        }
        /**
        * 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);
                    }
                }
            }
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.Cryptography.X509CrlRecord"/> class.
        /// </summary>
        /// <param name="crl">Crl.</param>
        public X509CrlRecord(X509Crl crl)
        {
            if (crl == null)
                throw new ArgumentNullException ("crl");

            if (crl.NextUpdate != null)
                NextUpdate = crl.NextUpdate.Value;

            IssuerName = crl.IssuerDN.ToString ();
            ThisUpdate = crl.ThisUpdate;
            IsDelta = crl.IsDelta ();
            Crl = crl;
        }
Beispiel #5
0
        public Crl(byte[] crlBytes)
        {
            _crl = new X509CrlParser().ReadCrl(crlBytes);
            try
            {
                _crl.GetSignature();
            }
            catch (Exception)
            {
                throw new InvalidOperationException("Error parsing CRL");

            }
        }
        private long?GetCRLNumber(Org.BouncyCastle.X509.X509Crl crlEntry)
        {
            Asn1OctetString extValue = crlEntry.GetExtensionValue(X509Extensions.CrlNumber);

            if (extValue != null)
            {
                Asn1Object asn1Value = X509ExtensionUtilities.FromExtensionValue(extValue);

                return(DerInteger.GetInstance(asn1Value).PositiveValue.LongValue);
            }

            return(null);
        }
		/// <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);
			}
		}
Beispiel #8
0
		/// <param name="crl"></param>
		/// <returns></returns>
		public virtual bool Match(X509Crl crl)
		{
			try
			{				
                byte[] computedValue = DigestUtilities.CalculateDigest
                    (algorithm, crl.GetEncoded());             
				return Arrays.Equals(digestValue, computedValue);
			}
			catch (NoSuchAlgorithmException ex)
			{
				throw new RuntimeException("Maybe BouncyCastle provider is not installed ?", ex);
			}
			catch (CrlException ex)
			{
				throw new RuntimeException(ex);
			}
		}
Beispiel #9
0
        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());
        }
        public void AddCrl(X509Crl other)
        {
            //IL_0008: Unknown result type (might be due to invalid IL or missing references)
            //IL_004b: Expected O, but got Unknown
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }
            ISet revokedCertificates = other.GetRevokedCertificates();

            if (revokedCertificates == null)
            {
                return;
            }
            global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)revokedCertificates).GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    X509CrlEntry x509CrlEntry = (X509CrlEntry)enumerator.get_Current();
                    try
                    {
                        tbsGen.AddCrlEntry(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(x509CrlEntry.GetEncoded())));
                    }
                    catch (IOException val)
                    {
                        IOException e = val;
                        throw new CrlException("exception processing encoding of CRL", (global::System.Exception)(object) e);
                    }
                }
            }
            finally
            {
                global::System.IDisposable disposable = enumerator as global::System.IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
        public void AddCrl(X509Crl other)
        {
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }
            ISet revokedCertificates = other.GetRevokedCertificates();

            if (revokedCertificates != null)
            {
                foreach (X509CrlEntry x509CrlEntry in revokedCertificates)
                {
                    try
                    {
                        this.tbsGen.AddCrlEntry(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(x509CrlEntry.GetEncoded())));
                    }
                    catch (IOException e)
                    {
                        throw new CrlException("exception processing encoding of CRL", e);
                    }
                }
            }
        }
        public override bool Equals(object other)
        {
            if (this == other)
            {
                return(true);
            }

            X509Crl that = other as X509Crl;

            if (null == that)
            {
                return(false);
            }

            if (this.hashValueSet && that.hashValueSet)
            {
                if (this.hashValue != that.hashValue)
                {
                    return(false);
                }
            }
            else if (null == this.cachedEncoding || null == that.cachedEncoding)
            {
                DerBitString signature = c.Signature;
                if (null != signature && !signature.Equals(that.c.Signature))
                {
                    return(false);
                }
            }

            byte[] thisEncoding = this.GetCachedEncoding().Encoding;
            byte[] thatEncoding = that.GetCachedEncoding().Encoding;

            return(null != thisEncoding &&
                   null != thatEncoding &&
                   Arrays.AreEqual(thisEncoding, thatEncoding));
        }
		/**
		 * 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)
			{
				throw 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)
					{
						throw 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);
				}
			}
		}
Beispiel #15
0
 /**
 * Verifies a certificate chain against a KeyStore.
 * @param certs the certificate chain
 * @param keystore the <CODE>KeyStore</CODE>
 * @param crls the certificate revocation list or <CODE>null</CODE>
 * @param calendar the date or <CODE>null</CODE> for the current date
 * @return <CODE>null</CODE> if the certificate chain could be validade or a
 * <CODE>Object[]{cert,error}</CODE> where <CODE>cert</CODE> is the
 * failed certificate and <CODE>error</CODE> is the error message
 */    
 public static Object[] VerifyCertificates(X509Certificate[] certs, List<X509Certificate> keystore, X509Crl[] crls, DateTime calendar) {
     for (int k = 0; k < certs.Length; ++k) {
         X509Certificate cert = certs[k];
         String err = VerifyCertificate(cert, crls, calendar);
         if (err != null)
             return new Object[]{cert, err};
         foreach (X509Certificate certStoreX509 in keystore) {
             try {
                 if (VerifyCertificate(certStoreX509, crls, calendar) != null)
                     continue;
                 try {
                     cert.Verify(certStoreX509.GetPublicKey());
                     return null;
                 }
                 catch {
                     continue;
                 }
             }
             catch {
             }
         }
         int j;
         for (j = 0; j < certs.Length; ++j) {
             if (j == k)
                 continue;
             X509Certificate certNext = certs[j];
             try {
                 cert.Verify(certNext.GetPublicKey());
                 break;
             }
             catch {
             }
         }
         if (j == certs.Length)
             return new Object[]{cert, "Cannot be verified against the KeyStore or the certificate chain"};
     }
     return new Object[]{null, "Invalid state. Possible circular certificate chain"};
 }
		internal static void ProcessCrlJ(
			DateTime	validDate,
			X509Crl		completecrl,
			object		cert,
			CertStatus	certStatus)
		{
			if (certStatus.Status == CertStatus.Unrevoked)
			{
				PkixCertPathValidatorUtilities.GetCertStatus(validDate, completecrl, 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[] 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 };
		}
 /**
  * Verifies a certificate against a single CRL.
  * @param crl	the Certificate Revocation List
  * @param signCert	a certificate that needs to be verified
  * @param issuerCert	its issuer
  * @param signDate		the sign date
  * @return true if the verification succeeded
  * @throws GeneralSecurityException
  */
 public bool Verify(X509Crl crl, X509Certificate signCert, X509Certificate issuerCert, DateTime signDate)
 {
     if (crl == null || signDate == DateTime.MaxValue)
         return false;
     // We only check CRLs valid on the signing date for which the issuer matches
     if (crl.IssuerDN.Equals(signCert.IssuerDN)
         && signDate.CompareTo(crl.ThisUpdate) > 0 && signDate.CompareTo(crl.NextUpdate.Value) < 0) {
         // the signing certificate may not be revoked
         if (IsSignatureValid(crl, issuerCert) && crl.IsRevoked(signCert)) {
             throw new VerificationException(signCert, String.Format("{0} The certificate has been revoked.", signCert));
         }
         return true;
     }
     return false;
 }
Beispiel #20
0
		/// <summary>
		/// Gets the database command to select the record for the specified CRL.
		/// </summary>
		/// <remarks>
		/// Gets the database command to select the record for the specified CRL.
		/// </remarks>
		/// <returns>The database command.</returns>
		/// <param name="crl">The X.509 CRL.</param>
		/// <param name="fields">The fields to return.</param>
		protected override DbCommand GetSelectCommand (X509Crl crl, X509CrlRecordFields fields)
		{
			var query = "SELECT " + string.Join (", ", GetColumnNames (fields)) + " FROM CRLS ";
			var issuerName = crl.IssuerDN.ToString ();
			var command = connection.CreateCommand ();

			command.CommandText = query + "WHERE DELTA = @DELTA AND ISSUERNAME = @ISSUERNAME AND THISUPDATE = @THISUPDATE LIMIT 1";
			command.AddParameterWithValue ("@DELTA", crl.IsDelta ());
			command.AddParameterWithValue ("@ISSUERNAME", issuerName);
			command.AddParameterWithValue ("@THISUPDATE", crl.ThisUpdate);
			command.CommandType = CommandType.Text;

			return command;
		}
    /// <summary>
    /// Revoke the CA signed certificate.
    /// The issuer CA public key, the private key and the crl reside in the storepath.
    /// The CRL number is increased by one and existing CRL for the issuer are deleted from the store.
    /// </summary>
    public static async Task RevokeCertificateAsync(
        string storePath,
        X509Certificate2 certificate,
        string issuerKeyFilePassword = null
        )
    {
        try
        {
            string subjectName  = certificate.IssuerName.Name;
            string keyId        = null;
            string serialNumber = null;

            // caller may want to create empty CRL using the CA cert itself
            bool isCACert = IsCertificateAuthority(certificate);

            // find the authority key identifier.
            X509AuthorityKeyIdentifierExtension authority = FindAuthorityKeyIdentifier(certificate);

            if (authority != null)
            {
                keyId        = authority.KeyId;
                serialNumber = authority.SerialNumber;
            }
            else
            {
                throw new ArgumentException("Certificate does not contain an Authority Key");
            }

            if (!isCACert)
            {
                if (serialNumber == certificate.SerialNumber ||
                    Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer))
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Cannot revoke self signed certificates");
                }
            }

            X509Certificate2 certCA = null;
            using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(storePath))
            {
                if (store == null)
                {
                    throw new ArgumentException("Invalid store path/type");
                }
                certCA = await FindIssuerCABySerialNumberAsync(store, certificate.Issuer, serialNumber);

                if (certCA == null)
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Cannot find issuer certificate in store.");
                }

                if (!certCA.HasPrivateKey)
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer certificate has no private key, cannot revoke certificate.");
                }

                CertificateIdentifier certCAIdentifier = new CertificateIdentifier(certCA);
                certCAIdentifier.StorePath = storePath;
                certCAIdentifier.StoreType = CertificateStoreIdentifier.DetermineStoreType(storePath);
                X509Certificate2 certCAWithPrivateKey = await certCAIdentifier.LoadPrivateKey(issuerKeyFilePassword);

                if (certCAWithPrivateKey == null)
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Failed to load issuer private key. Is the password correct?");
                }

                List <X509CRL> certCACrl = store.EnumerateCRLs(certCA, false);

                using (var cfrg = new CertificateFactoryRandomGenerator())
                {
                    // cert generators
                    SecureRandom random          = new SecureRandom(cfrg);
                    BigInteger   crlSerialNumber = BigInteger.Zero;

                    Org.BouncyCastle.X509.X509Certificate bcCertCA = new X509CertificateParser().ReadCertificate(certCA.RawData);
                    AsymmetricKeyParameter signingKey = GetPrivateKeyParameter(certCAWithPrivateKey);

                    ISignatureFactory signatureFactory =
                        new Asn1SignatureFactory(GetRSAHashAlgorithm(defaultHashSize), signingKey, random);

                    X509V2CrlGenerator crlGen = new X509V2CrlGenerator();
                    crlGen.SetIssuerDN(bcCertCA.IssuerDN);
                    crlGen.SetThisUpdate(DateTime.UtcNow);
                    crlGen.SetNextUpdate(DateTime.UtcNow.AddMonths(12));

                    // merge all existing revocation list
                    X509CrlParser parser = new X509CrlParser();
                    foreach (X509CRL caCrl in certCACrl)
                    {
                        X509Crl crl = parser.ReadCrl(caCrl.RawData);
                        crlGen.AddCrl(crl);
                        var crlVersion = GetCrlNumber(crl);
                        if (crlVersion.IntValue > crlSerialNumber.IntValue)
                        {
                            crlSerialNumber = crlVersion;
                        }
                    }

                    if (isCACert)
                    {
                        // add a dummy revoked cert
                        crlGen.AddCrlEntry(BigInteger.One, DateTime.UtcNow, CrlReason.Superseded);
                    }
                    else
                    {
                        // add the revoked cert
                        crlGen.AddCrlEntry(GetSerialNumber(certificate), DateTime.UtcNow, CrlReason.PrivilegeWithdrawn);
                    }

                    crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier,
                                        false,
                                        new AuthorityKeyIdentifierStructure(bcCertCA));

                    // set new serial number
                    crlSerialNumber = crlSerialNumber.Add(BigInteger.One);
                    crlGen.AddExtension(X509Extensions.CrlNumber,
                                        false,
                                        new CrlNumber(crlSerialNumber));

                    // generate updated CRL
                    Org.BouncyCastle.X509.X509Crl updatedCrl = crlGen.Generate(signatureFactory);

                    // add updated CRL to store
                    X509CRL updatedCRL = new X509CRL(updatedCrl.GetEncoded());
                    store.AddCRL(updatedCRL);

                    // delete outdated CRLs from store
                    foreach (X509CRL caCrl in certCACrl)
                    {
                        store.DeleteCRL(caCrl);
                    }
                }
                store.Close();
            }
        }
        catch (Exception e)
        {
            throw e;
        }
    }
        /// <summary>
        /// Import the specified certificate revocation list.
        /// </summary>
        /// <param name="crl">The certificate revocation list.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="crl"/> is <c>null</c>.
        /// </exception>
        public override void Import(X509Crl crl)
        {
            if (crl == null)
                throw new ArgumentNullException ("crl");

            // FIXME: implement this
        }
		private static bool isDeltaCrl(
			X509Crl crl)
		{
			ISet critical = crl.GetCriticalExtensionOids();

			return critical.Contains(X509Extensions.DeltaCrlIndicator.Id);
		}
 /**
  * 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;
 }
		/**
		* 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;
		}
 /// <summary>
 /// Import the specified certificate revocation list.
 /// </summary>
 /// <param name="crl">The certificate revocation list.</param>
 /// <exception cref="System.ArgumentNullException">
 /// <paramref name="crl"/> is <c>null</c>.
 /// </exception>
 public abstract void Import(X509Crl crl);
		/**
		* 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.");
				}
			}
		}
		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;
		}
		private BigInteger GetCrlNumber(X509Crl crl)
		{
			//byte[] crlNumberExtensionValue = crl.GetExtensionValue(X509Extensions.CrlNumber);
            Asn1OctetString crlNumberExtensionValue = crl.GetExtensionValue(X509Extensions.CrlNumber);
			if (null == crlNumberExtensionValue)
			{
				return null;
			}
			try
			{
                //DerOctetString octetString = (DerOctetString)(new ASN1InputStream(new ByteArrayInputStream
                //    (crlNumberExtensionValue)).ReadObject());
                DerOctetString octetString = (DerOctetString)crlNumberExtensionValue;
				byte[] octets = octetString.GetOctets();
				DerInteger integer = (DerInteger)new Asn1InputStream(octets).ReadObject();
				BigInteger crlNumber = integer.PositiveValue;
				return crlNumber;
			}
			catch (IOException e)
			{
				throw new RuntimeException("IO error: " + e.Message, e);
			}
		}
		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);
			}
		}
		/// <summary>
		/// Finds the specified certificate revocation list.
		/// </summary>
		/// <remarks>
		/// Searches the database for the specified CRL, returning the matching record with
		/// the desired fields populated.
		/// </remarks>
		/// <returns>The matching record if found; otherwise <c>null</c>.</returns>
		/// <param name="crl">The certificate revocation list.</param>
		/// <param name="fields">The desired fields.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="crl"/> is <c>null</c>.
		/// </exception>
		public X509CrlRecord Find (X509Crl crl, X509CrlRecordFields fields)
		{
			if (crl == null)
				throw new ArgumentNullException ("crl");

			using (var command = GetSelectCommand (crl, fields)) {
				var reader = command.ExecuteReader ();

				try {
					if (reader.Read ()) {
						var parser = new X509CrlParser ();
						var buffer = new byte[4096];

						return LoadCrlRecord (reader, parser, ref buffer);
					}
				} finally {
					reader.Close ();
				}
			}

			return null;
		}
		/**
		* 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 (Org.BouncyCastle.Utilities.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.");
			}
		}
Beispiel #33
0
        /**
        * Loads the default root certificates at &lt;java.home&gt;/lib/security/cacerts
        * with the default provider.
        * @return a <CODE>KeyStore</CODE>
        */    
//        public static KeyStore LoadCacertsKeyStore() {
//            return LoadCacertsKeyStore(null);
//        }

        /**
        * Loads the default root certificates at &lt;java.home&gt;/lib/security/cacerts.
        * @param provider the provider or <code>null</code> for the default provider
        * @return a <CODE>KeyStore</CODE>
        */    
//        public static KeyStore LoadCacertsKeyStore(String provider) {
//            File file = new File(System.GetProperty("java.home"), "lib");
//            file = new File(file, "security");
//            file = new File(file, "cacerts");
//            FileInputStream fin = null;
//            try {
//                fin = new FileInputStream(file);
//                KeyStore k;
//                if (provider == null)
//                    k = KeyStore.GetInstance("JKS");
//                else
//                    k = KeyStore.GetInstance("JKS", provider);
//                k.Load(fin, null);
//                return k;
//            }
//            catch (Exception e) {
//                throw new ExceptionConverter(e);
//            }
//            finally {
//                try{fin.Close();}catch(Exception ex){}
//            }
//        }
        
        /**
        * Verifies a single certificate.
        * @param cert the certificate to verify
        * @param crls the certificate revocation list or <CODE>null</CODE>
        * @param calendar the date or <CODE>null</CODE> for the current date
        * @return a <CODE>String</CODE> with the error description or <CODE>null</CODE>
        * if no error
        */    
        public static String VerifyCertificate(X509Certificate cert, X509Crl[] crls, DateTime calendar) {
            try {
                if (!cert.IsValid(calendar))
                    return "The certificate has expired or is not yet valid";
            }
            catch (Exception e) {
                return e.ToString();
            }
            return null;
        }
		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);
		}
		/// <summary>
		/// Gets the database command to select the record for the specified CRL.
		/// </summary>
		/// <remarks>
		/// Gets the database command to select the record for the specified CRL.
		/// </remarks>
		/// <returns>The database command.</returns>
		/// <param name="crl">The X.509 CRL.</param>
		/// <param name="fields">The fields to return.</param>
		protected abstract IDbCommand GetSelectCommand (X509Crl crl, X509CrlRecordFields fields);
		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);
		}
		/// <summary>
		/// Import the specified certificate revocation list.
		/// </summary>
		/// <remarks>
		/// Import the specified certificate revocation list.
		/// </remarks>
		/// <param name="crl">The certificate revocation list.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="crl"/> is <c>null</c>.
		/// </exception>
		public override void Import (X509Crl crl)
		{
			if (crl == null)
				throw new ArgumentNullException ("crl");

			// TODO: figure out where to store the CRLs...
		}