public PkixCertPathBuilderResult(
            PkixCertPath certPath,
            TrustAnchor trustAnchor,
            PkixPolicyNode policyTree,
            AsymmetricKeyParameter subjectPublicKey)
            : base(trustAnchor, policyTree, subjectPublicKey)
        {
            if (certPath == null)
            {
                throw new ArgumentNullException("certPath");
            }

            this.certPath = certPath;
        }
Example #2
0
        internal static DateTime GetValidCertDateFromValidityModel(
            PkixParameters paramsPkix,
            PkixCertPath certPath,
            int index)
        {
            if (paramsPkix.ValidityModel != PkixParameters.ChainValidityModel)
            {
                return(GetValidDate(paramsPkix));
            }

            // if end cert use given signing/encryption/... time
            if (index <= 0)
            {
                return(PkixCertPathValidatorUtilities.GetValidDate(paramsPkix));
                // else use time when previous cert was created
            }

            if (index - 1 == 0)
            {
                DerGeneralizedTime dateOfCertgen = null;
                try
                {
                    X509Certificate cert   = (X509Certificate)certPath.Certificates[index - 1];
                    Asn1OctetString extVal = cert.GetExtensionValue(
                        IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen);
                    dateOfCertgen = DerGeneralizedTime.GetInstance(extVal);
                }
                catch (ArgumentException)
                {
                    throw new Exception(
                              "Date of cert gen extension could not be read.");
                }
                if (dateOfCertgen != null)
                {
                    try
                    {
                        return(dateOfCertgen.ToDateTime());
                    }
                    catch (ArgumentException e)
                    {
                        throw new Exception(
                                  "Date from date of cert gen extension could not be parsed.",
                                  e);
                    }
                }
            }

            return(((X509Certificate)certPath.Certificates[index - 1]).NotBefore);
        }
        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);
            }
        }
Example #4
0
        /**
         * Compares this certification path for equality with the specified object.
         * Two CertPaths are equal if and only if their types are equal and their
         * certificate Lists (and by implication the Certificates in those Lists)
         * are equal. A CertPath is never equal to an object that is not a CertPath.<br />
         * <br />
         * This algorithm is implemented by this method. If it is overridden, the
         * behavior specified here must be maintained.
         *
         * @param other
         *            the object to test for equality with this certification path
         *
         * @return true if the specified object is equal to this certification path,
         *         false otherwise
         *
         * @see Object#hashCode() Object.hashCode()
         */
        public override bool Equals(
            object obj)
        {
            if (this == obj)
            {
                return(true);
            }

            PkixCertPath other = obj as PkixCertPath;

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

//			if (!this.Type.Equals(other.Type))
//				return false;

            //return this.Certificates.Equals(other.Certificates);

            // TODO Extract this to a utility class
            IList thisCerts  = this.Certificates;
            IList otherCerts = other.Certificates;

            if (thisCerts.Count != otherCerts.Count)
            {
                return(false);
            }

            IEnumerator e1 = thisCerts.GetEnumerator();
            IEnumerator e2 = thisCerts.GetEnumerator();

            while (e1.MoveNext())
            {
                e2.MoveNext();

                if (!Platform.Equals(e1.Current, e2.Current))
                {
                    return(false);
                }
            }

            return(true);
        }
        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);
            }
        }
