Example #1
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.Sign;
                    }
                    else                     // (i) or (j) (2)
                    {
                        certStatus.Status = CrlReason.Unspecified;
                    }
                    certStatus.RevocationDate = new DateTimeObject(crl_entry.RevocationDate);
                }
            }
        }
		internal static void ProcessCrlJ(
			DateTime	validDate,
			X509Crl		completecrl,
			object		cert,
			CertStatus	certStatus)
		{
			if (certStatus.Status == CertStatus.Unrevoked)
			{
				PkixCertPathValidatorUtilities.GetCertStatus(validDate, completecrl, cert, certStatus);
			}
		}
		/**
		* Checks a distribution point for revocation information for the
		* certificate <code>cert</code>.
		*
		* @param dp                 The distribution point to consider.
		* @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 defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
		* @param defaultCRLSignKey  The public key of the issuer certificate
		*                           <code>defaultCRLSignCert</code>.
		* @param certStatus         The current certificate revocation status.
		* @param reasonMask         The reasons mask which is already checked.
		* @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.
		*/
		private static void CheckCrl(
			DistributionPoint dp,
			PkixParameters paramsPKIX,
			X509Certificate cert,
			DateTime validDate,
			X509Certificate defaultCRLSignCert,
			AsymmetricKeyParameter defaultCRLSignKey,
			CertStatus certStatus,
			ReasonsMask reasonMask,
			IList certPathCerts)
			//throws AnnotatedException
		{
			DateTime currentDate = DateTime.UtcNow;

			if (validDate.Ticks > currentDate.Ticks)
			{
				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, cert, 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, cert, defaultCRLSignCert, defaultCRLSignKey,
						paramsPKIX, certPathCerts);
					// (g)
					AsymmetricKeyParameter key = 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, key);
					}

					/*
					 * 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 validity 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 (cert.NotAfter.Ticks < crl.ThisUpdate.Ticks)
						{
							throw new Exception("No valid CRL for current time found.");
						}
					}

					Rfc3280CertPathUtilities.ProcessCrlB1(dp, cert, crl);

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

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

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

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

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

					// update reasons mask
					reasonMask.AddReasons(interimReasonsMask);

					ISet criticalExtensions = crl.GetCriticalExtensionOids();

					if (criticalExtensions != null)
					{
						criticalExtensions = new HashSet(criticalExtensions);
						criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id);
						criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id);

						if (!criticalExtensions.IsEmpty)
							throw new Exception("CRL contains unsupported critical extensions.");
					}

					if (deltaCRL != null)
					{
						criticalExtensions = deltaCRL.GetCriticalExtensionOids();
						if (criticalExtensions != null)
						{
							criticalExtensions = new HashSet(criticalExtensions);
							criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id);
							criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id);

							if (!criticalExtensions.IsEmpty)
								throw new Exception("Delta CRL contains unsupported critical extension.");
						}
					}

					validCrlFound = true;
				}
				catch (Exception e)
				{
					lastException = e;
				}
			}
			if (!validCrlFound)
			{
				throw lastException;
			}
		}
		/**
		 * 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", new CultureInfo("en-us"));
				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.");
			}
		}
		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);
			}
		}
		/**
		* 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 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;
			}
		}
		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);
				}
			}
		}
Example #9
0
        /**
         * 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.");
                    }
                }
            }
        }
Example #10
0
        /**
         *
         * 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;
            }
        }