Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Pkix/PkixCertPathValidatorUtilities.cs
2025-10-09 09:57:24 +09:00

796 lines
22 KiB
C#

using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.IsisMtt;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
using Org.BouncyCastle.X509.Store;
namespace Org.BouncyCastle.Pkix;
public class PkixCertPathValidatorUtilities
{
private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities();
internal static readonly string ANY_POLICY = "2.5.29.32.0";
internal static readonly string CRL_NUMBER = X509Extensions.CrlNumber.Id;
internal static readonly int KEY_CERT_SIGN = 5;
internal static readonly int CRL_SIGN = 6;
internal static readonly string[] crlReasons = new string[11]
{
"unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn",
"aACompromise"
};
internal static TrustAnchor FindTrustAnchor(X509Certificate cert, ISet trustAnchors)
{
IEnumerator enumerator = trustAnchors.GetEnumerator();
TrustAnchor trustAnchor = null;
AsymmetricKeyParameter asymmetricKeyParameter = null;
Exception ex = null;
X509CertStoreSelector x509CertStoreSelector = new X509CertStoreSelector();
try
{
x509CertStoreSelector.Subject = GetIssuerPrincipal(cert);
}
catch (IOException innerException)
{
throw new Exception("Cannot set subject search criteria for trust anchor.", innerException);
}
while (enumerator.MoveNext() && trustAnchor == null)
{
trustAnchor = (TrustAnchor)enumerator.Current;
if (trustAnchor.TrustedCert != null)
{
if (x509CertStoreSelector.Match(trustAnchor.TrustedCert))
{
asymmetricKeyParameter = trustAnchor.TrustedCert.GetPublicKey();
}
else
{
trustAnchor = null;
}
}
else if (trustAnchor.CAName != null && trustAnchor.CAPublicKey != null)
{
try
{
X509Name issuerPrincipal = GetIssuerPrincipal(cert);
X509Name other = new X509Name(trustAnchor.CAName);
if (issuerPrincipal.Equivalent(other, inOrder: true))
{
asymmetricKeyParameter = trustAnchor.CAPublicKey;
}
else
{
trustAnchor = null;
}
}
catch (InvalidParameterException)
{
trustAnchor = null;
}
}
else
{
trustAnchor = null;
}
if (asymmetricKeyParameter != null)
{
try
{
cert.Verify(asymmetricKeyParameter);
}
catch (Exception ex3)
{
ex = ex3;
trustAnchor = null;
}
}
}
if (trustAnchor == null && ex != null)
{
throw new Exception("TrustAnchor found but certificate validation failed.", ex);
}
return trustAnchor;
}
internal static bool IsIssuerTrustAnchor(X509Certificate cert, ISet trustAnchors)
{
try
{
return FindTrustAnchor(cert, trustAnchors) != null;
}
catch (Exception)
{
return false;
}
}
internal static void AddAdditionalStoresFromAltNames(X509Certificate cert, PkixParameters pkixParams)
{
if (cert.GetIssuerAlternativeNames() == null)
{
return;
}
IEnumerator enumerator = cert.GetIssuerAlternativeNames().GetEnumerator();
while (enumerator.MoveNext())
{
IList list = (IList)enumerator.Current;
if (list[0].Equals(6))
{
string location = (string)list[1];
AddAdditionalStoreFromLocation(location, pkixParams);
}
}
}
internal static DateTime GetValidDate(PkixParameters paramsPKIX)
{
return paramsPKIX.Date?.Value ?? DateTime.UtcNow;
}
internal static X509Name GetIssuerPrincipal(object cert)
{
if (cert is X509Certificate)
{
return ((X509Certificate)cert).IssuerDN;
}
return ((IX509AttributeCertificate)cert).Issuer.GetPrincipals()[0];
}
internal static bool IsSelfIssued(X509Certificate cert)
{
return cert.SubjectDN.Equivalent(cert.IssuerDN, inOrder: true);
}
internal static AlgorithmIdentifier GetAlgorithmIdentifier(AsymmetricKeyParameter key)
{
try
{
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key);
return subjectPublicKeyInfo.AlgorithmID;
}
catch (Exception cause)
{
throw new PkixCertPathValidatorException("Subject public key cannot be decoded.", cause);
}
}
internal static bool IsAnyPolicy(ISet policySet)
{
if (policySet != null && !policySet.Contains(ANY_POLICY))
{
return policySet.Count == 0;
}
return true;
}
internal static void AddAdditionalStoreFromLocation(string location, PkixParameters pkixParams)
{
if (!pkixParams.IsAdditionalLocationsEnabled)
{
return;
}
try
{
if (Platform.StartsWith(location, "ldap://"))
{
location = location.Substring(7);
int num = location.IndexOf('/');
if (num != -1)
{
_ = "ldap://" + location.Substring(0, num);
}
else
{
_ = "ldap://" + location;
}
throw Platform.CreateNotImplementedException("LDAP cert/CRL stores");
}
}
catch (Exception)
{
throw new Exception("Exception adding X.509 stores.");
}
}
private static BigInteger GetSerialNumber(object cert)
{
if (cert is X509Certificate)
{
return ((X509Certificate)cert).SerialNumber;
}
return ((X509V2AttributeCertificate)cert).SerialNumber;
}
internal static ISet GetQualifierSet(Asn1Sequence qualifiers)
{
ISet set = new HashSet();
if (qualifiers == null)
{
return set;
}
foreach (Asn1Encodable qualifier in qualifiers)
{
try
{
set.Add(PolicyQualifierInfo.GetInstance(qualifier.ToAsn1Object()));
}
catch (IOException cause)
{
throw new PkixCertPathValidatorException("Policy qualifier info cannot be decoded.", cause);
}
}
return set;
}
internal static PkixPolicyNode RemovePolicyNode(PkixPolicyNode validPolicyTree, IList[] policyNodes, PkixPolicyNode _node)
{
PkixPolicyNode parent = _node.Parent;
if (validPolicyTree == null)
{
return null;
}
if (parent == null)
{
for (int i = 0; i < policyNodes.Length; i++)
{
policyNodes[i] = Platform.CreateArrayList();
}
return null;
}
parent.RemoveChild(_node);
RemovePolicyNodeRecurse(policyNodes, _node);
return validPolicyTree;
}
private static void RemovePolicyNodeRecurse(IList[] policyNodes, PkixPolicyNode _node)
{
policyNodes[_node.Depth].Remove(_node);
if (!_node.HasChildren)
{
return;
}
foreach (PkixPolicyNode child in _node.Children)
{
RemovePolicyNodeRecurse(policyNodes, child);
}
}
internal static void PrepareNextCertB1(int i, IList[] policyNodes, string id_p, IDictionary m_idp, X509Certificate cert)
{
bool flag = false;
IEnumerator enumerator = policyNodes[i].GetEnumerator();
while (enumerator.MoveNext())
{
PkixPolicyNode pkixPolicyNode = (PkixPolicyNode)enumerator.Current;
if (pkixPolicyNode.ValidPolicy.Equals(id_p))
{
flag = true;
pkixPolicyNode.ExpectedPolicies = (ISet)m_idp[id_p];
break;
}
}
if (flag)
{
return;
}
enumerator = policyNodes[i].GetEnumerator();
while (enumerator.MoveNext())
{
PkixPolicyNode pkixPolicyNode2 = (PkixPolicyNode)enumerator.Current;
if (!ANY_POLICY.Equals(pkixPolicyNode2.ValidPolicy))
{
continue;
}
ISet policyQualifiers = null;
Asn1Sequence asn1Sequence = null;
try
{
asn1Sequence = Asn1Sequence.GetInstance(GetExtensionValue(cert, X509Extensions.CertificatePolicies));
}
catch (Exception innerException)
{
throw new Exception("Certificate policies cannot be decoded.", innerException);
}
IEnumerator enumerator2 = asn1Sequence.GetEnumerator();
while (enumerator2.MoveNext())
{
PolicyInformation policyInformation = null;
try
{
policyInformation = PolicyInformation.GetInstance(enumerator2.Current);
}
catch (Exception innerException2)
{
throw new Exception("Policy information cannot be decoded.", innerException2);
}
if (ANY_POLICY.Equals(policyInformation.PolicyIdentifier.Id))
{
try
{
policyQualifiers = GetQualifierSet(policyInformation.PolicyQualifiers);
}
catch (PkixCertPathValidatorException cause)
{
throw new PkixCertPathValidatorException("Policy qualifier info set could not be built.", cause);
}
break;
}
}
bool critical = false;
ISet criticalExtensionOids = cert.GetCriticalExtensionOids();
if (criticalExtensionOids != null)
{
critical = criticalExtensionOids.Contains(X509Extensions.CertificatePolicies.Id);
}
PkixPolicyNode parent = pkixPolicyNode2.Parent;
if (ANY_POLICY.Equals(parent.ValidPolicy))
{
PkixPolicyNode pkixPolicyNode3 = new PkixPolicyNode(Platform.CreateArrayList(), i, (ISet)m_idp[id_p], parent, policyQualifiers, id_p, critical);
parent.AddChild(pkixPolicyNode3);
policyNodes[i].Add(pkixPolicyNode3);
}
break;
}
}
internal static PkixPolicyNode PrepareNextCertB2(int i, IList[] policyNodes, string id_p, PkixPolicyNode validPolicyTree)
{
int num = 0;
foreach (PkixPolicyNode item in Platform.CreateArrayList(policyNodes[i]))
{
if (item.ValidPolicy.Equals(id_p))
{
PkixPolicyNode parent = item.Parent;
parent.RemoveChild(item);
policyNodes[i].RemoveAt(num);
for (int num2 = i - 1; num2 >= 0; num2--)
{
IList list = policyNodes[num2];
for (int j = 0; j < list.Count; j++)
{
PkixPolicyNode pkixPolicyNode2 = (PkixPolicyNode)list[j];
if (!pkixPolicyNode2.HasChildren)
{
validPolicyTree = RemovePolicyNode(validPolicyTree, policyNodes, pkixPolicyNode2);
if (validPolicyTree == null)
{
break;
}
}
}
}
}
else
{
num++;
}
}
return validPolicyTree;
}
internal static void GetCertStatus(DateTime validDate, X509Crl crl, object cert, CertStatus certStatus)
{
X509Crl x509Crl = null;
try
{
x509Crl = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Object.FromByteArray(crl.GetEncoded())));
}
catch (Exception innerException)
{
throw new Exception("Bouncy Castle X509Crl could not be created.", innerException);
}
X509CrlEntry revokedCertificate = x509Crl.GetRevokedCertificate(GetSerialNumber(cert));
if (revokedCertificate == null)
{
return;
}
X509Name issuerPrincipal = GetIssuerPrincipal(cert);
if (!issuerPrincipal.Equivalent(revokedCertificate.GetCertificateIssuer(), inOrder: true) && !issuerPrincipal.Equivalent(crl.IssuerDN, inOrder: true))
{
return;
}
DerEnumerated derEnumerated = null;
if (revokedCertificate.HasExtensions)
{
try
{
derEnumerated = DerEnumerated.GetInstance(GetExtensionValue(revokedCertificate, X509Extensions.ReasonCode));
}
catch (Exception innerException2)
{
throw new Exception("Reason code CRL entry extension could not be decoded.", innerException2);
}
}
if (validDate.Ticks >= revokedCertificate.RevocationDate.Ticks || derEnumerated == null || derEnumerated.Value.TestBit(0) || derEnumerated.Value.TestBit(1) || derEnumerated.Value.TestBit(2) || derEnumerated.Value.TestBit(8))
{
if (derEnumerated != null)
{
certStatus.Status = derEnumerated.Value.SignValue;
}
else
{
certStatus.Status = 0;
}
certStatus.RevocationDate = new DateTimeObject(revokedCertificate.RevocationDate);
}
}
internal static AsymmetricKeyParameter GetNextWorkingKey(IList certs, int index)
{
X509Certificate x509Certificate = (X509Certificate)certs[index];
AsymmetricKeyParameter publicKey = x509Certificate.GetPublicKey();
if (!(publicKey is DsaPublicKeyParameters))
{
return publicKey;
}
DsaPublicKeyParameters dsaPublicKeyParameters = (DsaPublicKeyParameters)publicKey;
if (dsaPublicKeyParameters.Parameters != null)
{
return dsaPublicKeyParameters;
}
for (int i = index + 1; i < certs.Count; i++)
{
X509Certificate x509Certificate2 = (X509Certificate)certs[i];
publicKey = x509Certificate2.GetPublicKey();
if (!(publicKey is DsaPublicKeyParameters))
{
throw new PkixCertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
}
DsaPublicKeyParameters dsaPublicKeyParameters2 = (DsaPublicKeyParameters)publicKey;
if (dsaPublicKeyParameters2.Parameters != null)
{
DsaParameters parameters = dsaPublicKeyParameters2.Parameters;
try
{
return new DsaPublicKeyParameters(dsaPublicKeyParameters.Y, parameters);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
throw new PkixCertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
}
internal static DateTime GetValidCertDateFromValidityModel(PkixParameters paramsPkix, PkixCertPath certPath, int index)
{
if (paramsPkix.ValidityModel != 1)
{
return GetValidDate(paramsPkix);
}
if (index <= 0)
{
return GetValidDate(paramsPkix);
}
if (index - 1 == 0)
{
DerGeneralizedTime derGeneralizedTime = null;
try
{
X509Certificate x509Certificate = (X509Certificate)certPath.Certificates[index - 1];
Asn1OctetString extensionValue = x509Certificate.GetExtensionValue(IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen);
derGeneralizedTime = DerGeneralizedTime.GetInstance(extensionValue);
}
catch (ArgumentException)
{
throw new Exception("Date of cert gen extension could not be read.");
}
if (derGeneralizedTime != null)
{
try
{
return derGeneralizedTime.ToDateTime();
}
catch (ArgumentException innerException)
{
throw new Exception("Date from date of cert gen extension could not be parsed.", innerException);
}
}
}
return ((X509Certificate)certPath.Certificates[index - 1]).NotBefore;
}
internal static ICollection FindCertificates(X509CertStoreSelector certSelect, IList certStores)
{
ISet set = new HashSet();
foreach (IX509Store certStore in certStores)
{
try
{
foreach (X509Certificate match in certStore.GetMatches(certSelect))
{
set.Add(match);
}
}
catch (Exception innerException)
{
throw new Exception("Problem while picking certificates from X.509 store.", innerException);
}
}
return set;
}
internal static void GetCrlIssuersFromDistributionPoint(DistributionPoint dp, ICollection issuerPrincipals, X509CrlStoreSelector selector, PkixParameters pkixParams)
{
IList list = Platform.CreateArrayList();
if (dp.CrlIssuer != null)
{
GeneralName[] names = dp.CrlIssuer.GetNames();
for (int i = 0; i < names.Length; i++)
{
if (names[i].TagNo == 4)
{
try
{
list.Add(X509Name.GetInstance(names[i].Name.ToAsn1Object()));
}
catch (IOException innerException)
{
throw new Exception("CRL issuer information from distribution point cannot be decoded.", innerException);
}
}
}
}
else
{
if (dp.DistributionPointName == null)
{
throw new Exception("CRL issuer is omitted from distribution point but no distributionPoint field present.");
}
IEnumerator enumerator = issuerPrincipals.GetEnumerator();
while (enumerator.MoveNext())
{
list.Add((X509Name)enumerator.Current);
}
}
selector.Issuers = list;
}
internal static ISet GetCompleteCrls(DistributionPoint dp, object cert, DateTime currentDate, PkixParameters paramsPKIX)
{
X509CrlStoreSelector x509CrlStoreSelector = new X509CrlStoreSelector();
try
{
ISet set = new HashSet();
if (cert is X509V2AttributeCertificate)
{
set.Add(((X509V2AttributeCertificate)cert).Issuer.GetPrincipals()[0]);
}
else
{
set.Add(GetIssuerPrincipal(cert));
}
GetCrlIssuersFromDistributionPoint(dp, set, x509CrlStoreSelector, paramsPKIX);
}
catch (Exception innerException)
{
throw new Exception("Could not get issuer information from distribution point.", innerException);
}
if (cert is X509Certificate)
{
x509CrlStoreSelector.CertificateChecking = (X509Certificate)cert;
}
else if (cert is X509V2AttributeCertificate)
{
x509CrlStoreSelector.AttrCertChecking = (IX509AttributeCertificate)cert;
}
x509CrlStoreSelector.CompleteCrlEnabled = true;
ISet set2 = CrlUtilities.FindCrls(x509CrlStoreSelector, paramsPKIX, currentDate);
if (set2.IsEmpty)
{
if (cert is IX509AttributeCertificate)
{
IX509AttributeCertificate iX509AttributeCertificate = (IX509AttributeCertificate)cert;
throw new Exception(string.Concat("No CRLs found for issuer \"", iX509AttributeCertificate.Issuer.GetPrincipals()[0], "\""));
}
X509Certificate x509Certificate = (X509Certificate)cert;
throw new Exception(string.Concat("No CRLs found for issuer \"", x509Certificate.IssuerDN, "\""));
}
return set2;
}
internal static ISet GetDeltaCrls(DateTime currentDate, PkixParameters paramsPKIX, X509Crl completeCRL)
{
X509CrlStoreSelector x509CrlStoreSelector = new X509CrlStoreSelector();
try
{
IList list = Platform.CreateArrayList();
list.Add(completeCRL.IssuerDN);
x509CrlStoreSelector.Issuers = list;
}
catch (IOException innerException)
{
throw new Exception("Cannot extract issuer from CRL.", innerException);
}
BigInteger bigInteger = null;
try
{
Asn1Object extensionValue = GetExtensionValue(completeCRL, X509Extensions.CrlNumber);
if (extensionValue != null)
{
bigInteger = DerInteger.GetInstance(extensionValue).PositiveValue;
}
}
catch (Exception innerException2)
{
throw new Exception("CRL number extension could not be extracted from CRL.", innerException2);
}
byte[] issuingDistributionPoint = null;
try
{
Asn1Object extensionValue2 = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint);
if (extensionValue2 != null)
{
issuingDistributionPoint = extensionValue2.GetDerEncoded();
}
}
catch (Exception innerException3)
{
throw new Exception("Issuing distribution point extension value could not be read.", innerException3);
}
x509CrlStoreSelector.MinCrlNumber = bigInteger?.Add(BigInteger.One);
x509CrlStoreSelector.IssuingDistributionPoint = issuingDistributionPoint;
x509CrlStoreSelector.IssuingDistributionPointEnabled = true;
x509CrlStoreSelector.MaxBaseCrlNumber = bigInteger;
ISet set = CrlUtilities.FindCrls(x509CrlStoreSelector, paramsPKIX, currentDate);
ISet set2 = new HashSet();
foreach (X509Crl item in set)
{
if (isDeltaCrl(item))
{
set2.Add(item);
}
}
return set2;
}
private static bool isDeltaCrl(X509Crl crl)
{
ISet criticalExtensionOids = crl.GetCriticalExtensionOids();
return criticalExtensionOids.Contains(X509Extensions.DeltaCrlIndicator.Id);
}
internal static ICollection FindCertificates(X509AttrCertStoreSelector certSelect, IList certStores)
{
ISet set = new HashSet();
foreach (IX509Store certStore in certStores)
{
try
{
foreach (X509V2AttributeCertificate match in certStore.GetMatches(certSelect))
{
set.Add(match);
}
}
catch (Exception innerException)
{
throw new Exception("Problem while picking certificates from X.509 store.", innerException);
}
}
return set;
}
internal static void AddAdditionalStoresFromCrlDistributionPoint(CrlDistPoint crldp, PkixParameters pkixParams)
{
if (crldp == null)
{
return;
}
DistributionPoint[] array = null;
try
{
array = crldp.GetDistributionPoints();
}
catch (Exception innerException)
{
throw new Exception("Distribution points could not be read.", innerException);
}
for (int i = 0; i < array.Length; i++)
{
DistributionPointName distributionPointName = array[i].DistributionPointName;
if (distributionPointName == null || distributionPointName.PointType != 0)
{
continue;
}
GeneralName[] names = GeneralNames.GetInstance(distributionPointName.Name).GetNames();
for (int j = 0; j < names.Length; j++)
{
if (names[j].TagNo == 6)
{
string location = DerIA5String.GetInstance(names[j].Name).GetString();
AddAdditionalStoreFromLocation(location, pkixParams);
}
}
}
}
internal static bool ProcessCertD1i(int index, IList[] policyNodes, DerObjectIdentifier pOid, ISet pq)
{
IList list = policyNodes[index - 1];
for (int i = 0; i < list.Count; i++)
{
PkixPolicyNode pkixPolicyNode = (PkixPolicyNode)list[i];
ISet expectedPolicies = pkixPolicyNode.ExpectedPolicies;
if (expectedPolicies.Contains(pOid.Id))
{
ISet set = new HashSet();
set.Add(pOid.Id);
PkixPolicyNode pkixPolicyNode2 = new PkixPolicyNode(Platform.CreateArrayList(), index, set, pkixPolicyNode, pq, pOid.Id, critical: false);
pkixPolicyNode.AddChild(pkixPolicyNode2);
policyNodes[index].Add(pkixPolicyNode2);
return true;
}
}
return false;
}
internal static void ProcessCertD1ii(int index, IList[] policyNodes, DerObjectIdentifier _poid, ISet _pq)
{
IList list = policyNodes[index - 1];
for (int i = 0; i < list.Count; i++)
{
PkixPolicyNode pkixPolicyNode = (PkixPolicyNode)list[i];
if (ANY_POLICY.Equals(pkixPolicyNode.ValidPolicy))
{
ISet set = new HashSet();
set.Add(_poid.Id);
PkixPolicyNode pkixPolicyNode2 = new PkixPolicyNode(Platform.CreateArrayList(), index, set, pkixPolicyNode, _pq, _poid.Id, critical: false);
pkixPolicyNode.AddChild(pkixPolicyNode2);
policyNodes[index].Add(pkixPolicyNode2);
break;
}
}
}
internal static ICollection FindIssuerCerts(X509Certificate cert, PkixBuilderParameters pkixParams)
{
X509CertStoreSelector x509CertStoreSelector = new X509CertStoreSelector();
ISet set = new HashSet();
try
{
x509CertStoreSelector.Subject = cert.IssuerDN;
}
catch (IOException innerException)
{
throw new Exception("Subject criteria for certificate selector to find issuer certificate could not be set.", innerException);
}
try
{
set.AddAll(FindCertificates(x509CertStoreSelector, pkixParams.GetStores()));
set.AddAll(FindCertificates(x509CertStoreSelector, pkixParams.GetAdditionalStores()));
return set;
}
catch (Exception innerException2)
{
throw new Exception("Issuer certificate cannot be searched.", innerException2);
}
}
internal static Asn1Object GetExtensionValue(IX509Extension ext, DerObjectIdentifier oid)
{
Asn1OctetString extensionValue = ext.GetExtensionValue(oid);
if (extensionValue == null)
{
return null;
}
return X509ExtensionUtilities.FromExtensionValue(extensionValue);
}
}