Rfc3281CertPathUtilities.cs :  » PDF » iTextSharp » Org » BouncyCastle » Pkix » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » PDF » iTextSharp 
iTextSharp » Org » BouncyCastle » Pkix » Rfc3281CertPathUtilities.cs
using System;
using System.Collections;
using System.Globalization;
using System.IO;

using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Store;

namespace Org.BouncyCastle.Pkix{
  internal class Rfc3281CertPathUtilities
  {
    internal static void ProcessAttrCert7(
      IX509AttributeCertificate  attrCert,
      PkixCertPath        certPath,
      PkixCertPath        holderCertPath,
      PkixParameters        pkixParams)
    {
      // TODO:
      // AA Controls
      // Attribute encryption
      // Proxy
      ISet critExtOids = attrCert.GetCriticalExtensionOids();

      // 7.1
      // process extensions

      // target information checked in step 6 / X509AttributeCertStoreSelector
      if (critExtOids.Contains(X509Extensions.TargetInformation.Id))
      {
        try
        {
          TargetInformation.GetInstance(PkixCertPathValidatorUtilities
            .GetExtensionValue(attrCert, X509Extensions.TargetInformation));
        }
        catch (Exception e)
        {
          throw new PkixCertPathValidatorException(
            "Target information extension could not be read.", e);
        }
      }
      critExtOids.Remove(X509Extensions.TargetInformation.Id);
      foreach (PkixAttrCertChecker checker in pkixParams.GetAttrCertCheckers())
      {
        checker.Check(attrCert, certPath, holderCertPath, critExtOids);
      }
      if (!critExtOids.IsEmpty)
      {
        throw new PkixCertPathValidatorException(
          "Attribute certificate contains unsupported critical extensions: "
            + critExtOids);
      }
    }