Example #6
0
        /**
         * Validates an attribute certificate with the given certificate path.
         *
         * <p>
         * <code>params</code> must be an instance of
         * <code>ExtendedPkixParameters</code>.
         * </p><p>
         * The target constraints in the <code>params</code> must be an
         * <code>X509AttrCertStoreSelector</code> with at least the attribute
         * certificate criterion set. Obey that also target informations may be
         * necessary to correctly validate this attribute certificate.
         * </p><p>
         * The attribute certificate issuer must be added to the trusted attribute
         * issuers with {@link ExtendedPkixParameters#setTrustedACIssuers(Set)}.
         * </p>
         * @param certPath The certificate path which belongs to the attribute
         *            certificate issuer public key certificate.
         * @param params The PKIX parameters.
         * @return A <code>PKIXCertPathValidatorResult</code> of the result of
         *         validating the <code>certPath</code>.
         * @throws InvalidAlgorithmParameterException if <code>params</code> is
         *             inappropriate for this validator.
         * @throws CertPathValidatorException if the verification fails.
         */
        public virtual PkixCertPathValidatorResult Validate(
            PkixCertPath certPath,
            PkixParameters pkixParams)
        {
            IX509Selector certSelect = pkixParams.GetTargetConstraints();

            if (!(certSelect is X509AttrCertStoreSelector))
            {
                throw new ArgumentException(
                          "TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName,
                          "pkixParams");
            }
            IX509AttributeCertificate attrCert = ((X509AttrCertStoreSelector)certSelect).AttributeCert;

            PkixCertPath holderCertPath            = Rfc3281CertPathUtilities.ProcessAttrCert1(attrCert, pkixParams);
            PkixCertPathValidatorResult result     = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams);
            X509Certificate             issuerCert = (X509Certificate)certPath.Certificates[0];

            Rfc3281CertPathUtilities.ProcessAttrCert3(issuerCert, pkixParams);
            Rfc3281CertPathUtilities.ProcessAttrCert4(issuerCert, pkixParams);
            Rfc3281CertPathUtilities.ProcessAttrCert5(attrCert, pkixParams);
            // 6 already done in X509AttrCertStoreSelector
            Rfc3281CertPathUtilities.ProcessAttrCert7(attrCert, certPath, holderCertPath, pkixParams);
            Rfc3281CertPathUtilities.AdditionalChecks(attrCert, pkixParams);
            DateTime date;

            try
            {
                date = PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(pkixParams, null, -1);
            }
            catch (Exception e)
            {
                throw new PkixCertPathValidatorException(
                          "Could not get validity date from attribute certificate.", e);
            }
            Rfc3281CertPathUtilities.CheckCrls(attrCert, pkixParams, issuerCert, date, certPath.Certificates);
            return(result);
        }
        /// <summary>
        /// Creates a <code>PkixCertPathValidatorException</code> with the specified
        /// detail message, cause, certification path, and index.
        /// </summary>
        /// <param name="message">the detail message (or <code>null</code> if none)</param>
        /// <param name="cause">the cause (or <code>null</code> if none)</param>
        /// <param name="certPath">the certification path that was in the process of being
        /// validated when the error was encountered</param>
        /// <param name="index">the index of the certificate in the certification path that</param>																																																																																   *
        public PkixCertPathValidatorException(
            string message,
            Exception cause,
            PkixCertPath certPath,
            int index)
            : base(message)
        {
            if (certPath == null && index != -1)
            {
                throw new ArgumentNullException(
                          "certPath = null and index != -1");
            }
            if (index < -1 ||
                (certPath != null && index >= certPath.Certificates.Count))
            {
                throw new IndexOutOfRangeException(
                          " index < -1 or out of bound of certPath.getCertificates()");
            }

            this.cause    = cause;
            this.certPath = certPath;
            this.index    = index;
        }
