<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

Rfc3281CertPathUtilities

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.Extension; using Org.BouncyCastle.X509.Store; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Pkix { internal static class Rfc3281CertPathUtilities { internal static void ProcessAttrCert7(X509V2AttributeCertificate attrCert, PkixCertPath certPath, PkixCertPath holderCertPath, PkixParameters pkixParams) { ISet<string> criticalExtensionOids = attrCert.GetCriticalExtensionOids(); if (criticalExtensionOids.Contains(X509Extensions.TargetInformation.Id)) try { attrCert.GetExtension(X509Extensions.TargetInformation, TargetInformation.GetInstance); } catch (Exception innerException) { throw new PkixCertPathValidatorException("Target information extension could not be read.", innerException); } criticalExtensionOids.Remove(X509Extensions.TargetInformation.Id); foreach (PkixAttrCertChecker attrCertChecker in pkixParams.GetAttrCertCheckers()) { attrCertChecker.Check(attrCert, certPath, holderCertPath, criticalExtensionOids); } if (criticalExtensionOids.Count > 0) throw new PkixCertPathValidatorException("Attribute certificate contains unsupported critical extensions: " + criticalExtensionOids?.ToString()); } internal static void CheckCrls(X509V2AttributeCertificate attrCert, PkixParameters paramsPKIX, X509Certificate issuerCert, DateTime validDate, IList<X509Certificate> certPathCerts) { if (paramsPKIX.IsRevocationEnabled) { if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null) { 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."); } else { CrlDistPoint extension; try { extension = attrCert.GetExtension(X509Extensions.CrlDistributionPoints, CrlDistPoint.GetInstance); } catch (Exception innerException) { throw new PkixCertPathValidatorException("CRL distribution point extension could not be read.", innerException); } try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(extension, paramsPKIX); } catch (Exception innerException2) { throw new PkixCertPathValidatorException("No additional CRL locations could be decoded from CRL distribution point extension.", innerException2); } CertStatus certStatus = new CertStatus(); ReasonsMask reasonsMask = new ReasonsMask(); Exception innerException3 = null; bool flag = false; if (extension != null) { DistributionPoint[] distributionPoints; try { distributionPoints = extension.GetDistributionPoints(); } catch (Exception innerException4) { throw new PkixCertPathValidatorException("Distribution points could not be read.", innerException4); } try { for (int i = 0; i < distributionPoints.Length; i++) { if (certStatus.Status != 11) break; if (reasonsMask.IsAllReasons) break; PkixParameters paramsPKIX2 = (PkixParameters)paramsPKIX.Clone(); CheckCrl(distributionPoints[i], attrCert, paramsPKIX2, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); flag = true; } } catch (Exception innerException5) { innerException3 = new Exception("No valid CRL for distribution point found.", innerException5); } } if (certStatus.Status == 11 && !reasonsMask.IsAllReasons) try { X509Name instance; try { instance = X509Name.GetInstance(attrCert.Issuer.GetPrincipals()[0].GetEncoded()); } catch (Exception innerException6) { throw new Exception("Issuer from certificate for CRL could not be reencoded.", innerException6); } DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(new GeneralName(4, instance))), null, null); PkixParameters paramsPKIX3 = (PkixParameters)paramsPKIX.Clone(); CheckCrl(dp, attrCert, paramsPKIX3, validDate, issuerCert, certStatus, reasonsMask, certPathCerts); flag = true; } catch (Exception innerException7) { innerException3 = new Exception("No valid CRL for distribution point found.", innerException7); } if (!flag) throw new PkixCertPathValidatorException("No valid CRL found.", innerException3); if (certStatus.Status != 11) { string str = certStatus.RevocationDate.Value.ToString("ddd MMM dd HH:mm:ss K yyyy"); throw new PkixCertPathValidatorException("Attribute certificate revocation after " + str + ", reason: " + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status]); } if (!reasonsMask.IsAllReasons && certStatus.Status == 11) certStatus.Status = 12; if (certStatus.Status == 12) throw new PkixCertPathValidatorException("Attribute certificate status could not be determined."); } } } internal static void AdditionalChecks(X509V2AttributeCertificate attrCert, PkixParameters pkixParams) { foreach (string prohibitedACAttribute in pkixParams.GetProhibitedACAttributes()) { if (attrCert.GetAttributes(prohibitedACAttribute) != null) throw new PkixCertPathValidatorException("Attribute certificate contains prohibited attribute: " + prohibitedACAttribute + "."); } foreach (string necessaryACAttribute in pkixParams.GetNecessaryACAttributes()) { if (attrCert.GetAttributes(necessaryACAttribute) == null) throw new PkixCertPathValidatorException("Attribute certificate does not contain necessary attribute: " + necessaryACAttribute + "."); } } internal static void ProcessAttrCert5(X509V2AttributeCertificate attrCert, PkixParameters pkixParams) { try { attrCert.CheckValidity(PkixCertPathValidatorUtilities.GetValidDate(pkixParams)); } catch (CertificateExpiredException innerException) { throw new PkixCertPathValidatorException("Attribute certificate is not valid.", innerException); } catch (CertificateNotYetValidException innerException2) { throw new PkixCertPathValidatorException("Attribute certificate is not valid.", innerException2); } } internal static void ProcessAttrCert4(X509Certificate acIssuerCert, PkixParameters pkixParams) { foreach (TrustAnchor trustedACIssuer in pkixParams.GetTrustedACIssuers()) { IDictionary<DerObjectIdentifier, string> rFC2253Symbols = X509Name.RFC2253Symbols; if (acIssuerCert.SubjectDN.ToString(false, rFC2253Symbols).Equals(trustedACIssuer.CAName) || acIssuerCert.Equals(trustedACIssuer.TrustedCert)) return; } 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 pkixCertPathValidator = new PkixCertPathValidator(); try { return pkixCertPathValidator.Validate(certPath, pkixParams); } catch (PkixCertPathValidatorException innerException) { throw new PkixCertPathValidatorException("Certification path for issuer certificate of attribute certificate could not be validated.", innerException); } } internal static PkixCertPath ProcessAttrCert1(X509V2AttributeCertificate attrCert, PkixParameters pkixParams) { PkixCertPathBuilderResult pkixCertPathBuilderResult = null; HashSet<X509Certificate> hashSet = new HashSet<X509Certificate>(); if (attrCert.Holder.GetIssuer() != null) { X509CertStoreSelector x509CertStoreSelector = new X509CertStoreSelector(); x509CertStoreSelector.SerialNumber = attrCert.Holder.SerialNumber; X509Name[] issuer = attrCert.Holder.GetIssuer(); for (int i = 0; i < issuer.Length; i++) { try { x509CertStoreSelector.Issuer = issuer[i]; CollectionUtilities.CollectMatches(hashSet, x509CertStoreSelector, pkixParams.GetStoresCert()); } catch (Exception innerException) { throw new PkixCertPathValidatorException("Public key certificate for attribute certificate cannot be searched.", innerException); } } if (hashSet.Count < 1) throw new PkixCertPathValidatorException("Public key certificate specified in base certificate ID for attribute certificate cannot be found."); } if (attrCert.Holder.GetEntityNames() != null) { X509CertStoreSelector x509CertStoreSelector2 = new X509CertStoreSelector(); X509Name[] entityNames = attrCert.Holder.GetEntityNames(); for (int j = 0; j < entityNames.Length; j++) { try { x509CertStoreSelector2.Issuer = entityNames[j]; CollectionUtilities.CollectMatches(hashSet, x509CertStoreSelector2, pkixParams.GetStoresCert()); } catch (Exception innerException2) { throw new PkixCertPathValidatorException("Public key certificate for attribute certificate cannot be searched.", innerException2); } } if (hashSet.Count < 1) throw new PkixCertPathValidatorException("Public key certificate specified in entity name for attribute certificate cannot be found."); } PkixBuilderParameters instance = PkixBuilderParameters.GetInstance(pkixParams); PkixCertPathValidatorException ex = null; foreach (X509Certificate item in hashSet) { X509CertStoreSelector x509CertStoreSelector3 = new X509CertStoreSelector(); x509CertStoreSelector3.Certificate = item; instance.SetTargetConstraintsCert(x509CertStoreSelector3); PkixCertPathBuilder pkixCertPathBuilder = new PkixCertPathBuilder(); try { pkixCertPathBuilderResult = pkixCertPathBuilder.Build(instance); } catch (PkixCertPathBuilderException innerException3) { ex = new PkixCertPathValidatorException("Certification path for public key certificate of attribute certificate could not be build.", innerException3); } } if (ex != null) throw ex; return pkixCertPathBuilderResult.CertPath; } private static void CheckCrl(DistributionPoint dp, X509V2AttributeCertificate attrCert, PkixParameters paramsPKIX, DateTime validDate, X509Certificate issuerCert, CertStatus certStatus, ReasonsMask reasonMask, IList<X509Certificate> certPathCerts) { if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) == null) { DateTime utcNow = DateTime.UtcNow; if (validDate.CompareTo(utcNow) > 0) throw new Exception("Validation time is in future."); HashSet<X509Crl> completeCrls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, utcNow, paramsPKIX); bool flag = false; Exception ex = null; HashSet<X509Crl>.Enumerator enumerator = completeCrls.GetEnumerator(); while (enumerator.MoveNext() && certStatus.Status == 11 && !reasonMask.IsAllReasons) { try { X509Crl current = enumerator.Current; ReasonsMask reasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(current, dp); if (reasonsMask.HasNewReasons(reasonMask)) { HashSet<AsymmetricKeyParameter> keys = Rfc3280CertPathUtilities.ProcessCrlF(current, attrCert, null, null, paramsPKIX, certPathCerts); AsymmetricKeyParameter key = Rfc3280CertPathUtilities.ProcessCrlG(current, keys); X509Crl x509Crl = null; if (paramsPKIX.IsUseDeltasEnabled) x509Crl = Rfc3280CertPathUtilities.ProcessCrlH(PkixCertPathValidatorUtilities.GetDeltaCrls(utcNow, paramsPKIX, current), key); if (paramsPKIX.ValidityModel != 1 && attrCert.NotAfter.CompareTo(current.ThisUpdate) < 0) throw new Exception("No valid CRL for current time found."); Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, current); Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, current); Rfc3280CertPathUtilities.ProcessCrlC(x509Crl, current, paramsPKIX); Rfc3280CertPathUtilities.ProcessCrlI(validDate, x509Crl, attrCert, certStatus, paramsPKIX); Rfc3280CertPathUtilities.ProcessCrlJ(validDate, current, attrCert, certStatus); if (certStatus.Status == 8) certStatus.Status = 11; reasonMask.AddReasons(reasonsMask); flag = true; } } catch (Exception ex2) { ex = ex2; } } if (!flag) throw ex; } } } }