<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

PkixAttrCertPathBuilder

using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.X509; using Org.BouncyCastle.X509.Store; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Pkix { public class PkixAttrCertPathBuilder { private Exception certPathException; public virtual PkixCertPathBuilderResult Build(PkixBuilderParameters pkixParams) { X509AttrCertStoreSelector x509AttrCertStoreSelector = pkixParams.GetTargetConstraintsAttrCert() as X509AttrCertStoreSelector; if (x509AttrCertStoreSelector == null) throw new PkixCertPathBuilderException("TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName + " for " + typeof(PkixAttrCertPathBuilder).FullName + " class."); HashSet<X509V2AttributeCertificate> hashSet; try { hashSet = FindAttributeCertificates(x509AttrCertStoreSelector, pkixParams.GetStoresAttrCert()); } catch (Exception innerException) { throw new PkixCertPathBuilderException("Error finding target attribute certificate.", innerException); } if (hashSet.Count == 0) throw new PkixCertPathBuilderException("No attribute certificate found matching targetConstraints."); PkixCertPathBuilderResult pkixCertPathBuilderResult = null; foreach (X509V2AttributeCertificate item in hashSet) { X509CertStoreSelector x509CertStoreSelector = new X509CertStoreSelector(); X509Name[] principals = item.Issuer.GetPrincipals(); HashSet<X509Certificate> hashSet2 = new HashSet<X509Certificate>(); for (int i = 0; i < principals.Length; i++) { try { x509CertStoreSelector.Subject = principals[i]; CollectionUtilities.CollectMatches(hashSet2, x509CertStoreSelector, pkixParams.GetStoresCert()); } catch (Exception innerException2) { throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be searched.", innerException2); } } if (hashSet2.Count < 1) throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found."); List<X509Certificate> tbvPath = new List<X509Certificate>(); foreach (X509Certificate item2 in hashSet2) { pkixCertPathBuilderResult = Build(item, item2, pkixParams, tbvPath); if (pkixCertPathBuilderResult != null) break; } if (pkixCertPathBuilderResult != null) break; } if (pkixCertPathBuilderResult == null && certPathException != null) throw new PkixCertPathBuilderException("Possible certificate chain could not be validated.", certPathException); if (pkixCertPathBuilderResult == null && certPathException == null) throw new PkixCertPathBuilderException("Unable to find certificate chain."); return pkixCertPathBuilderResult; } private PkixCertPathBuilderResult Build(X509V2AttributeCertificate attrCert, X509Certificate tbvCert, PkixBuilderParameters pkixParams, IList<X509Certificate> tbvPath) { if (tbvPath.Contains(tbvCert)) return null; if (pkixParams.GetExcludedCerts().Contains(tbvCert)) return null; if (pkixParams.MaxPathLength != -1 && tbvPath.Count - 1 > pkixParams.MaxPathLength) return null; tbvPath.Add(tbvCert); PkixCertPathBuilderResult pkixCertPathBuilderResult = null; PkixAttrCertPathValidator pkixAttrCertPathValidator = new PkixAttrCertPathValidator(); try { if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors())) { PkixCertPath certPath = new PkixCertPath(tbvPath); PkixCertPathValidatorResult pkixCertPathValidatorResult; try { pkixCertPathValidatorResult = pkixAttrCertPathValidator.Validate(certPath, pkixParams); } catch (Exception innerException) { throw new Exception("Certification path could not be validated.", innerException); } return new PkixCertPathBuilderResult(certPath, pkixCertPathValidatorResult.TrustAnchor, pkixCertPathValidatorResult.PolicyTree, pkixCertPathValidatorResult.SubjectPublicKey); } try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams); } catch (CertificateParsingException innerException2) { throw new Exception("No additional X.509 stores can be added from certificate locations.", innerException2); } HashSet<X509Certificate> hashSet; try { hashSet = PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams); } catch (Exception innerException3) { throw new Exception("Cannot find issuer certificate for certificate in certification path.", innerException3); } if (hashSet.Count < 1) throw new Exception("No issuer certificate for certificate in certification path found."); foreach (X509Certificate item in hashSet) { if (!PkixCertPathValidatorUtilities.IsSelfIssued(item)) { pkixCertPathBuilderResult = Build(attrCert, item, pkixParams, tbvPath); if (pkixCertPathBuilderResult != null) break; } } } catch (Exception innerException4) { certPathException = new Exception("No valid certification path could be build.", innerException4); } if (pkixCertPathBuilderResult == null) tbvPath.Remove(tbvCert); return pkixCertPathBuilderResult; } internal static HashSet<X509V2AttributeCertificate> FindAttributeCertificates(ISelector<X509V2AttributeCertificate> attrCertSelector, IList<IStore<X509V2AttributeCertificate>> attrCertStores) { HashSet<X509V2AttributeCertificate> hashSet = new HashSet<X509V2AttributeCertificate>(); foreach (IStore<X509V2AttributeCertificate> attrCertStore in attrCertStores) { try { hashSet.UnionWith(attrCertStore.EnumerateMatches(attrCertSelector)); } catch (Exception innerException) { throw new Exception("Problem while picking certificates from X.509 store.", innerException); } } return hashSet; } } }