Example #8
0
 /**
  * Performs checks on the specified attribute certificate. Every handled
  * extension is rmeoved from the <code>unresolvedCritExts</code>
  * collection.
  *
  * @param attrCert The attribute certificate to be checked.
  * @param certPath The certificate path which belongs to the attribute
  *            certificate issuer public key certificate.
  * @param holderCertPath The certificate path which belongs to the holder
  *            certificate.
  * @param unresolvedCritExts a <code>Collection</code> of OID strings
  *            representing the current set of unresolved critical extensions
  * @throws CertPathValidatorException if the specified attribute certificate
  *             does not pass the check.
  */
 public abstract void Check(IX509AttributeCertificate attrCert, PkixCertPath certPath,
                            PkixCertPath holderCertPath, ICollection unresolvedCritExts);
        public virtual PkixCertPathValidatorResult Validate(
            PkixCertPath certPath,
            PkixParameters paramsPkix)
        {
            if (paramsPkix.GetTrustAnchors() == null)
            {
                throw new ArgumentException(
                          "trustAnchors is null, this is not allowed for certification path validation.",
                          "parameters");
            }

            //
            // 6.1.1 - inputs
            //

            //
            // (a)
            //
            IList certs = certPath.Certificates;
            int   n     = certs.Count;

            if (certs.Count == 0)
            {
                throw new PkixCertPathValidatorException("Certification path is empty.", null, certPath, 0);
            }

            //
            // (b)
            //
            // DateTime validDate = PkixCertPathValidatorUtilities.GetValidDate(paramsPkix);

            //
            // (c)
            //
            ISet userInitialPolicySet = paramsPkix.GetInitialPolicies();

            //
            // (d)
            //
            TrustAnchor trust;

            try
            {
                trust = PkixCertPathValidatorUtilities.FindTrustAnchor(
                    (X509Certificate)certs[certs.Count - 1],
                    paramsPkix.GetTrustAnchors());
            }
            catch (Exception e)
            {
                throw new PkixCertPathValidatorException(e.Message, e, certPath, certs.Count - 1);
            }

            if (trust == null)
            {
                throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1);
            }

            //
            // (e), (f), (g) are part of the paramsPkix object.
            //
            IEnumerator certIter;
            int         index = 0;
            int         i;

            // Certificate for each interation of the validation loop
            // Signature information for each iteration of the validation loop
            //
            // 6.1.2 - setup
            //

            //
            // (a)
            //
            IList[] policyNodes = new IList[n + 1];
            for (int j = 0; j < policyNodes.Length; j++)
            {
                policyNodes[j] = Platform.CreateArrayList();
            }

            ISet policySet = new HashSet();

            policySet.Add(Rfc3280CertPathUtilities.ANY_POLICY);

            PkixPolicyNode validPolicyTree = new PkixPolicyNode(Platform.CreateArrayList(), 0, policySet, null, new HashSet(),
                                                                Rfc3280CertPathUtilities.ANY_POLICY, false);

            policyNodes[0].Add(validPolicyTree);

            //
            // (b) and (c)
            //
            PkixNameConstraintValidator nameConstraintValidator = new PkixNameConstraintValidator();

            // (d)
            //
            int  explicitPolicy;
            ISet acceptablePolicies = new HashSet();

            if (paramsPkix.IsExplicitPolicyRequired)
            {
                explicitPolicy = 0;
            }
            else
            {
                explicitPolicy = n + 1;
            }

            //
            // (e)
            //
            int inhibitAnyPolicy;

            if (paramsPkix.IsAnyPolicyInhibited)
            {
                inhibitAnyPolicy = 0;
            }
            else
            {
                inhibitAnyPolicy = n + 1;
            }

            //
            // (f)
            //
            int policyMapping;

            if (paramsPkix.IsPolicyMappingInhibited)
            {
                policyMapping = 0;
            }
            else
            {
                policyMapping = n + 1;
            }

            //
            // (g), (h), (i), (j)
            //
            AsymmetricKeyParameter workingPublicKey;
            X509Name workingIssuerName;

            X509Certificate sign = trust.TrustedCert;

            try
            {
                if (sign != null)
                {
                    workingIssuerName = sign.SubjectDN;
                    workingPublicKey  = sign.GetPublicKey();
                }
                else
                {
                    workingIssuerName = new X509Name(trust.CAName);
                    workingPublicKey  = trust.CAPublicKey;
                }
            }
            catch (ArgumentException ex)
            {
                throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath,
                                                         -1);
            }

            AlgorithmIdentifier workingAlgId = null;

            try
            {
                workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey);
            }
            catch (PkixCertPathValidatorException e)
            {
                throw new PkixCertPathValidatorException(
                          "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1);
            }

//			DerObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.ObjectID;
//			Asn1Encodable workingPublicKeyParameters = workingAlgId.Parameters;

            //
            // (k)
            //
            int maxPathLength = n;

            //
            // 6.1.3
            //

            X509CertStoreSelector certConstraints = paramsPkix.GetTargetCertConstraints();

            if (certConstraints != null && !certConstraints.Match((X509Certificate)certs[0]))
            {
                throw new PkixCertPathValidatorException(
                          "Target certificate in certification path does not match targetConstraints.", null, certPath, 0);
            }

            //
            // initialize CertPathChecker's
            //
            IList pathCheckers = paramsPkix.GetCertPathCheckers();

            certIter = pathCheckers.GetEnumerator();

            while (certIter.MoveNext())
            {
                ((PkixCertPathChecker)certIter.Current).Init(false);
            }

            X509Certificate cert = null;

            for (index = certs.Count - 1; index >= 0; index--)
            {
                // try
                // {
                //
                // i as defined in the algorithm description
                //
                i = n - index;

                //
                // set certificate to be checked in this round
                // sign and workingPublicKey and workingIssuerName are set
                // at the end of the for loop and initialized the
                // first time from the TrustAnchor
                //
                cert = (X509Certificate)certs[index];

                //
                // 6.1.3
                //

                Rfc3280CertPathUtilities.ProcessCertA(certPath, paramsPkix, index, workingPublicKey,
                                                      workingIssuerName, sign);

                Rfc3280CertPathUtilities.ProcessCertBC(certPath, index, nameConstraintValidator);

                validPolicyTree = Rfc3280CertPathUtilities.ProcessCertD(certPath, index,
                                                                        acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy);

                validPolicyTree = Rfc3280CertPathUtilities.ProcessCertE(certPath, index, validPolicyTree);

                Rfc3280CertPathUtilities.ProcessCertF(certPath, index, validPolicyTree, explicitPolicy);

                //
                // 6.1.4
                //

                if (i != n)
                {
                    if (cert != null && cert.Version == 1)
                    {
                        throw new PkixCertPathValidatorException(
                                  "Version 1 certificates can't be used as CA ones.", null, certPath, index);
                    }

                    Rfc3280CertPathUtilities.PrepareNextCertA(certPath, index);

                    validPolicyTree = Rfc3280CertPathUtilities.PrepareCertB(certPath, index, policyNodes,
                                                                            validPolicyTree, policyMapping);

                    Rfc3280CertPathUtilities.PrepareNextCertG(certPath, index, nameConstraintValidator);

                    // (h)
                    explicitPolicy   = Rfc3280CertPathUtilities.PrepareNextCertH1(certPath, index, explicitPolicy);
                    policyMapping    = Rfc3280CertPathUtilities.PrepareNextCertH2(certPath, index, policyMapping);
                    inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertH3(certPath, index, inhibitAnyPolicy);

                    //
                    // (i)
                    //
                    explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertI1(certPath, index, explicitPolicy);
                    policyMapping  = Rfc3280CertPathUtilities.PrepareNextCertI2(certPath, index, policyMapping);

                    // (j)
                    inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertJ(certPath, index, inhibitAnyPolicy);

                    // (k)
                    Rfc3280CertPathUtilities.PrepareNextCertK(certPath, index);

                    // (l)
                    maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertL(certPath, index, maxPathLength);

                    // (m)
                    maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertM(certPath, index, maxPathLength);

                    // (n)
                    Rfc3280CertPathUtilities.PrepareNextCertN(certPath, index);

                    ISet criticalExtensions1 = cert.GetCriticalExtensionOids();

                    if (criticalExtensions1 != null)
                    {
                        criticalExtensions1 = new HashSet(criticalExtensions1);

                        // these extensions are handled by the algorithm
                        criticalExtensions1.Remove(X509Extensions.KeyUsage.Id);
                        criticalExtensions1.Remove(X509Extensions.CertificatePolicies.Id);
                        criticalExtensions1.Remove(X509Extensions.PolicyMappings.Id);
                        criticalExtensions1.Remove(X509Extensions.InhibitAnyPolicy.Id);
                        criticalExtensions1.Remove(X509Extensions.IssuingDistributionPoint.Id);
                        criticalExtensions1.Remove(X509Extensions.DeltaCrlIndicator.Id);
                        criticalExtensions1.Remove(X509Extensions.PolicyConstraints.Id);
                        criticalExtensions1.Remove(X509Extensions.BasicConstraints.Id);
                        criticalExtensions1.Remove(X509Extensions.SubjectAlternativeName.Id);
                        criticalExtensions1.Remove(X509Extensions.NameConstraints.Id);
                    }
                    else
                    {
                        criticalExtensions1 = new HashSet();
                    }

                    // (o)
                    Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, pathCheckers);

                    // set signing certificate for next round
                    sign = cert;

                    // (c)
                    workingIssuerName = sign.SubjectDN;

                    // (d)
                    try
                    {
                        workingPublicKey = PkixCertPathValidatorUtilities.GetNextWorkingKey(certPath.Certificates, index);
                    }
                    catch (PkixCertPathValidatorException e)
                    {
                        throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, certPath, index);
                    }

                    workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey);
                    // (f)
