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;
}
}
}
}