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); }
/** * Build and validate a CertPath using the given parameter. * * @param params PKIXBuilderParameters object containing all information to * build the CertPath */ public virtual PkixCertPathBuilderResult Build( PkixBuilderParameters pkixParams) { // search target certificates IX509Selector certSelect = pkixParams.GetTargetConstraints(); if (!(certSelect is X509AttrCertStoreSelector)) { throw new PkixCertPathBuilderException( "TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName + " for " + typeof(PkixAttrCertPathBuilder).FullName + " class."); } ICollection targets; try { targets = PkixCertPathValidatorUtilities.FindCertificates( (X509AttrCertStoreSelector)certSelect, pkixParams.GetStores()); } catch (Exception e) { throw new PkixCertPathBuilderException("Error finding target attribute certificate.", e); } if (targets.Count == 0) { throw new PkixCertPathBuilderException( "No attribute certificate found matching targetContraints."); } PkixCertPathBuilderResult result = null; // check all potential target certificates foreach (IX509AttributeCertificate cert in targets) { X509CertStoreSelector selector = new X509CertStoreSelector(); X509Name[] principals = cert.Issuer.GetPrincipals(); ISet issuers = new HashSet(); for (int i = 0; i < principals.Length; i++) { try { selector.Subject = principals[i]; issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStores())); } catch (Exception e) { throw new PkixCertPathBuilderException( "Public key certificate for attribute certificate cannot be searched.", e); } } if (issuers.IsEmpty) { throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found."); } IList certPathList = Platform.CreateArrayList(); foreach (X509Certificate issuer in issuers) { result = Build(cert, issuer, pkixParams, certPathList); if (result != null) { break; } } if (result != null) { break; } } if (result == null && certPathException != null) { throw new PkixCertPathBuilderException( "Possible certificate chain could not be validated.", certPathException); } if (result == null && certPathException == null) { throw new PkixCertPathBuilderException( "Unable to find certificate chain."); } return(result); }