//                    workingPublicKeyAlgorithm = workingAlgId.ObjectID;
                    // (e)
//                    workingPublicKeyParameters = workingAlgId.Parameters;
                }
            }

            //
            // 6.1.5 Wrap-up procedure
            //

            explicitPolicy = Rfc3280CertPathUtilities.WrapupCertA(explicitPolicy, cert);

            explicitPolicy = Rfc3280CertPathUtilities.WrapupCertB(certPath, index + 1, explicitPolicy);

            //
            // (c) (d) and (e) are already done
            //

            //
            // (f)
            //
            ISet criticalExtensions = cert.GetCriticalExtensionOids();

            if (criticalExtensions != null)
            {
                criticalExtensions = new HashSet(criticalExtensions);

                // Requires .Id
                // these extensions are handled by the algorithm
                criticalExtensions.Remove(X509Extensions.KeyUsage.Id);
                criticalExtensions.Remove(X509Extensions.CertificatePolicies.Id);
                criticalExtensions.Remove(X509Extensions.PolicyMappings.Id);
                criticalExtensions.Remove(X509Extensions.InhibitAnyPolicy.Id);
                criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id);
                criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id);
                criticalExtensions.Remove(X509Extensions.PolicyConstraints.Id);
                criticalExtensions.Remove(X509Extensions.BasicConstraints.Id);
                criticalExtensions.Remove(X509Extensions.SubjectAlternativeName.Id);
                criticalExtensions.Remove(X509Extensions.NameConstraints.Id);
                criticalExtensions.Remove(X509Extensions.CrlDistributionPoints.Id);
            }
            else
            {
                criticalExtensions = new HashSet();
            }

            Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions);

            PkixPolicyNode intersection = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix, userInitialPolicySet,
                                                                               index + 1, policyNodes, validPolicyTree, acceptablePolicies);

            if ((explicitPolicy > 0) || (intersection != null))
            {
                return(new PkixCertPathValidatorResult(trust, intersection, cert.GetPublicKey()));
            }

            throw new PkixCertPathValidatorException("Path processing failed on policy.", null, certPath, index);
        }
