private PkixCertPathBuilderResult Build( IX509AttributeCertificate attrCert, 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); PkixCertPathBuilderResult builderResult = null; // X509CertificateParser certParser = new X509CertificateParser(); PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator(); try { // check whether the issuer of <tbvCert> is a TrustAnchor if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null) { PkixCertPath certPath = new PkixCertPath(tbvPath); PkixCertPathValidatorResult result; try { result = 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 additional X.509 stores can be added from certificate locations.", e); } // try to get the issuer certificate from one of the stores ISet 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) { // if untrusted self signed certificate continue if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer)) { continue; } builderResult = Build(attrCert, issuer, pkixParams, tbvPath); if (builderResult != null) { break; } } } } catch (Exception e) { certPathException = new Exception("No valid certification path could be build.", e); } if (builderResult == null) { tbvPath.Remove(tbvCert); } return(builderResult); }