    /**
    * 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", CultureInfo.CreateSpecificCulture("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.");
          }
        }
      }
    }

    internal static void AdditionalChecks(
      IX509AttributeCertificate  attrCert,
      PkixParameters        pkixParams)
    {
      // 1
      foreach (string oid in pkixParams.GetProhibitedACAttributes())
      {
        if (attrCert.GetAttributes(oid) != null)
        {
          throw new PkixCertPathValidatorException(
            "Attribute certificate contains prohibited attribute: "
              + oid + ".");
        }
      }
      foreach (string oid in pkixParams.GetNecessaryACAttributes())
      {
        if (attrCert.GetAttributes(oid) == null)
        {
          throw new PkixCertPathValidatorException(
            "Attribute certificate does not contain necessary attribute: "
              + oid + ".");
        }
      }
    }

    internal static void ProcessAttrCert5(
      IX509AttributeCertificate  attrCert,
      PkixParameters        pkixParams)
    {
      try
      {
        attrCert.CheckValidity(PkixCertPathValidatorUtilities.GetValidDate(pkixParams));
      }
      catch (CertificateExpiredException e)
      {
        throw new PkixCertPathValidatorException(
          "Attribute certificate is not valid.", e);
      }
      catch (CertificateNotYetValidException e)
      {
        throw new PkixCertPathValidatorException(
          "Attribute certificate is not valid.", e);
      }
    }

    internal static void ProcessAttrCert4(
      X509Certificate  acIssuerCert,
      PkixParameters  pkixParams)
    {
      ISet set = pkixParams.GetTrustedACIssuers();
      bool trusted = false;
      foreach (TrustAnchor anchor in set)
      {
        if (acIssuerCert.SubjectDN.ToString(false, X509Name.RFC2253Symbols)
          .Equals(anchor.CAName)
          || acIssuerCert.Equals(anchor.TrustedCert))
        {
          trusted = true;
        }
      }
      if (!trusted)
      {
        throw new PkixCertPathValidatorException(
          "Attribute certificate issuer is not directly trusted.");
      }
    }

    internal static void ProcessAttrCert3(
      X509Certificate  acIssuerCert,
      PkixParameters  pkixParams)
    {
      if (acIssuerCert.GetKeyUsage() != null
        && (!acIssuerCert.GetKeyUsage()[0] && !acIssuerCert.GetKeyUsage()[1]))
      {
        throw new PkixCertPathValidatorException(
          "Attribute certificate issuer public key cannot be used to validate digital signatures.");
      }
      if (acIssuerCert.GetBasicConstraints() != -1)
      {
        throw new PkixCertPathValidatorException(
          "Attribute certificate issuer is also a public key certificate issuer.");
      }
    }

    internal static PkixCertPathValidatorResult ProcessAttrCert2(
      PkixCertPath  certPath,
      PkixParameters  pkixParams)
    {
      PkixCertPathValidator validator = new PkixCertPathValidator();

      try
      {
        return validator.Validate(certPath, pkixParams);
      }
      catch (PkixCertPathValidatorException e)
      {
        throw new PkixCertPathValidatorException(
          "Certification path for issuer certificate of attribute certificate could not be validated.",
          e);
      }
    }

    /**
    * Searches for a holder public key certificate and verifies its
    * certification path.
    * 
    * @param attrCert the attribute certificate.
    * @param pkixParams The PKIX parameters.
    * @return The certificate path of the holder certificate.
    * @throws Exception if
    *             <ul>
    *             <li>no public key certificate can be found although holder
    *             information is given by an entity name or a base certificate
    *             ID</li>
    *             <li>support classes cannot be created</li>
    *             <li>no certification path for the public key certificate can
    *             be built</li>
    *             </ul>
    */
    internal static PkixCertPath ProcessAttrCert1(
      IX509AttributeCertificate  attrCert,
      PkixParameters        pkixParams)
    {
      PkixCertPathBuilderResult result = null;
      // find holder PKCs
      ISet holderPKCs = new HashSet();
      if (attrCert.Holder.GetIssuer() != null)
      {
        X509CertStoreSelector selector = new X509CertStoreSelector();
        selector.SerialNumber = attrCert.Holder.SerialNumber;
        X509Name[] principals = attrCert.Holder.GetIssuer();
        for (int i = 0; i < principals.Length; i++)
        {
          try
          {
//            if (principals[i] is X500Principal)
            {
              selector.Issuer = principals[i];
            }
            holderPKCs.AddAll(PkixCertPathValidatorUtilities
              .FindCertificates(selector, pkixParams.GetStores()));
          }
          catch (Exception e)
          {
            throw new PkixCertPathValidatorException(
              "Public key certificate for attribute certificate cannot be searched.",
              e);
          }
        }
        if (holderPKCs.IsEmpty)
        {
          throw new PkixCertPathValidatorException(
            "Public key certificate specified in base certificate ID for attribute certificate cannot be found.");
        }
      }
      if (attrCert.Holder.GetEntityNames() != null)
      {
        X509CertStoreSelector selector = new X509CertStoreSelector();
        X509Name[] principals = attrCert.Holder.GetEntityNames();
        for (int i = 0; i < principals.Length; i++)
        {
          try
          {
//            if (principals[i] is X500Principal)
            {
              selector.Issuer = principals[i];
            }
            holderPKCs.AddAll(PkixCertPathValidatorUtilities
              .FindCertificates(selector, pkixParams.GetStores()));
          }
          catch (Exception e)
          {
            throw new PkixCertPathValidatorException(
              "Public key certificate for attribute certificate cannot be searched.",
              e);
          }
        }
        if (holderPKCs.IsEmpty)
        {
          throw new PkixCertPathValidatorException(
            "Public key certificate specified in entity name for attribute certificate cannot be found.");
        }
      }

      // verify cert paths for PKCs
      PkixBuilderParameters parameters = (PkixBuilderParameters)
        PkixBuilderParameters.GetInstance(pkixParams);

      PkixCertPathValidatorException lastException = null;
      foreach (X509Certificate cert in holderPKCs)
      {
        X509CertStoreSelector selector = new X509CertStoreSelector();
        selector.Certificate = cert;
        parameters.SetTargetConstraints(selector);

        PkixCertPathBuilder builder = new PkixCertPathBuilder();

        try
        {
          result = builder.Build(PkixBuilderParameters.GetInstance(parameters));
        }
        catch (PkixCertPathBuilderException e)
        {
          lastException = new PkixCertPathValidatorException(
            "Certification path for public key certificate of attribute certificate could not be build.",
            e);
        }
      }
      if (lastException != null)
      {
        throw lastException;
      }
      return result.CertPath;
    }

    /**
    * 
    * 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;
      }
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.