Example #10
0
        protected virtual PkixCertPathBuilderResult Build(
            X509Certificate tbvCert,
            PkixBuilderParameters pkixParams,
            IList tbvPath)
        {
            // If tbvCert is readily present in tbvPath, it indicates having run
            // into a cycle in the PKI graph.
            if (tbvPath.Contains(tbvCert))
            {
                return(null);
            }

            // step out, the certificate is not allowed to appear in a certification
            // chain.
            if (pkixParams.GetExcludedCerts().Contains(tbvCert))
            {
                return(null);
            }

            // test if certificate path exceeds maximum length
            if (pkixParams.MaxPathLength != -1)
            {
                if (tbvPath.Count - 1 > pkixParams.MaxPathLength)
                {
                    return(null);
                }
            }

            tbvPath.Add(tbvCert);

//			X509CertificateParser certParser = new X509CertificateParser();
            PkixCertPathBuilderResult builderResult = null;
            PkixCertPathValidator     validator     = new PkixCertPathValidator();

            try
            {
                // check whether the issuer of <tbvCert> is a TrustAnchor
                if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null)
                {
                    // exception message from possibly later tried certification
                    // chains
                    PkixCertPath certPath = null;
                    try
                    {
                        certPath = new PkixCertPath(tbvPath);
                    }
                    catch (Exception e)
                    {
                        throw new Exception(
                                  "Certification path could not be constructed from certificate list.",
                                  e);
                    }

                    PkixCertPathValidatorResult result = null;
                    try
                    {
                        result = (PkixCertPathValidatorResult)validator.Validate(
                            certPath, pkixParams);
                    }
                    catch (Exception e)
                    {
                        throw new Exception(
                                  "Certification path could not be validated.", e);
                    }

                    return(new PkixCertPathBuilderResult(certPath, result.TrustAnchor,
                                                         result.PolicyTree, result.SubjectPublicKey));
                }
                else
                {
                    // add additional X.509 stores from locations in certificate
                    try
                    {
                        PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(
                            tbvCert, pkixParams);
                    }
                    catch (CertificateParsingException e)
                    {
                        throw new Exception(
                                  "No additiontal X.509 stores can be added from certificate locations.",
                                  e);
                    }

                    // try to get the issuer certificate from one of the stores
                    HashSet issuers = new HashSet();
                    try
                    {
                        issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
                    }
                    catch (Exception e)
                    {
                        throw new Exception(
                                  "Cannot find issuer certificate for certificate in certification path.",
                                  e);
                    }

                    if (issuers.IsEmpty)
                    {
                        throw new Exception("No issuer certificate for certificate in certification path found.");
                    }

                    foreach (X509Certificate issuer in issuers)
                    {
                        builderResult = Build(issuer, pkixParams, tbvPath);

                        if (builderResult != null)
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                certPathException = e;
            }

            if (builderResult == null)
            {
                tbvPath.Remove(tbvCert);
            }

            return(builderResult);
        }