Exemplo n.º 1
0
		/// <summary>
		/// Intersects this mask with the given reasons mask.
		/// </summary>
		/// <param name="mask">mask The mask to intersect with.</param>
		/// <returns>The intersection of this and teh given mask.</returns>
		internal ReasonsMask Intersect(
			ReasonsMask mask)
		{
			ReasonsMask _mask = new ReasonsMask();
			_mask.AddReasons(new ReasonsMask(_reasons & mask.Reasons.IntValue));
			return _mask;
		}
Exemplo n.º 2
0
        /// <summary>
        /// Intersects this mask with the given reasons mask.
        /// </summary>
        /// <param name="mask">mask The mask to intersect with.</param>
        /// <returns>The intersection of this and teh given mask.</returns>
        internal ReasonsMask Intersect(
            ReasonsMask mask)
        {
            ReasonsMask _mask = new ReasonsMask();

            _mask.AddReasons(new ReasonsMask(_reasons & mask.Reasons.IntValue));
            return(_mask);
        }
		/**
		* 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;
			}
		}
		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);
		}
		/**
		 * 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.");
			}
		}
		/**
		* 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;
			}
		}
Exemplo n.º 8
0
 /// <summary>
 /// Returns <c>true</c> if the passed reasons mask has new reasons.
 /// </summary>
 /// <param name="mask">The reasons mask which should be tested for new reasons.</param>
 /// <returns><c>true</c> if the passed reasons mask has new reasons.</returns>
 internal bool HasNewReasons(
     ReasonsMask mask)
 {
     return((_reasons | mask.Reasons.IntValue ^ _reasons) != 0);
 }
Exemplo n.º 9
0
 /**
  * Adds all reasons from the reasons mask to this mask.
  *
  * @param mask The reasons mask to add.
  */
 internal void AddReasons(
     ReasonsMask mask)
 {
     _reasons = _reasons | mask.Reasons.IntValue;
 }
Exemplo n.º 10
0
		/// <summary>
		/// Returns <c>true</c> if the passed reasons mask has new reasons.
		/// </summary>
		/// <param name="mask">The reasons mask which should be tested for new reasons.</param>
		/// <returns><c>true</c> if the passed reasons mask has new reasons.</returns>
		internal bool HasNewReasons(
			ReasonsMask mask)
		{
			return ((_reasons | mask.Reasons.IntValue ^ _reasons) != 0);
		}
Exemplo n.º 11
0
		/**
		 * Adds all reasons from the reasons mask to this mask.
		 *
		 * @param mask The reasons mask to add.
		 */
		internal void AddReasons(
			ReasonsMask mask)
		{
			_reasons = _reasons | mask.Reasons.IntValue;
		}
Exemplo n.º 12
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.");
                    }
                }
            }
        }
Exemplo n.º 13
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;
            }
        }