init commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class CertStatus
|
||||
{
|
||||
public const int Unrevoked = 11;
|
||||
|
||||
public const int Undetermined = 12;
|
||||
|
||||
private int status = 11;
|
||||
|
||||
private DateTimeObject revocationDate = null;
|
||||
|
||||
public DateTimeObject RevocationDate
|
||||
{
|
||||
get
|
||||
{
|
||||
return revocationDate;
|
||||
}
|
||||
set
|
||||
{
|
||||
revocationDate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return status;
|
||||
}
|
||||
set
|
||||
{
|
||||
status = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public abstract class PkixAttrCertChecker
|
||||
{
|
||||
public abstract ISet GetSupportedExtensions();
|
||||
|
||||
public abstract void Check(IX509AttributeCertificate attrCert, PkixCertPath certPath, PkixCertPath holderCertPath, ICollection unresolvedCritExts);
|
||||
|
||||
public abstract PkixAttrCertChecker Clone();
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixAttrCertPathBuilder
|
||||
{
|
||||
private Exception certPathException;
|
||||
|
||||
public virtual PkixCertPathBuilderResult Build(PkixBuilderParameters pkixParams)
|
||||
{
|
||||
IX509Selector targetConstraints = pkixParams.GetTargetConstraints();
|
||||
if (!(targetConstraints is X509AttrCertStoreSelector))
|
||||
{
|
||||
throw new PkixCertPathBuilderException("TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName + " for " + typeof(PkixAttrCertPathBuilder).FullName + " class.");
|
||||
}
|
||||
ICollection collection;
|
||||
try
|
||||
{
|
||||
collection = PkixCertPathValidatorUtilities.FindCertificates((X509AttrCertStoreSelector)targetConstraints, pkixParams.GetStores());
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("Error finding target attribute certificate.", exception);
|
||||
}
|
||||
if (collection.Count == 0)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("No attribute certificate found matching targetContraints.");
|
||||
}
|
||||
PkixCertPathBuilderResult pkixCertPathBuilderResult = null;
|
||||
foreach (IX509AttributeCertificate item in collection)
|
||||
{
|
||||
X509CertStoreSelector x509CertStoreSelector = new X509CertStoreSelector();
|
||||
X509Name[] principals = item.Issuer.GetPrincipals();
|
||||
ISet set = new HashSet();
|
||||
for (int i = 0; i < principals.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
x509CertStoreSelector.Subject = principals[i];
|
||||
set.AddAll(PkixCertPathValidatorUtilities.FindCertificates(x509CertStoreSelector, pkixParams.GetStores()));
|
||||
}
|
||||
catch (Exception exception2)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be searched.", exception2);
|
||||
}
|
||||
}
|
||||
if (set.IsEmpty)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found.");
|
||||
}
|
||||
IList tbvPath = Platform.CreateArrayList();
|
||||
foreach (X509Certificate item2 in set)
|
||||
{
|
||||
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(IX509AttributeCertificate attrCert, X509Certificate tbvCert, PkixBuilderParameters pkixParams, IList 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);
|
||||
}
|
||||
ISet set = new HashSet();
|
||||
try
|
||||
{
|
||||
set.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
|
||||
}
|
||||
catch (Exception innerException3)
|
||||
{
|
||||
throw new Exception("Cannot find issuer certificate for certificate in certification path.", innerException3);
|
||||
}
|
||||
if (set.IsEmpty)
|
||||
{
|
||||
throw new Exception("No issuer certificate for certificate in certification path found.");
|
||||
}
|
||||
foreach (X509Certificate item in set)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixAttrCertPathValidator
|
||||
{
|
||||
public virtual PkixCertPathValidatorResult Validate(PkixCertPath certPath, PkixParameters pkixParams)
|
||||
{
|
||||
IX509Selector targetConstraints = pkixParams.GetTargetConstraints();
|
||||
if (!(targetConstraints is X509AttrCertStoreSelector))
|
||||
{
|
||||
throw new ArgumentException("TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName, "pkixParams");
|
||||
}
|
||||
IX509AttributeCertificate attributeCert = ((X509AttrCertStoreSelector)targetConstraints).AttributeCert;
|
||||
PkixCertPath holderCertPath = Rfc3281CertPathUtilities.ProcessAttrCert1(attributeCert, pkixParams);
|
||||
PkixCertPathValidatorResult result = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams);
|
||||
X509Certificate x509Certificate = (X509Certificate)certPath.Certificates[0];
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert3(x509Certificate, pkixParams);
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert4(x509Certificate, pkixParams);
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert5(attributeCert, pkixParams);
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert7(attributeCert, certPath, holderCertPath, pkixParams);
|
||||
Rfc3281CertPathUtilities.AdditionalChecks(attributeCert, pkixParams);
|
||||
DateTime validCertDateFromValidityModel;
|
||||
try
|
||||
{
|
||||
validCertDateFromValidityModel = PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(pkixParams, null, -1);
|
||||
}
|
||||
catch (Exception cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Could not get validity date from attribute certificate.", cause);
|
||||
}
|
||||
Rfc3281CertPathUtilities.CheckCrls(attributeCert, pkixParams, x509Certificate, validCertDateFromValidityModel, certPath.Certificates);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixBuilderParameters : PkixParameters
|
||||
{
|
||||
private int maxPathLength = 5;
|
||||
|
||||
private ISet excludedCerts = new HashSet();
|
||||
|
||||
public virtual int MaxPathLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return maxPathLength;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < -1)
|
||||
{
|
||||
throw new InvalidParameterException("The maximum path length parameter can not be less than -1.");
|
||||
}
|
||||
maxPathLength = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static PkixBuilderParameters GetInstance(PkixParameters pkixParams)
|
||||
{
|
||||
PkixBuilderParameters pkixBuilderParameters = new PkixBuilderParameters(pkixParams.GetTrustAnchors(), new X509CertStoreSelector(pkixParams.GetTargetCertConstraints()));
|
||||
pkixBuilderParameters.SetParams(pkixParams);
|
||||
return pkixBuilderParameters;
|
||||
}
|
||||
|
||||
public PkixBuilderParameters(ISet trustAnchors, IX509Selector targetConstraints)
|
||||
: base(trustAnchors)
|
||||
{
|
||||
SetTargetCertConstraints(targetConstraints);
|
||||
}
|
||||
|
||||
public virtual ISet GetExcludedCerts()
|
||||
{
|
||||
return new HashSet(excludedCerts);
|
||||
}
|
||||
|
||||
public virtual void SetExcludedCerts(ISet excludedCerts)
|
||||
{
|
||||
if (excludedCerts == null)
|
||||
{
|
||||
excludedCerts = new HashSet();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.excludedCerts = new HashSet(excludedCerts);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetParams(PkixParameters parameters)
|
||||
{
|
||||
base.SetParams(parameters);
|
||||
if (parameters is PkixBuilderParameters)
|
||||
{
|
||||
PkixBuilderParameters pkixBuilderParameters = (PkixBuilderParameters)parameters;
|
||||
maxPathLength = pkixBuilderParameters.maxPathLength;
|
||||
excludedCerts = new HashSet(pkixBuilderParameters.excludedCerts);
|
||||
}
|
||||
}
|
||||
|
||||
public override object Clone()
|
||||
{
|
||||
PkixBuilderParameters pkixBuilderParameters = new PkixBuilderParameters(GetTrustAnchors(), GetTargetCertConstraints());
|
||||
pkixBuilderParameters.SetParams(this);
|
||||
return pkixBuilderParameters;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string newLine = Platform.NewLine;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append("PkixBuilderParameters [" + newLine);
|
||||
stringBuilder.Append(base.ToString());
|
||||
stringBuilder.Append(" Maximum Path Length: ");
|
||||
stringBuilder.Append(MaxPathLength);
|
||||
stringBuilder.Append(newLine + "]" + newLine);
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.OpenSsl;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixCertPath
|
||||
{
|
||||
internal static readonly IList certPathEncodings;
|
||||
|
||||
private readonly IList certificates;
|
||||
|
||||
public virtual IEnumerable Encodings => new EnumerableProxy(certPathEncodings);
|
||||
|
||||
public virtual IList Certificates => CollectionUtilities.ReadOnly(certificates);
|
||||
|
||||
static PkixCertPath()
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
list.Add("PkiPath");
|
||||
list.Add("PEM");
|
||||
list.Add("PKCS7");
|
||||
certPathEncodings = CollectionUtilities.ReadOnly(list);
|
||||
}
|
||||
|
||||
private static IList SortCerts(IList certs)
|
||||
{
|
||||
if (certs.Count < 2)
|
||||
{
|
||||
return certs;
|
||||
}
|
||||
X509Name issuerDN = ((X509Certificate)certs[0]).IssuerDN;
|
||||
bool flag = true;
|
||||
for (int i = 1; i != certs.Count; i++)
|
||||
{
|
||||
X509Certificate x509Certificate = (X509Certificate)certs[i];
|
||||
if (issuerDN.Equivalent(x509Certificate.SubjectDN, inOrder: true))
|
||||
{
|
||||
issuerDN = ((X509Certificate)certs[i]).IssuerDN;
|
||||
continue;
|
||||
}
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
return certs;
|
||||
}
|
||||
IList list = Platform.CreateArrayList(certs.Count);
|
||||
IList result = Platform.CreateArrayList(certs);
|
||||
for (int j = 0; j < certs.Count; j++)
|
||||
{
|
||||
X509Certificate x509Certificate2 = (X509Certificate)certs[j];
|
||||
bool flag2 = false;
|
||||
X509Name subjectDN = x509Certificate2.SubjectDN;
|
||||
foreach (X509Certificate cert in certs)
|
||||
{
|
||||
if (cert.IssuerDN.Equivalent(subjectDN, inOrder: true))
|
||||
{
|
||||
flag2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag2)
|
||||
{
|
||||
list.Add(x509Certificate2);
|
||||
certs.RemoveAt(j);
|
||||
}
|
||||
}
|
||||
if (list.Count > 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
for (int k = 0; k != list.Count; k++)
|
||||
{
|
||||
issuerDN = ((X509Certificate)list[k]).IssuerDN;
|
||||
for (int l = 0; l < certs.Count; l++)
|
||||
{
|
||||
X509Certificate x509Certificate4 = (X509Certificate)certs[l];
|
||||
if (issuerDN.Equivalent(x509Certificate4.SubjectDN, inOrder: true))
|
||||
{
|
||||
list.Add(x509Certificate4);
|
||||
certs.RemoveAt(l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (certs.Count > 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public PkixCertPath(ICollection certificates)
|
||||
{
|
||||
this.certificates = SortCerts(Platform.CreateArrayList(certificates));
|
||||
}
|
||||
|
||||
public PkixCertPath(Stream inStream)
|
||||
: this(inStream, "PkiPath")
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPath(Stream inStream, string encoding)
|
||||
{
|
||||
string text = Platform.ToUpperInvariant(encoding);
|
||||
IList list;
|
||||
try
|
||||
{
|
||||
if (text.Equals(Platform.ToUpperInvariant("PkiPath")))
|
||||
{
|
||||
Asn1InputStream asn1InputStream = new Asn1InputStream(inStream);
|
||||
Asn1Object asn1Object = asn1InputStream.ReadObject();
|
||||
if (!(asn1Object is Asn1Sequence))
|
||||
{
|
||||
throw new CertificateException("input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath");
|
||||
}
|
||||
list = Platform.CreateArrayList();
|
||||
foreach (Asn1Encodable item in (Asn1Sequence)asn1Object)
|
||||
{
|
||||
byte[] encoded = item.GetEncoded("DER");
|
||||
Stream inStream2 = new MemoryStream(encoded, writable: false);
|
||||
list.Insert(0, new X509CertificateParser().ReadCertificate(inStream2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!text.Equals("PKCS7") && !text.Equals("PEM"))
|
||||
{
|
||||
throw new CertificateException("unsupported encoding: " + encoding);
|
||||
}
|
||||
list = Platform.CreateArrayList(new X509CertificateParser().ReadCertificates(inStream));
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new CertificateException("IOException throw while decoding CertPath:\n" + ex.ToString());
|
||||
}
|
||||
certificates = SortCerts(list);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is PkixCertPath pkixCertPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IList list = Certificates;
|
||||
IList list2 = pkixCertPath.Certificates;
|
||||
if (list.Count != list2.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IEnumerator enumerator = list.GetEnumerator();
|
||||
IEnumerator enumerator2 = list.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
enumerator2.MoveNext();
|
||||
if (!object.Equals(enumerator.Current, enumerator2.Current))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Certificates.GetHashCode();
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
foreach (object encoding in Encodings)
|
||||
{
|
||||
if (encoding is string)
|
||||
{
|
||||
return GetEncoded((string)encoding);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded(string encoding)
|
||||
{
|
||||
if (Platform.EqualsIgnoreCase(encoding, "PkiPath"))
|
||||
{
|
||||
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
||||
for (int num = certificates.Count - 1; num >= 0; num--)
|
||||
{
|
||||
asn1EncodableVector.Add(ToAsn1Object((X509Certificate)certificates[num]));
|
||||
}
|
||||
return ToDerEncoded(new DerSequence(asn1EncodableVector));
|
||||
}
|
||||
if (Platform.EqualsIgnoreCase(encoding, "PKCS7"))
|
||||
{
|
||||
ContentInfo contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, null);
|
||||
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
||||
for (int i = 0; i != certificates.Count; i++)
|
||||
{
|
||||
asn1EncodableVector2.Add(ToAsn1Object((X509Certificate)certificates[i]));
|
||||
}
|
||||
SignedData content = new SignedData(new DerInteger(1), new DerSet(), contentInfo, new DerSet(asn1EncodableVector2), null, new DerSet());
|
||||
return ToDerEncoded(new ContentInfo(PkcsObjectIdentifiers.SignedData, content));
|
||||
}
|
||||
if (Platform.EqualsIgnoreCase(encoding, "PEM"))
|
||||
{
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
PemWriter pemWriter = new PemWriter(new StreamWriter(memoryStream));
|
||||
try
|
||||
{
|
||||
for (int j = 0; j != certificates.Count; j++)
|
||||
{
|
||||
pemWriter.WriteObject(certificates[j]);
|
||||
}
|
||||
Platform.Dispose(pemWriter.Writer);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new CertificateEncodingException("can't encode certificate for PEM encoded path");
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
throw new CertificateEncodingException("unsupported encoding: " + encoding);
|
||||
}
|
||||
|
||||
private Asn1Object ToAsn1Object(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Asn1Object.FromByteArray(cert.GetEncoded());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateEncodingException("Exception while encoding certificate", e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ToDerEncoded(Asn1Encodable obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
return obj.GetEncoded("DER");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CertificateEncodingException("Exception thrown", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixCertPathBuilder
|
||||
{
|
||||
private Exception certPathException;
|
||||
|
||||
public virtual PkixCertPathBuilderResult Build(PkixBuilderParameters pkixParams)
|
||||
{
|
||||
IX509Selector targetCertConstraints = pkixParams.GetTargetCertConstraints();
|
||||
if (!(targetCertConstraints is X509CertStoreSelector))
|
||||
{
|
||||
throw new PkixCertPathBuilderException("TargetConstraints must be an instance of " + typeof(X509CertStoreSelector).FullName + " for " + Platform.GetTypeName(this) + " class.");
|
||||
}
|
||||
ISet set = new HashSet();
|
||||
try
|
||||
{
|
||||
set.AddAll(PkixCertPathValidatorUtilities.FindCertificates((X509CertStoreSelector)targetCertConstraints, pkixParams.GetStores()));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("Error finding target certificate.", exception);
|
||||
}
|
||||
if (set.IsEmpty)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("No certificate found matching targetContraints.");
|
||||
}
|
||||
PkixCertPathBuilderResult pkixCertPathBuilderResult = null;
|
||||
IList tbvPath = Platform.CreateArrayList();
|
||||
foreach (X509Certificate item in set)
|
||||
{
|
||||
pkixCertPathBuilderResult = Build(item, pkixParams, tbvPath);
|
||||
if (pkixCertPathBuilderResult != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pkixCertPathBuilderResult == null && certPathException != null)
|
||||
{
|
||||
throw new PkixCertPathBuilderException(certPathException.Message, certPathException.InnerException);
|
||||
}
|
||||
if (pkixCertPathBuilderResult == null && certPathException == null)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("Unable to find certificate chain.");
|
||||
}
|
||||
return pkixCertPathBuilderResult;
|
||||
}
|
||||
|
||||
protected virtual PkixCertPathBuilderResult Build(X509Certificate tbvCert, PkixBuilderParameters pkixParams, IList 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;
|
||||
PkixCertPathValidator pkixCertPathValidator = new PkixCertPathValidator();
|
||||
try
|
||||
{
|
||||
if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
|
||||
{
|
||||
PkixCertPath pkixCertPath = null;
|
||||
try
|
||||
{
|
||||
pkixCertPath = new PkixCertPath(tbvPath);
|
||||
}
|
||||
catch (Exception innerException)
|
||||
{
|
||||
throw new Exception("Certification path could not be constructed from certificate list.", innerException);
|
||||
}
|
||||
PkixCertPathValidatorResult pkixCertPathValidatorResult = null;
|
||||
try
|
||||
{
|
||||
pkixCertPathValidatorResult = pkixCertPathValidator.Validate(pkixCertPath, pkixParams);
|
||||
}
|
||||
catch (Exception innerException2)
|
||||
{
|
||||
throw new Exception("Certification path could not be validated.", innerException2);
|
||||
}
|
||||
return new PkixCertPathBuilderResult(pkixCertPath, pkixCertPathValidatorResult.TrustAnchor, pkixCertPathValidatorResult.PolicyTree, pkixCertPathValidatorResult.SubjectPublicKey);
|
||||
}
|
||||
try
|
||||
{
|
||||
PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams);
|
||||
}
|
||||
catch (CertificateParsingException innerException3)
|
||||
{
|
||||
throw new Exception("No additiontal X.509 stores can be added from certificate locations.", innerException3);
|
||||
}
|
||||
HashSet hashSet = new HashSet();
|
||||
try
|
||||
{
|
||||
hashSet.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
|
||||
}
|
||||
catch (Exception innerException4)
|
||||
{
|
||||
throw new Exception("Cannot find issuer certificate for certificate in certification path.", innerException4);
|
||||
}
|
||||
if (hashSet.IsEmpty)
|
||||
{
|
||||
throw new Exception("No issuer certificate for certificate in certification path found.");
|
||||
}
|
||||
foreach (X509Certificate item in hashSet)
|
||||
{
|
||||
pkixCertPathBuilderResult = Build(item, pkixParams, tbvPath);
|
||||
if (pkixCertPathBuilderResult != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
certPathException = ex;
|
||||
}
|
||||
if (pkixCertPathBuilderResult == null)
|
||||
{
|
||||
tbvPath.Remove(tbvCert);
|
||||
}
|
||||
return pkixCertPathBuilderResult;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
[Serializable]
|
||||
public class PkixCertPathBuilderException : GeneralSecurityException
|
||||
{
|
||||
public PkixCertPathBuilderException()
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathBuilderException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathBuilderException(string message, Exception exception)
|
||||
: base(message, exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixCertPathBuilderResult : PkixCertPathValidatorResult
|
||||
{
|
||||
private PkixCertPath certPath;
|
||||
|
||||
public PkixCertPath CertPath => certPath;
|
||||
|
||||
public PkixCertPathBuilderResult(PkixCertPath certPath, TrustAnchor trustAnchor, PkixPolicyNode policyTree, AsymmetricKeyParameter subjectPublicKey)
|
||||
: base(trustAnchor, policyTree, subjectPublicKey)
|
||||
{
|
||||
if (certPath == null)
|
||||
{
|
||||
throw new ArgumentNullException("certPath");
|
||||
}
|
||||
this.certPath = certPath;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append("SimplePKIXCertPathBuilderResult: [\n");
|
||||
stringBuilder.Append(" Certification Path: ").Append(CertPath).Append('\n');
|
||||
stringBuilder.Append(" Trust Anchor: ").Append(base.TrustAnchor.TrustedCert.IssuerDN.ToString()).Append('\n');
|
||||
stringBuilder.Append(" Subject Public Key: ").Append(base.SubjectPublicKey).Append("\n]");
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public abstract class PkixCertPathChecker
|
||||
{
|
||||
public abstract void Init(bool forward);
|
||||
|
||||
public abstract bool IsForwardCheckingSupported();
|
||||
|
||||
public abstract ISet GetSupportedExtensions();
|
||||
|
||||
public abstract void Check(X509Certificate cert, ISet unresolvedCritExts);
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
return MemberwiseClone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixCertPathValidator
|
||||
{
|
||||
public virtual PkixCertPathValidatorResult Validate(PkixCertPath certPath, PkixParameters paramsPkix)
|
||||
{
|
||||
if (paramsPkix.GetTrustAnchors() == null)
|
||||
{
|
||||
throw new ArgumentException("trustAnchors is null, this is not allowed for certification path validation.", "parameters");
|
||||
}
|
||||
IList certificates = certPath.Certificates;
|
||||
int count = certificates.Count;
|
||||
if (certificates.Count == 0)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Certification path is empty.", null, certPath, 0);
|
||||
}
|
||||
ISet initialPolicies = paramsPkix.GetInitialPolicies();
|
||||
TrustAnchor trustAnchor;
|
||||
try
|
||||
{
|
||||
trustAnchor = PkixCertPathValidatorUtilities.FindTrustAnchor((X509Certificate)certificates[certificates.Count - 1], paramsPkix.GetTrustAnchors());
|
||||
if (trustAnchor == null)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1);
|
||||
}
|
||||
CheckCertificate(trustAnchor.TrustedCert);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(ex.Message, ex.InnerException, certPath, certificates.Count - 1);
|
||||
}
|
||||
int num = 0;
|
||||
IList[] array = new IList[count + 1];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = Platform.CreateArrayList();
|
||||
}
|
||||
ISet set = new HashSet();
|
||||
set.Add(Rfc3280CertPathUtilities.ANY_POLICY);
|
||||
PkixPolicyNode pkixPolicyNode = new PkixPolicyNode(Platform.CreateArrayList(), 0, set, null, new HashSet(), Rfc3280CertPathUtilities.ANY_POLICY, critical: false);
|
||||
array[0].Add(pkixPolicyNode);
|
||||
PkixNameConstraintValidator nameConstraintValidator = new PkixNameConstraintValidator();
|
||||
ISet acceptablePolicies = new HashSet();
|
||||
int explicitPolicy = ((!paramsPkix.IsExplicitPolicyRequired) ? (count + 1) : 0);
|
||||
int inhibitAnyPolicy = ((!paramsPkix.IsAnyPolicyInhibited) ? (count + 1) : 0);
|
||||
int policyMapping = ((!paramsPkix.IsPolicyMappingInhibited) ? (count + 1) : 0);
|
||||
X509Certificate x509Certificate = trustAnchor.TrustedCert;
|
||||
X509Name workingIssuerName;
|
||||
AsymmetricKeyParameter asymmetricKeyParameter;
|
||||
try
|
||||
{
|
||||
if (x509Certificate != null)
|
||||
{
|
||||
workingIssuerName = x509Certificate.SubjectDN;
|
||||
asymmetricKeyParameter = x509Certificate.GetPublicKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
workingIssuerName = new X509Name(trustAnchor.CAName);
|
||||
asymmetricKeyParameter = trustAnchor.CAPublicKey;
|
||||
}
|
||||
}
|
||||
catch (ArgumentException cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", cause, certPath, -1);
|
||||
}
|
||||
try
|
||||
{
|
||||
PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(asymmetricKeyParameter);
|
||||
}
|
||||
catch (PkixCertPathValidatorException cause2)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Algorithm identifier of public key of trust anchor could not be read.", cause2, certPath, -1);
|
||||
}
|
||||
int maxPathLength = count;
|
||||
X509CertStoreSelector targetCertConstraints = paramsPkix.GetTargetCertConstraints();
|
||||
if (targetCertConstraints != null && !targetCertConstraints.Match((X509Certificate)certificates[0]))
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Target certificate in certification path does not match targetConstraints.", null, certPath, 0);
|
||||
}
|
||||
IList certPathCheckers = paramsPkix.GetCertPathCheckers();
|
||||
IEnumerator enumerator = certPathCheckers.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((PkixCertPathChecker)enumerator.Current).Init(forward: false);
|
||||
}
|
||||
X509Certificate x509Certificate2 = null;
|
||||
for (num = certificates.Count - 1; num >= 0; num--)
|
||||
{
|
||||
int num2 = count - num;
|
||||
x509Certificate2 = (X509Certificate)certificates[num];
|
||||
try
|
||||
{
|
||||
CheckCertificate(x509Certificate2);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(ex2.Message, ex2.InnerException, certPath, num);
|
||||
}
|
||||
Rfc3280CertPathUtilities.ProcessCertA(certPath, paramsPkix, num, asymmetricKeyParameter, workingIssuerName, x509Certificate);
|
||||
Rfc3280CertPathUtilities.ProcessCertBC(certPath, num, nameConstraintValidator);
|
||||
pkixPolicyNode = Rfc3280CertPathUtilities.ProcessCertD(certPath, num, acceptablePolicies, pkixPolicyNode, array, inhibitAnyPolicy);
|
||||
pkixPolicyNode = Rfc3280CertPathUtilities.ProcessCertE(certPath, num, pkixPolicyNode);
|
||||
Rfc3280CertPathUtilities.ProcessCertF(certPath, num, pkixPolicyNode, explicitPolicy);
|
||||
if (num2 != count)
|
||||
{
|
||||
if (x509Certificate2 != null && x509Certificate2.Version == 1)
|
||||
{
|
||||
if (num2 != 1 || !x509Certificate2.Equals(trustAnchor.TrustedCert))
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Version 1 certificates can't be used as CA ones.", null, certPath, num);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rfc3280CertPathUtilities.PrepareNextCertA(certPath, num);
|
||||
pkixPolicyNode = Rfc3280CertPathUtilities.PrepareCertB(certPath, num, array, pkixPolicyNode, policyMapping);
|
||||
Rfc3280CertPathUtilities.PrepareNextCertG(certPath, num, nameConstraintValidator);
|
||||
explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertH1(certPath, num, explicitPolicy);
|
||||
policyMapping = Rfc3280CertPathUtilities.PrepareNextCertH2(certPath, num, policyMapping);
|
||||
inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertH3(certPath, num, inhibitAnyPolicy);
|
||||
explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertI1(certPath, num, explicitPolicy);
|
||||
policyMapping = Rfc3280CertPathUtilities.PrepareNextCertI2(certPath, num, policyMapping);
|
||||
inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertJ(certPath, num, inhibitAnyPolicy);
|
||||
Rfc3280CertPathUtilities.PrepareNextCertK(certPath, num);
|
||||
maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertL(certPath, num, maxPathLength);
|
||||
maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertM(certPath, num, maxPathLength);
|
||||
Rfc3280CertPathUtilities.PrepareNextCertN(certPath, num);
|
||||
ISet criticalExtensionOids = x509Certificate2.GetCriticalExtensionOids();
|
||||
if (criticalExtensionOids != null)
|
||||
{
|
||||
criticalExtensionOids = new HashSet(criticalExtensionOids);
|
||||
criticalExtensionOids.Remove(X509Extensions.KeyUsage.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.CertificatePolicies.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.PolicyMappings.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.InhibitAnyPolicy.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.IssuingDistributionPoint.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.DeltaCrlIndicator.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.PolicyConstraints.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.BasicConstraints.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.SubjectAlternativeName.Id);
|
||||
criticalExtensionOids.Remove(X509Extensions.NameConstraints.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
criticalExtensionOids = new HashSet();
|
||||
}
|
||||
Rfc3280CertPathUtilities.PrepareNextCertO(certPath, num, criticalExtensionOids, certPathCheckers);
|
||||
x509Certificate = x509Certificate2;
|
||||
workingIssuerName = x509Certificate.SubjectDN;
|
||||
try
|
||||
{
|
||||
asymmetricKeyParameter = PkixCertPathValidatorUtilities.GetNextWorkingKey(certPath.Certificates, num);
|
||||
}
|
||||
catch (PkixCertPathValidatorException cause3)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Next working key could not be retrieved.", cause3, certPath, num);
|
||||
}
|
||||
PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(asymmetricKeyParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
explicitPolicy = Rfc3280CertPathUtilities.WrapupCertA(explicitPolicy, x509Certificate2);
|
||||
explicitPolicy = Rfc3280CertPathUtilities.WrapupCertB(certPath, num + 1, explicitPolicy);
|
||||
ISet criticalExtensionOids2 = x509Certificate2.GetCriticalExtensionOids();
|
||||
if (criticalExtensionOids2 != null)
|
||||
{
|
||||
criticalExtensionOids2 = new HashSet(criticalExtensionOids2);
|
||||
criticalExtensionOids2.Remove(X509Extensions.KeyUsage.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.CertificatePolicies.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.PolicyMappings.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.InhibitAnyPolicy.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.IssuingDistributionPoint.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.DeltaCrlIndicator.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.PolicyConstraints.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.BasicConstraints.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.SubjectAlternativeName.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.NameConstraints.Id);
|
||||
criticalExtensionOids2.Remove(X509Extensions.CrlDistributionPoints.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
criticalExtensionOids2 = new HashSet();
|
||||
}
|
||||
Rfc3280CertPathUtilities.WrapupCertF(certPath, num + 1, certPathCheckers, criticalExtensionOids2);
|
||||
PkixPolicyNode pkixPolicyNode2 = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix, initialPolicies, num + 1, array, pkixPolicyNode, acceptablePolicies);
|
||||
if (explicitPolicy > 0 || pkixPolicyNode2 != null)
|
||||
{
|
||||
return new PkixCertPathValidatorResult(trustAnchor, pkixPolicyNode2, x509Certificate2.GetPublicKey());
|
||||
}
|
||||
throw new PkixCertPathValidatorException("Path processing failed on policy.", null, certPath, num);
|
||||
}
|
||||
|
||||
internal static void CheckCertificate(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
TbsCertificateStructure.GetInstance(cert.CertificateStructure.TbsCertificate);
|
||||
}
|
||||
catch (CertificateEncodingException innerException)
|
||||
{
|
||||
throw new Exception("unable to process TBSCertificate", innerException);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
[Serializable]
|
||||
public class PkixCertPathValidatorException : GeneralSecurityException
|
||||
{
|
||||
private Exception cause;
|
||||
|
||||
private PkixCertPath certPath;
|
||||
|
||||
private int index = -1;
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
string message = base.Message;
|
||||
if (message != null)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
if (cause != null)
|
||||
{
|
||||
return cause.Message;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public PkixCertPath CertPath => certPath;
|
||||
|
||||
public int Index => index;
|
||||
|
||||
public PkixCertPathValidatorException()
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathValidatorException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathValidatorException(string message, Exception cause)
|
||||
: base(message)
|
||||
{
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public PkixCertPathValidatorException(string message, Exception cause, PkixCertPath certPath, int index)
|
||||
: base(message)
|
||||
{
|
||||
if (certPath == null && index != -1)
|
||||
{
|
||||
throw new ArgumentNullException("certPath = null and index != -1");
|
||||
}
|
||||
if (index < -1 || (certPath != null && index >= certPath.Certificates.Count))
|
||||
{
|
||||
throw new IndexOutOfRangeException(" index < -1 or out of bound of certPath.getCertificates()");
|
||||
}
|
||||
this.cause = cause;
|
||||
this.certPath = certPath;
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixCertPathValidatorResult
|
||||
{
|
||||
private TrustAnchor trustAnchor;
|
||||
|
||||
private PkixPolicyNode policyTree;
|
||||
|
||||
private AsymmetricKeyParameter subjectPublicKey;
|
||||
|
||||
public PkixPolicyNode PolicyTree => policyTree;
|
||||
|
||||
public TrustAnchor TrustAnchor => trustAnchor;
|
||||
|
||||
public AsymmetricKeyParameter SubjectPublicKey => subjectPublicKey;
|
||||
|
||||
public PkixCertPathValidatorResult(TrustAnchor trustAnchor, PkixPolicyNode policyTree, AsymmetricKeyParameter subjectPublicKey)
|
||||
{
|
||||
if (subjectPublicKey == null)
|
||||
{
|
||||
throw new NullReferenceException("subjectPublicKey must be non-null");
|
||||
}
|
||||
if (trustAnchor == null)
|
||||
{
|
||||
throw new NullReferenceException("trustAnchor must be non-null");
|
||||
}
|
||||
this.trustAnchor = trustAnchor;
|
||||
this.policyTree = policyTree;
|
||||
this.subjectPublicKey = subjectPublicKey;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new PkixCertPathValidatorResult(TrustAnchor, PolicyTree, SubjectPublicKey);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append("PKIXCertPathValidatorResult: [ \n");
|
||||
stringBuilder.Append(" Trust Anchor: ").Append(TrustAnchor).Append('\n');
|
||||
stringBuilder.Append(" Policy Tree: ").Append(PolicyTree).Append('\n');
|
||||
stringBuilder.Append(" Subject Public Key: ").Append(SubjectPublicKey).Append("\n]");
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,795 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixCrlUtilities
|
||||
{
|
||||
public virtual ISet FindCrls(X509CrlStoreSelector crlselect, PkixParameters paramsPkix, DateTime currentDate)
|
||||
{
|
||||
ISet set = new HashSet();
|
||||
try
|
||||
{
|
||||
set.AddAll(FindCrls(crlselect, paramsPkix.GetAdditionalStores()));
|
||||
set.AddAll(FindCrls(crlselect, paramsPkix.GetStores()));
|
||||
}
|
||||
catch (Exception innerException)
|
||||
{
|
||||
throw new Exception("Exception obtaining complete CRLs.", innerException);
|
||||
}
|
||||
ISet set2 = new HashSet();
|
||||
DateTime dateTime = currentDate;
|
||||
if (paramsPkix.Date != null)
|
||||
{
|
||||
dateTime = paramsPkix.Date.Value;
|
||||
}
|
||||
foreach (X509Crl item in set)
|
||||
{
|
||||
if (item.NextUpdate.Value.CompareTo((object?)dateTime) <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
X509Certificate certificateChecking = crlselect.CertificateChecking;
|
||||
if (certificateChecking != null)
|
||||
{
|
||||
if (item.ThisUpdate.CompareTo((object?)certificateChecking.NotAfter) < 0)
|
||||
{
|
||||
set2.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set2.Add(item);
|
||||
}
|
||||
}
|
||||
return set2;
|
||||
}
|
||||
|
||||
public virtual ISet FindCrls(X509CrlStoreSelector crlselect, PkixParameters paramsPkix)
|
||||
{
|
||||
ISet set = new HashSet();
|
||||
try
|
||||
{
|
||||
set.AddAll(FindCrls(crlselect, paramsPkix.GetStores()));
|
||||
return set;
|
||||
}
|
||||
catch (Exception innerException)
|
||||
{
|
||||
throw new Exception("Exception obtaining complete CRLs.", innerException);
|
||||
}
|
||||
}
|
||||
|
||||
private ICollection FindCrls(X509CrlStoreSelector crlSelect, IList crlStores)
|
||||
{
|
||||
ISet set = new HashSet();
|
||||
Exception ex = null;
|
||||
bool flag = false;
|
||||
foreach (IX509Store crlStore in crlStores)
|
||||
{
|
||||
try
|
||||
{
|
||||
set.AddAll(crlStore.GetMatches(crlSelect));
|
||||
flag = true;
|
||||
}
|
||||
catch (X509StoreException innerException)
|
||||
{
|
||||
ex = new Exception("Exception searching in X.509 CRL store.", innerException);
|
||||
}
|
||||
}
|
||||
if (!flag && ex != null)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
[Serializable]
|
||||
public class PkixNameConstraintValidatorException : Exception
|
||||
{
|
||||
public PkixNameConstraintValidatorException(string msg)
|
||||
: base(msg)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixParameters
|
||||
{
|
||||
public const int PkixValidityModel = 0;
|
||||
|
||||
public const int ChainValidityModel = 1;
|
||||
|
||||
private ISet trustAnchors;
|
||||
|
||||
private DateTimeObject date;
|
||||
|
||||
private IList certPathCheckers;
|
||||
|
||||
private bool revocationEnabled = true;
|
||||
|
||||
private ISet initialPolicies;
|
||||
|
||||
private bool explicitPolicyRequired = false;
|
||||
|
||||
private bool anyPolicyInhibited = false;
|
||||
|
||||
private bool policyMappingInhibited = false;
|
||||
|
||||
private bool policyQualifiersRejected = true;
|
||||
|
||||
private IX509Selector certSelector;
|
||||
|
||||
private IList stores;
|
||||
|
||||
private IX509Selector selector;
|
||||
|
||||
private bool additionalLocationsEnabled;
|
||||
|
||||
private IList additionalStores;
|
||||
|
||||
private ISet trustedACIssuers;
|
||||
|
||||
private ISet necessaryACAttributes;
|
||||
|
||||
private ISet prohibitedACAttributes;
|
||||
|
||||
private ISet attrCertCheckers;
|
||||
|
||||
private int validityModel = 0;
|
||||
|
||||
private bool useDeltas = false;
|
||||
|
||||
public virtual bool IsRevocationEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return revocationEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
revocationEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsExplicitPolicyRequired
|
||||
{
|
||||
get
|
||||
{
|
||||
return explicitPolicyRequired;
|
||||
}
|
||||
set
|
||||
{
|
||||
explicitPolicyRequired = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsAnyPolicyInhibited
|
||||
{
|
||||
get
|
||||
{
|
||||
return anyPolicyInhibited;
|
||||
}
|
||||
set
|
||||
{
|
||||
anyPolicyInhibited = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsPolicyMappingInhibited
|
||||
{
|
||||
get
|
||||
{
|
||||
return policyMappingInhibited;
|
||||
}
|
||||
set
|
||||
{
|
||||
policyMappingInhibited = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsPolicyQualifiersRejected
|
||||
{
|
||||
get
|
||||
{
|
||||
return policyQualifiersRejected;
|
||||
}
|
||||
set
|
||||
{
|
||||
policyQualifiersRejected = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual DateTimeObject Date
|
||||
{
|
||||
get
|
||||
{
|
||||
return date;
|
||||
}
|
||||
set
|
||||
{
|
||||
date = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsUseDeltasEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return useDeltas;
|
||||
}
|
||||
set
|
||||
{
|
||||
useDeltas = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int ValidityModel
|
||||
{
|
||||
get
|
||||
{
|
||||
return validityModel;
|
||||
}
|
||||
set
|
||||
{
|
||||
validityModel = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsAdditionalLocationsEnabled => additionalLocationsEnabled;
|
||||
|
||||
public PkixParameters(ISet trustAnchors)
|
||||
{
|
||||
SetTrustAnchors(trustAnchors);
|
||||
initialPolicies = new HashSet();
|
||||
certPathCheckers = Platform.CreateArrayList();
|
||||
stores = Platform.CreateArrayList();
|
||||
additionalStores = Platform.CreateArrayList();
|
||||
trustedACIssuers = new HashSet();
|
||||
necessaryACAttributes = new HashSet();
|
||||
prohibitedACAttributes = new HashSet();
|
||||
attrCertCheckers = new HashSet();
|
||||
}
|
||||
|
||||
public virtual ISet GetTrustAnchors()
|
||||
{
|
||||
return new HashSet(trustAnchors);
|
||||
}
|
||||
|
||||
public virtual void SetTrustAnchors(ISet tas)
|
||||
{
|
||||
if (tas == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
if (tas.IsEmpty)
|
||||
{
|
||||
throw new ArgumentException("non-empty set required", "value");
|
||||
}
|
||||
trustAnchors = new HashSet();
|
||||
foreach (TrustAnchor ta in tas)
|
||||
{
|
||||
if (ta != null)
|
||||
{
|
||||
trustAnchors.Add(ta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual X509CertStoreSelector GetTargetCertConstraints()
|
||||
{
|
||||
if (certSelector == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return (X509CertStoreSelector)certSelector.Clone();
|
||||
}
|
||||
|
||||
public virtual void SetTargetCertConstraints(IX509Selector selector)
|
||||
{
|
||||
if (selector == null)
|
||||
{
|
||||
certSelector = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
certSelector = (IX509Selector)selector.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ISet GetInitialPolicies()
|
||||
{
|
||||
ISet s = initialPolicies;
|
||||
if (initialPolicies == null)
|
||||
{
|
||||
s = new HashSet();
|
||||
}
|
||||
return new HashSet(s);
|
||||
}
|
||||
|
||||
public virtual void SetInitialPolicies(ISet initialPolicies)
|
||||
{
|
||||
this.initialPolicies = new HashSet();
|
||||
if (initialPolicies == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (string initialPolicy in initialPolicies)
|
||||
{
|
||||
if (initialPolicy != null)
|
||||
{
|
||||
this.initialPolicies.Add(initialPolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetCertPathCheckers(IList checkers)
|
||||
{
|
||||
certPathCheckers = Platform.CreateArrayList();
|
||||
if (checkers == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (PkixCertPathChecker checker in checkers)
|
||||
{
|
||||
certPathCheckers.Add(checker.Clone());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IList GetCertPathCheckers()
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
foreach (PkixCertPathChecker certPathChecker in certPathCheckers)
|
||||
{
|
||||
list.Add(certPathChecker.Clone());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public virtual void AddCertPathChecker(PkixCertPathChecker checker)
|
||||
{
|
||||
if (checker != null)
|
||||
{
|
||||
certPathCheckers.Add(checker.Clone());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
PkixParameters pkixParameters = new PkixParameters(GetTrustAnchors());
|
||||
pkixParameters.SetParams(this);
|
||||
return pkixParameters;
|
||||
}
|
||||
|
||||
protected virtual void SetParams(PkixParameters parameters)
|
||||
{
|
||||
Date = parameters.Date;
|
||||
SetCertPathCheckers(parameters.GetCertPathCheckers());
|
||||
IsAnyPolicyInhibited = parameters.IsAnyPolicyInhibited;
|
||||
IsExplicitPolicyRequired = parameters.IsExplicitPolicyRequired;
|
||||
IsPolicyMappingInhibited = parameters.IsPolicyMappingInhibited;
|
||||
IsRevocationEnabled = parameters.IsRevocationEnabled;
|
||||
SetInitialPolicies(parameters.GetInitialPolicies());
|
||||
IsPolicyQualifiersRejected = parameters.IsPolicyQualifiersRejected;
|
||||
SetTargetCertConstraints(parameters.GetTargetCertConstraints());
|
||||
SetTrustAnchors(parameters.GetTrustAnchors());
|
||||
validityModel = parameters.validityModel;
|
||||
useDeltas = parameters.useDeltas;
|
||||
additionalLocationsEnabled = parameters.additionalLocationsEnabled;
|
||||
selector = ((parameters.selector == null) ? null : ((IX509Selector)parameters.selector.Clone()));
|
||||
stores = Platform.CreateArrayList(parameters.stores);
|
||||
additionalStores = Platform.CreateArrayList(parameters.additionalStores);
|
||||
trustedACIssuers = new HashSet(parameters.trustedACIssuers);
|
||||
prohibitedACAttributes = new HashSet(parameters.prohibitedACAttributes);
|
||||
necessaryACAttributes = new HashSet(parameters.necessaryACAttributes);
|
||||
attrCertCheckers = new HashSet(parameters.attrCertCheckers);
|
||||
}
|
||||
|
||||
public virtual void SetStores(IList stores)
|
||||
{
|
||||
if (stores == null)
|
||||
{
|
||||
this.stores = Platform.CreateArrayList();
|
||||
return;
|
||||
}
|
||||
foreach (object store in stores)
|
||||
{
|
||||
if (!(store is IX509Store))
|
||||
{
|
||||
throw new InvalidCastException("All elements of list must be of type " + typeof(IX509Store).FullName);
|
||||
}
|
||||
}
|
||||
this.stores = Platform.CreateArrayList(stores);
|
||||
}
|
||||
|
||||
public virtual void AddStore(IX509Store store)
|
||||
{
|
||||
if (store != null)
|
||||
{
|
||||
stores.Add(store);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddAdditionalStore(IX509Store store)
|
||||
{
|
||||
if (store != null)
|
||||
{
|
||||
additionalStores.Add(store);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IList GetAdditionalStores()
|
||||
{
|
||||
return Platform.CreateArrayList(additionalStores);
|
||||
}
|
||||
|
||||
public virtual IList GetStores()
|
||||
{
|
||||
return Platform.CreateArrayList(stores);
|
||||
}
|
||||
|
||||
public virtual void SetAdditionalLocationsEnabled(bool enabled)
|
||||
{
|
||||
additionalLocationsEnabled = enabled;
|
||||
}
|
||||
|
||||
public virtual IX509Selector GetTargetConstraints()
|
||||
{
|
||||
if (selector != null)
|
||||
{
|
||||
return (IX509Selector)selector.Clone();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void SetTargetConstraints(IX509Selector selector)
|
||||
{
|
||||
if (selector != null)
|
||||
{
|
||||
this.selector = (IX509Selector)selector.Clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selector = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ISet GetTrustedACIssuers()
|
||||
{
|
||||
return new HashSet(trustedACIssuers);
|
||||
}
|
||||
|
||||
public virtual void SetTrustedACIssuers(ISet trustedACIssuers)
|
||||
{
|
||||
if (trustedACIssuers == null)
|
||||
{
|
||||
this.trustedACIssuers = new HashSet();
|
||||
return;
|
||||
}
|
||||
foreach (object trustedACIssuer in trustedACIssuers)
|
||||
{
|
||||
if (!(trustedACIssuer is TrustAnchor))
|
||||
{
|
||||
throw new InvalidCastException("All elements of set must be of type " + typeof(TrustAnchor).FullName + ".");
|
||||
}
|
||||
}
|
||||
this.trustedACIssuers = new HashSet(trustedACIssuers);
|
||||
}
|
||||
|
||||
public virtual ISet GetNecessaryACAttributes()
|
||||
{
|
||||
return new HashSet(necessaryACAttributes);
|
||||
}
|
||||
|
||||
public virtual void SetNecessaryACAttributes(ISet necessaryACAttributes)
|
||||
{
|
||||
if (necessaryACAttributes == null)
|
||||
{
|
||||
this.necessaryACAttributes = new HashSet();
|
||||
return;
|
||||
}
|
||||
foreach (object necessaryACAttribute in necessaryACAttributes)
|
||||
{
|
||||
if (!(necessaryACAttribute is string))
|
||||
{
|
||||
throw new InvalidCastException("All elements of set must be of type string.");
|
||||
}
|
||||
}
|
||||
this.necessaryACAttributes = new HashSet(necessaryACAttributes);
|
||||
}
|
||||
|
||||
public virtual ISet GetProhibitedACAttributes()
|
||||
{
|
||||
return new HashSet(prohibitedACAttributes);
|
||||
}
|
||||
|
||||
public virtual void SetProhibitedACAttributes(ISet prohibitedACAttributes)
|
||||
{
|
||||
if (prohibitedACAttributes == null)
|
||||
{
|
||||
this.prohibitedACAttributes = new HashSet();
|
||||
return;
|
||||
}
|
||||
foreach (object prohibitedACAttribute in prohibitedACAttributes)
|
||||
{
|
||||
if (!(prohibitedACAttribute is string))
|
||||
{
|
||||
throw new InvalidCastException("All elements of set must be of type string.");
|
||||
}
|
||||
}
|
||||
this.prohibitedACAttributes = new HashSet(prohibitedACAttributes);
|
||||
}
|
||||
|
||||
public virtual ISet GetAttrCertCheckers()
|
||||
{
|
||||
return new HashSet(attrCertCheckers);
|
||||
}
|
||||
|
||||
public virtual void SetAttrCertCheckers(ISet attrCertCheckers)
|
||||
{
|
||||
if (attrCertCheckers == null)
|
||||
{
|
||||
this.attrCertCheckers = new HashSet();
|
||||
return;
|
||||
}
|
||||
foreach (object attrCertChecker in attrCertCheckers)
|
||||
{
|
||||
if (!(attrCertChecker is PkixAttrCertChecker))
|
||||
{
|
||||
throw new InvalidCastException("All elements of set must be of type " + typeof(PkixAttrCertChecker).FullName + ".");
|
||||
}
|
||||
}
|
||||
this.attrCertCheckers = new HashSet(attrCertCheckers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class PkixPolicyNode
|
||||
{
|
||||
protected IList mChildren;
|
||||
|
||||
protected int mDepth;
|
||||
|
||||
protected ISet mExpectedPolicies;
|
||||
|
||||
protected PkixPolicyNode mParent;
|
||||
|
||||
protected ISet mPolicyQualifiers;
|
||||
|
||||
protected string mValidPolicy;
|
||||
|
||||
protected bool mCritical;
|
||||
|
||||
public virtual int Depth => mDepth;
|
||||
|
||||
public virtual IEnumerable Children => new EnumerableProxy(mChildren);
|
||||
|
||||
public virtual bool IsCritical
|
||||
{
|
||||
get
|
||||
{
|
||||
return mCritical;
|
||||
}
|
||||
set
|
||||
{
|
||||
mCritical = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ISet PolicyQualifiers => new HashSet(mPolicyQualifiers);
|
||||
|
||||
public virtual string ValidPolicy => mValidPolicy;
|
||||
|
||||
public virtual bool HasChildren => mChildren.Count != 0;
|
||||
|
||||
public virtual ISet ExpectedPolicies
|
||||
{
|
||||
get
|
||||
{
|
||||
return new HashSet(mExpectedPolicies);
|
||||
}
|
||||
set
|
||||
{
|
||||
mExpectedPolicies = new HashSet(value);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual PkixPolicyNode Parent
|
||||
{
|
||||
get
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
set
|
||||
{
|
||||
mParent = value;
|
||||
}
|
||||
}
|
||||
|
||||
public PkixPolicyNode(IList children, int depth, ISet expectedPolicies, PkixPolicyNode parent, ISet policyQualifiers, string validPolicy, bool critical)
|
||||
{
|
||||
if (children == null)
|
||||
{
|
||||
mChildren = Platform.CreateArrayList();
|
||||
}
|
||||
else
|
||||
{
|
||||
mChildren = Platform.CreateArrayList(children);
|
||||
}
|
||||
mDepth = depth;
|
||||
mExpectedPolicies = expectedPolicies;
|
||||
mParent = parent;
|
||||
mPolicyQualifiers = policyQualifiers;
|
||||
mValidPolicy = validPolicy;
|
||||
mCritical = critical;
|
||||
}
|
||||
|
||||
public virtual void AddChild(PkixPolicyNode child)
|
||||
{
|
||||
child.Parent = this;
|
||||
mChildren.Add(child);
|
||||
}
|
||||
|
||||
public virtual void RemoveChild(PkixPolicyNode child)
|
||||
{
|
||||
mChildren.Remove(child);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString("");
|
||||
}
|
||||
|
||||
public virtual string ToString(string indent)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append(indent);
|
||||
stringBuilder.Append(mValidPolicy);
|
||||
stringBuilder.Append(" {");
|
||||
stringBuilder.Append(Platform.NewLine);
|
||||
foreach (PkixPolicyNode mChild in mChildren)
|
||||
{
|
||||
stringBuilder.Append(mChild.ToString(indent + " "));
|
||||
}
|
||||
stringBuilder.Append(indent);
|
||||
stringBuilder.Append("}");
|
||||
stringBuilder.Append(Platform.NewLine);
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
return Copy();
|
||||
}
|
||||
|
||||
public virtual PkixPolicyNode Copy()
|
||||
{
|
||||
PkixPolicyNode pkixPolicyNode = new PkixPolicyNode(Platform.CreateArrayList(), mDepth, new HashSet(mExpectedPolicies), null, new HashSet(mPolicyQualifiers), mValidPolicy, mCritical);
|
||||
foreach (PkixPolicyNode mChild in mChildren)
|
||||
{
|
||||
PkixPolicyNode pkixPolicyNode3 = mChild.Copy();
|
||||
pkixPolicyNode3.Parent = pkixPolicyNode;
|
||||
pkixPolicyNode.AddChild(pkixPolicyNode3);
|
||||
}
|
||||
return pkixPolicyNode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
internal class ReasonsMask
|
||||
{
|
||||
private int _reasons;
|
||||
|
||||
internal static readonly ReasonsMask AllReasons = new ReasonsMask(33023);
|
||||
|
||||
internal bool IsAllReasons => _reasons == AllReasons._reasons;
|
||||
|
||||
public ReasonFlags Reasons => new ReasonFlags(_reasons);
|
||||
|
||||
internal ReasonsMask(int reasons)
|
||||
{
|
||||
_reasons = reasons;
|
||||
}
|
||||
|
||||
internal ReasonsMask()
|
||||
: this(0)
|
||||
{
|
||||
}
|
||||
|
||||
internal void AddReasons(ReasonsMask mask)
|
||||
{
|
||||
_reasons |= mask.Reasons.IntValue;
|
||||
}
|
||||
|
||||
internal ReasonsMask Intersect(ReasonsMask mask)
|
||||
{
|
||||
ReasonsMask reasonsMask = new ReasonsMask();
|
||||
reasonsMask.AddReasons(new ReasonsMask(_reasons & mask.Reasons.IntValue));
|
||||
return reasonsMask;
|
||||
}
|
||||
|
||||
internal bool HasNewReasons(ReasonsMask mask)
|
||||
{
|
||||
return (_reasons | (mask.Reasons.IntValue ^ _reasons)) != 0;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,358 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
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.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
internal class Rfc3281CertPathUtilities
|
||||
{
|
||||
internal static void ProcessAttrCert7(IX509AttributeCertificate attrCert, PkixCertPath certPath, PkixCertPath holderCertPath, PkixParameters pkixParams)
|
||||
{
|
||||
ISet criticalExtensionOids = attrCert.GetCriticalExtensionOids();
|
||||
if (criticalExtensionOids.Contains(X509Extensions.TargetInformation.Id))
|
||||
{
|
||||
try
|
||||
{
|
||||
TargetInformation.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(attrCert, X509Extensions.TargetInformation));
|
||||
}
|
||||
catch (Exception cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Target information extension could not be read.", cause);
|
||||
}
|
||||
}
|
||||
criticalExtensionOids.Remove(X509Extensions.TargetInformation.Id);
|
||||
foreach (PkixAttrCertChecker attrCertChecker in pkixParams.GetAttrCertCheckers())
|
||||
{
|
||||
attrCertChecker.Check(attrCert, certPath, holderCertPath, criticalExtensionOids);
|
||||
}
|
||||
if (!criticalExtensionOids.IsEmpty)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Attribute certificate contains unsupported critical extensions: " + criticalExtensionOids);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CheckCrls(IX509AttributeCertificate attrCert, PkixParameters paramsPKIX, X509Certificate issuerCert, DateTime validDate, IList certPathCerts)
|
||||
{
|
||||
if (!paramsPKIX.IsRevocationEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) == null)
|
||||
{
|
||||
CrlDistPoint crlDistPoint = null;
|
||||
try
|
||||
{
|
||||
crlDistPoint = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(attrCert, X509Extensions.CrlDistributionPoints));
|
||||
}
|
||||
catch (Exception cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("CRL distribution point extension could not be read.", cause);
|
||||
}
|
||||
try
|
||||
{
|
||||
PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crlDistPoint, paramsPKIX);
|
||||
}
|
||||
catch (Exception cause2)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("No additional CRL locations could be decoded from CRL distribution point extension.", cause2);
|
||||
}
|
||||
CertStatus certStatus = new CertStatus();
|
||||
ReasonsMask reasonsMask = new ReasonsMask();
|
||||
Exception cause3 = null;
|
||||
bool flag = false;
|
||||
if (crlDistPoint != null)
|
||||
{
|
||||
DistributionPoint[] array = null;
|
||||
try
|
||||
{
|
||||
array = crlDistPoint.GetDistributionPoints();
|
||||
}
|
||||
catch (Exception cause4)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Distribution points could not be read.", cause4);
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
if (certStatus.Status != 11)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (reasonsMask.IsAllReasons)
|
||||
{
|
||||
break;
|
||||
}
|
||||
PkixParameters paramsPKIX2 = (PkixParameters)paramsPKIX.Clone();
|
||||
CheckCrl(array[i], attrCert, paramsPKIX2, validDate, issuerCert, certStatus, reasonsMask, certPathCerts);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
catch (Exception innerException)
|
||||
{
|
||||
cause3 = new Exception("No valid CRL for distribution point found.", innerException);
|
||||
}
|
||||
}
|
||||
if (certStatus.Status == 11 && !reasonsMask.IsAllReasons)
|
||||
{
|
||||
try
|
||||
{
|
||||
Asn1Object asn1Object = null;
|
||||
try
|
||||
{
|
||||
asn1Object = new Asn1InputStream(attrCert.Issuer.GetPrincipals()[0].GetEncoded()).ReadObject();
|
||||
}
|
||||
catch (Exception innerException2)
|
||||
{
|
||||
throw new Exception("Issuer from certificate for CRL could not be reencoded.", innerException2);
|
||||
}
|
||||
DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(new GeneralName(4, asn1Object))), null, null);
|
||||
PkixParameters paramsPKIX3 = (PkixParameters)paramsPKIX.Clone();
|
||||
CheckCrl(dp, attrCert, paramsPKIX3, validDate, issuerCert, certStatus, reasonsMask, certPathCerts);
|
||||
flag = true;
|
||||
}
|
||||
catch (Exception innerException3)
|
||||
{
|
||||
cause3 = new Exception("No valid CRL for distribution point found.", innerException3);
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("No valid CRL found.", cause3);
|
||||
}
|
||||
if (certStatus.Status != 11)
|
||||
{
|
||||
string text = certStatus.RevocationDate.Value.ToString("ddd MMM dd HH:mm:ss K yyyy");
|
||||
string text2 = "Attribute certificate revocation after " + text;
|
||||
text2 = text2 + ", reason: " + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status];
|
||||
throw new PkixCertPathValidatorException(text2);
|
||||
}
|
||||
if (!reasonsMask.IsAllReasons && certStatus.Status == 11)
|
||||
{
|
||||
certStatus.Status = 12;
|
||||
}
|
||||
if (certStatus.Status == 12)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Attribute certificate status could not be determined.");
|
||||
}
|
||||
}
|
||||
else 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.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void AdditionalChecks(IX509AttributeCertificate 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(IX509AttributeCertificate attrCert, PkixParameters pkixParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
attrCert.CheckValidity(PkixCertPathValidatorUtilities.GetValidDate(pkixParams));
|
||||
}
|
||||
catch (CertificateExpiredException cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Attribute certificate is not valid.", cause);
|
||||
}
|
||||
catch (CertificateNotYetValidException cause2)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Attribute certificate is not valid.", cause2);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ProcessAttrCert4(X509Certificate acIssuerCert, PkixParameters pkixParams)
|
||||
{
|
||||
ISet trustedACIssuers = pkixParams.GetTrustedACIssuers();
|
||||
bool flag = false;
|
||||
foreach (TrustAnchor item in trustedACIssuers)
|
||||
{
|
||||
IDictionary rFC2253Symbols = X509Name.RFC2253Symbols;
|
||||
if (acIssuerCert.SubjectDN.ToString(reverse: false, rFC2253Symbols).Equals(item.CAName) || acIssuerCert.Equals(item.TrustedCert))
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
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 cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Certification path for issuer certificate of attribute certificate could not be validated.", cause);
|
||||
}
|
||||
}
|
||||
|
||||
internal static PkixCertPath ProcessAttrCert1(IX509AttributeCertificate attrCert, PkixParameters pkixParams)
|
||||
{
|
||||
PkixCertPathBuilderResult pkixCertPathBuilderResult = null;
|
||||
ISet set = new HashSet();
|
||||
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];
|
||||
set.AddAll(PkixCertPathValidatorUtilities.FindCertificates(x509CertStoreSelector, pkixParams.GetStores()));
|
||||
}
|
||||
catch (Exception cause)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Public key certificate for attribute certificate cannot be searched.", cause);
|
||||
}
|
||||
}
|
||||
if (set.IsEmpty)
|
||||
{
|
||||
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];
|
||||
set.AddAll(PkixCertPathValidatorUtilities.FindCertificates(x509CertStoreSelector2, pkixParams.GetStores()));
|
||||
}
|
||||
catch (Exception cause2)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Public key certificate for attribute certificate cannot be searched.", cause2);
|
||||
}
|
||||
}
|
||||
if (set.IsEmpty)
|
||||
{
|
||||
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 set)
|
||||
{
|
||||
X509CertStoreSelector x509CertStoreSelector3 = new X509CertStoreSelector();
|
||||
x509CertStoreSelector3.Certificate = item;
|
||||
instance.SetTargetConstraints(x509CertStoreSelector3);
|
||||
PkixCertPathBuilder pkixCertPathBuilder = new PkixCertPathBuilder();
|
||||
try
|
||||
{
|
||||
pkixCertPathBuilderResult = pkixCertPathBuilder.Build(PkixBuilderParameters.GetInstance(instance));
|
||||
}
|
||||
catch (PkixCertPathBuilderException cause3)
|
||||
{
|
||||
ex = new PkixCertPathValidatorException("Certification path for public key certificate of attribute certificate could not be build.", cause3);
|
||||
}
|
||||
}
|
||||
if (ex != null)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
return pkixCertPathBuilderResult.CertPath;
|
||||
}
|
||||
|
||||
private static void CheckCrl(DistributionPoint dp, IX509AttributeCertificate attrCert, PkixParameters paramsPKIX, DateTime validDate, X509Certificate issuerCert, CertStatus certStatus, ReasonsMask reasonMask, IList certPathCerts)
|
||||
{
|
||||
if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DateTime utcNow = DateTime.UtcNow;
|
||||
if (validDate.CompareTo((object?)utcNow) > 0)
|
||||
{
|
||||
throw new Exception("Validation time is in future.");
|
||||
}
|
||||
ISet completeCrls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, utcNow, paramsPKIX);
|
||||
bool flag = false;
|
||||
Exception ex = null;
|
||||
IEnumerator enumerator = completeCrls.GetEnumerator();
|
||||
while (enumerator.MoveNext() && certStatus.Status == 11 && !reasonMask.IsAllReasons)
|
||||
{
|
||||
try
|
||||
{
|
||||
X509Crl x509Crl = (X509Crl)enumerator.Current;
|
||||
ReasonsMask reasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(x509Crl, dp);
|
||||
if (reasonsMask.HasNewReasons(reasonMask))
|
||||
{
|
||||
ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(x509Crl, attrCert, null, null, paramsPKIX, certPathCerts);
|
||||
AsymmetricKeyParameter key = Rfc3280CertPathUtilities.ProcessCrlG(x509Crl, keys);
|
||||
X509Crl x509Crl2 = null;
|
||||
if (paramsPKIX.IsUseDeltasEnabled)
|
||||
{
|
||||
ISet deltaCrls = PkixCertPathValidatorUtilities.GetDeltaCrls(utcNow, paramsPKIX, x509Crl);
|
||||
x509Crl2 = Rfc3280CertPathUtilities.ProcessCrlH(deltaCrls, key);
|
||||
}
|
||||
if (paramsPKIX.ValidityModel != 1 && attrCert.NotAfter.CompareTo((object?)x509Crl.ThisUpdate) < 0)
|
||||
{
|
||||
throw new Exception("No valid CRL for current time found.");
|
||||
}
|
||||
Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, x509Crl);
|
||||
Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, x509Crl);
|
||||
Rfc3280CertPathUtilities.ProcessCrlC(x509Crl2, x509Crl, paramsPKIX);
|
||||
Rfc3280CertPathUtilities.ProcessCrlI(validDate, x509Crl2, attrCert, certStatus, paramsPKIX);
|
||||
Rfc3280CertPathUtilities.ProcessCrlJ(validDate, x509Crl, attrCert, certStatus);
|
||||
if (certStatus.Status == 8)
|
||||
{
|
||||
certStatus.Status = 11;
|
||||
}
|
||||
reasonMask.AddReasons(reasonsMask);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
ex = ex2;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509;
|
||||
|
||||
namespace Org.BouncyCastle.Pkix;
|
||||
|
||||
public class TrustAnchor
|
||||
{
|
||||
private readonly AsymmetricKeyParameter pubKey;
|
||||
|
||||
private readonly string caName;
|
||||
|
||||
private readonly X509Name caPrincipal;
|
||||
|
||||
private readonly X509Certificate trustedCert;
|
||||
|
||||
private byte[] ncBytes;
|
||||
|
||||
private NameConstraints nc;
|
||||
|
||||
public X509Certificate TrustedCert => trustedCert;
|
||||
|
||||
public X509Name CA => caPrincipal;
|
||||
|
||||
public string CAName => caName;
|
||||
|
||||
public AsymmetricKeyParameter CAPublicKey => pubKey;
|
||||
|
||||
public byte[] GetNameConstraints => Arrays.Clone(ncBytes);
|
||||
|
||||
public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
|
||||
{
|
||||
if (trustedCert == null)
|
||||
{
|
||||
throw new ArgumentNullException("trustedCert");
|
||||
}
|
||||
this.trustedCert = trustedCert;
|
||||
pubKey = null;
|
||||
caName = null;
|
||||
caPrincipal = null;
|
||||
setNameConstraints(nameConstraints);
|
||||
}
|
||||
|
||||
public TrustAnchor(X509Name caPrincipal, AsymmetricKeyParameter pubKey, byte[] nameConstraints)
|
||||
{
|
||||
if (caPrincipal == null)
|
||||
{
|
||||
throw new ArgumentNullException("caPrincipal");
|
||||
}
|
||||
if (pubKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("pubKey");
|
||||
}
|
||||
trustedCert = null;
|
||||
this.caPrincipal = caPrincipal;
|
||||
caName = caPrincipal.ToString();
|
||||
this.pubKey = pubKey;
|
||||
setNameConstraints(nameConstraints);
|
||||
}
|
||||
|
||||
public TrustAnchor(string caName, AsymmetricKeyParameter pubKey, byte[] nameConstraints)
|
||||
{
|
||||
if (caName == null)
|
||||
{
|
||||
throw new ArgumentNullException("caName");
|
||||
}
|
||||
if (pubKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("pubKey");
|
||||
}
|
||||
if (caName.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("caName can not be an empty string");
|
||||
}
|
||||
caPrincipal = new X509Name(caName);
|
||||
this.pubKey = pubKey;
|
||||
this.caName = caName;
|
||||
trustedCert = null;
|
||||
setNameConstraints(nameConstraints);
|
||||
}
|
||||
|
||||
private void setNameConstraints(byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
ncBytes = null;
|
||||
nc = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ncBytes = (byte[])bytes.Clone();
|
||||
nc = NameConstraints.GetInstance(Asn1Object.FromByteArray(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string newLine = Platform.NewLine;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append("[");
|
||||
stringBuilder.Append(newLine);
|
||||
if (pubKey != null)
|
||||
{
|
||||
stringBuilder.Append(" Trusted CA Public Key: ").Append(pubKey).Append(newLine);
|
||||
stringBuilder.Append(" Trusted CA Issuer Name: ").Append(caName).Append(newLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(" Trusted CA cert: ").Append(TrustedCert).Append(newLine);
|
||||
}
|
||||
if (nc != null)
|
||||
{
|
||||
stringBuilder.Append(" Name Constraints: ").Append(nc).Append(newLine);
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user