mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-12-31 11:08:09 +00:00
提交Unity 联机Pro
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
public class CertStatus
|
||||
{
|
||||
public const int Unrevoked = 11;
|
||||
|
||||
public const int Undetermined = 12;
|
||||
|
||||
private int status = Unrevoked;
|
||||
|
||||
DateTime? revocationDate = null;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the revocationDate.
|
||||
/// </summary>
|
||||
public DateTime? RevocationDate
|
||||
{
|
||||
get { return revocationDate; }
|
||||
set { this.revocationDate = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the certStatus.
|
||||
/// </summary>
|
||||
public int Status
|
||||
{
|
||||
get { return status; }
|
||||
set { this.status = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12be79f326e3a844f80690ca3213a20a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,61 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
public abstract class PkixAttrCertChecker
|
||||
{
|
||||
/**
|
||||
* Returns an immutable <code>Set</code> of X.509 attribute certificate
|
||||
* extensions that this <code>PkixAttrCertChecker</code> supports or
|
||||
* <code>null</code> if no extensions are supported.
|
||||
* <p>
|
||||
* Each element of the set is a <code>String</code> representing the
|
||||
* Object Identifier (OID) of the X.509 extension that is supported.
|
||||
* </p>
|
||||
* <p>
|
||||
* All X.509 attribute certificate extensions that a
|
||||
* <code>PkixAttrCertChecker</code> might possibly be able to process
|
||||
* should be included in the set.
|
||||
* </p>
|
||||
*
|
||||
* @return an immutable <code>Set</code> of X.509 extension OIDs (in
|
||||
* <code>String</code> format) supported by this
|
||||
* <code>PkixAttrCertChecker</code>, or <code>null</code> if no
|
||||
* extensions are supported
|
||||
*/
|
||||
public abstract ISet<DerObjectIdentifier> GetSupportedExtensions();
|
||||
|
||||
/**
|
||||
* Performs checks on the specified attribute certificate. Every handled
|
||||
* extension is rmeoved from the <code>unresolvedCritExts</code>
|
||||
* collection.
|
||||
*
|
||||
* @param attrCert The attribute certificate to be checked.
|
||||
* @param certPath The certificate path which belongs to the attribute
|
||||
* certificate issuer public key certificate.
|
||||
* @param holderCertPath The certificate path which belongs to the holder
|
||||
* certificate.
|
||||
* @param unresolvedCritExts a <code>Collection</code> of OID strings
|
||||
* representing the current set of unresolved critical extensions
|
||||
* @throws CertPathValidatorException if the specified attribute certificate
|
||||
* does not pass the check.
|
||||
*/
|
||||
public abstract void Check(X509V2AttributeCertificate attrCert, PkixCertPath certPath,
|
||||
PkixCertPath holderCertPath, ICollection<string> unresolvedCritExts);
|
||||
|
||||
/**
|
||||
* Returns a clone of this object.
|
||||
*
|
||||
* @return a copy of this <code>PkixAttrCertChecker</code>
|
||||
*/
|
||||
public abstract PkixAttrCertChecker Clone();
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55a8146ee5b463942b785a1ef6c9b129
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,228 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
public class PkixAttrCertPathBuilder
|
||||
{
|
||||
/**
|
||||
* Build and validate a CertPath using the given parameter.
|
||||
*
|
||||
* @param params PKIXBuilderParameters object containing all information to
|
||||
* build the CertPath
|
||||
*/
|
||||
public virtual PkixCertPathBuilderResult Build(PkixBuilderParameters pkixParams)
|
||||
{
|
||||
// search target certificates
|
||||
|
||||
if (!(pkixParams.GetTargetConstraintsAttrCert() is X509AttrCertStoreSelector attrCertSelector))
|
||||
{
|
||||
throw new PkixCertPathBuilderException(
|
||||
"TargetConstraints must be an instance of "
|
||||
+ typeof(X509AttrCertStoreSelector).FullName
|
||||
+ " for "
|
||||
+ typeof(PkixAttrCertPathBuilder).FullName + " class.");
|
||||
}
|
||||
|
||||
HashSet<X509V2AttributeCertificate> targets;
|
||||
try
|
||||
{
|
||||
targets = FindAttributeCertificates(attrCertSelector, pkixParams.GetStoresAttrCert());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathBuilderException("Error finding target attribute certificate.", e);
|
||||
}
|
||||
|
||||
if (targets.Count == 0)
|
||||
throw new PkixCertPathBuilderException("No attribute certificate found matching targetConstraints.");
|
||||
|
||||
PkixCertPathBuilderResult result = null;
|
||||
|
||||
// check all potential target certificates
|
||||
foreach (var target in targets)
|
||||
{
|
||||
X509CertStoreSelector certSelector = new X509CertStoreSelector();
|
||||
X509Name[] principals = target.Issuer.GetPrincipals();
|
||||
var issuers = new HashSet<X509Certificate>();
|
||||
for (int i = 0; i < principals.Length; i++)
|
||||
{
|
||||
// TODO Replace loop with a single multiprincipal selector (or don't even use selector)
|
||||
try
|
||||
{
|
||||
certSelector.Subject = principals[i];
|
||||
|
||||
CollectionUtilities.CollectMatches(issuers, certSelector, pkixParams.GetStoresCert());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathBuilderException(
|
||||
"Public key certificate for attribute certificate cannot be searched.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
if (issuers.Count < 1)
|
||||
throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found.");
|
||||
|
||||
var certPathList = new List<X509Certificate>();
|
||||
|
||||
foreach (X509Certificate issuer in issuers)
|
||||
{
|
||||
result = Build(target, issuer, pkixParams, certPathList);
|
||||
|
||||
if (result != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == null && certPathException != null)
|
||||
throw new PkixCertPathBuilderException("Possible certificate chain could not be validated.",
|
||||
certPathException);
|
||||
|
||||
if (result == null && certPathException == null)
|
||||
throw new PkixCertPathBuilderException("Unable to find certificate chain.");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Exception certPathException;
|
||||
|
||||
private PkixCertPathBuilderResult Build(
|
||||
X509V2AttributeCertificate attrCert,
|
||||
X509Certificate tbvCert,
|
||||
PkixBuilderParameters pkixParams,
|
||||
IList<X509Certificate> tbvPath)
|
||||
{
|
||||
// If tbvCert is readily present in tbvPath, it indicates having run
|
||||
// into a cycle in the
|
||||
// PKI graph.
|
||||
if (tbvPath.Contains(tbvCert))
|
||||
return null;
|
||||
|
||||
// step out, the certificate is not allowed to appear in a certification
|
||||
// chain
|
||||
if (pkixParams.GetExcludedCerts().Contains(tbvCert))
|
||||
return null;
|
||||
|
||||
// test if certificate path exceeds maximum length
|
||||
if (pkixParams.MaxPathLength != -1)
|
||||
{
|
||||
if (tbvPath.Count - 1 > pkixParams.MaxPathLength)
|
||||
return null;
|
||||
}
|
||||
|
||||
tbvPath.Add(tbvCert);
|
||||
|
||||
PkixCertPathBuilderResult builderResult = null;
|
||||
|
||||
// X509CertificateParser certParser = new X509CertificateParser();
|
||||
PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator();
|
||||
|
||||
try
|
||||
{
|
||||
// check whether the issuer of <tbvCert> is a TrustAnchor
|
||||
if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
|
||||
{
|
||||
PkixCertPath certPath = new PkixCertPath(tbvPath);
|
||||
PkixCertPathValidatorResult result;
|
||||
|
||||
try
|
||||
{
|
||||
result = validator.Validate(certPath, pkixParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Certification path could not be validated.", e);
|
||||
}
|
||||
|
||||
return new PkixCertPathBuilderResult(certPath, result.TrustAnchor,
|
||||
result.PolicyTree, result.SubjectPublicKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add additional X.509 stores from locations in certificate
|
||||
try
|
||||
{
|
||||
PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams);
|
||||
}
|
||||
catch (CertificateParsingException e)
|
||||
{
|
||||
throw new Exception("No additional X.509 stores can be added from certificate locations.", e);
|
||||
}
|
||||
|
||||
// try to get the issuer certificate from one of the stores
|
||||
ISet<X509Certificate> issuers;
|
||||
try
|
||||
{
|
||||
issuers = PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
|
||||
}
|
||||
|
||||
if (issuers.Count < 1)
|
||||
throw new Exception("No issuer certificate for certificate in certification path found.");
|
||||
|
||||
foreach (X509Certificate issuer in issuers)
|
||||
{
|
||||
// if untrusted self signed certificate continue
|
||||
if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer))
|
||||
continue;
|
||||
|
||||
builderResult = Build(attrCert, issuer, pkixParams, tbvPath);
|
||||
|
||||
if (builderResult != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
certPathException = new Exception("No valid certification path could be build.", e);
|
||||
}
|
||||
|
||||
if (builderResult == null)
|
||||
{
|
||||
tbvPath.Remove(tbvCert);
|
||||
}
|
||||
|
||||
return builderResult;
|
||||
}
|
||||
|
||||
internal static HashSet<X509V2AttributeCertificate> FindAttributeCertificates(
|
||||
ISelector<X509V2AttributeCertificate> attrCertSelector,
|
||||
IList<IStore<X509V2AttributeCertificate>> attrCertStores)
|
||||
{
|
||||
var attrCerts = new HashSet<X509V2AttributeCertificate>();
|
||||
|
||||
foreach (var attrCertStore in attrCertStores)
|
||||
{
|
||||
try
|
||||
{
|
||||
attrCerts.UnionWith(attrCertStore.EnumerateMatches(attrCertSelector));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Problem while picking certificates from X.509 store.", e);
|
||||
}
|
||||
}
|
||||
|
||||
return attrCerts;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecee7bdcfcd47514897052237429c5fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/**
|
||||
* CertPathValidatorSpi implementation for X.509 Attribute Certificates la RFC 3281.
|
||||
*
|
||||
* @see org.bouncycastle.x509.ExtendedPkixParameters
|
||||
*/
|
||||
public class PkixAttrCertPathValidator
|
||||
// extends CertPathValidatorSpi
|
||||
{
|
||||
/**
|
||||
* Validates an attribute certificate with the given certificate path.
|
||||
*
|
||||
* <p>
|
||||
* <code>params</code> must be an instance of
|
||||
* <code>ExtendedPkixParameters</code>.
|
||||
* </p><p>
|
||||
* The target constraints in the <code>params</code> must be an
|
||||
* <code>X509AttrCertStoreSelector</code> with at least the attribute
|
||||
* certificate criterion set. Obey that also target informations may be
|
||||
* necessary to correctly validate this attribute certificate.
|
||||
* </p><p>
|
||||
* The attribute certificate issuer must be added to the trusted attribute
|
||||
* issuers with {@link ExtendedPkixParameters#setTrustedACIssuers(Set)}.
|
||||
* </p>
|
||||
* @param certPath The certificate path which belongs to the attribute
|
||||
* certificate issuer public key certificate.
|
||||
* @param params The PKIX parameters.
|
||||
* @return A <code>PKIXCertPathValidatorResult</code> of the result of
|
||||
* validating the <code>certPath</code>.
|
||||
* @throws InvalidAlgorithmParameterException if <code>params</code> is
|
||||
* inappropriate for this validator.
|
||||
* @throws CertPathValidatorException if the verification fails.
|
||||
*/
|
||||
public virtual PkixCertPathValidatorResult Validate(PkixCertPath certPath, PkixParameters pkixParams)
|
||||
{
|
||||
if (!(pkixParams.GetTargetConstraintsAttrCert() is X509AttrCertStoreSelector attrCertSelector))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName,
|
||||
nameof(pkixParams));
|
||||
}
|
||||
|
||||
var attrCert = attrCertSelector.AttributeCert;
|
||||
PkixCertPath holderCertPath = Rfc3281CertPathUtilities.ProcessAttrCert1(attrCert, pkixParams);
|
||||
PkixCertPathValidatorResult result = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams);
|
||||
X509Certificate issuerCert = (X509Certificate)certPath.Certificates[0];
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert3(issuerCert, pkixParams);
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert4(issuerCert, pkixParams);
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert5(attrCert, pkixParams);
|
||||
// 6 already done in X509AttrCertStoreSelector
|
||||
Rfc3281CertPathUtilities.ProcessAttrCert7(attrCert, certPath, holderCertPath, pkixParams);
|
||||
Rfc3281CertPathUtilities.AdditionalChecks(attrCert, pkixParams);
|
||||
DateTime date;
|
||||
try
|
||||
{
|
||||
date = PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(pkixParams, null, -1);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Could not get validity date from attribute certificate.", e);
|
||||
}
|
||||
Rfc3281CertPathUtilities.CheckCrls(attrCert, pkixParams, issuerCert, date, certPath.Certificates);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85b76d91e2248a64191df671fb900d8b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,150 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for PkixBuilderParameters.
|
||||
/// </summary>
|
||||
public class PkixBuilderParameters
|
||||
: PkixParameters
|
||||
{
|
||||
private int maxPathLength = 5;
|
||||
|
||||
private ISet<X509Certificate> excludedCerts = new HashSet<X509Certificate>();
|
||||
|
||||
/**
|
||||
* Returns an instance of <code>PkixBuilderParameters</code>.
|
||||
* <p>
|
||||
* This method can be used to get a copy from other
|
||||
* <code>PKIXBuilderParameters</code>, <code>PKIXParameters</code>,
|
||||
* and <code>ExtendedPKIXParameters</code> instances.
|
||||
* </p>
|
||||
*
|
||||
* @param pkixParams The PKIX parameters to create a copy of.
|
||||
* @return An <code>PkixBuilderParameters</code> instance.
|
||||
*/
|
||||
public static PkixBuilderParameters GetInstance(
|
||||
PkixParameters pkixParams)
|
||||
{
|
||||
PkixBuilderParameters parameters = new PkixBuilderParameters(
|
||||
pkixParams.GetTrustAnchors(),
|
||||
pkixParams.GetTargetConstraintsCert(),
|
||||
pkixParams.GetTargetConstraintsAttrCert());
|
||||
parameters.SetParams(pkixParams);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public PkixBuilderParameters(ISet<TrustAnchor> trustAnchors, ISelector<X509Certificate> targetConstraintsCert)
|
||||
: this(trustAnchors, targetConstraintsCert, null)
|
||||
{
|
||||
}
|
||||
|
||||
public PkixBuilderParameters(ISet<TrustAnchor> trustAnchors, ISelector<X509Certificate> targetConstraintsCert,
|
||||
ISelector<X509V2AttributeCertificate> targetConstraintsAttrCert)
|
||||
: base(trustAnchors)
|
||||
{
|
||||
SetTargetConstraintsCert(targetConstraintsCert);
|
||||
SetTargetConstraintsAttrCert(targetConstraintsAttrCert);
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
this.maxPathLength = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Excluded certificates are not used for building a certification path.
|
||||
/// </summary>
|
||||
/// <returns>the excluded certificates.</returns>
|
||||
public virtual ISet<X509Certificate> GetExcludedCerts()
|
||||
{
|
||||
return new HashSet<X509Certificate>(excludedCerts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the excluded certificates which are not used for building a
|
||||
/// certification path. If the <code>ISet</code> is <code>null</code> an
|
||||
/// empty set is assumed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The given set is cloned to protect it against subsequent modifications.
|
||||
/// </remarks>
|
||||
/// <param name="excludedCerts">The excluded certificates to set.</param>
|
||||
public virtual void SetExcludedCerts(ISet<X509Certificate> excludedCerts)
|
||||
{
|
||||
if (excludedCerts == null)
|
||||
{
|
||||
this.excludedCerts = new HashSet<X509Certificate>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.excludedCerts = new HashSet<X509Certificate>(excludedCerts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can alse handle <code>ExtendedPKIXBuilderParameters</code> and
|
||||
* <code>PKIXBuilderParameters</code>.
|
||||
*
|
||||
* @param params Parameters to set.
|
||||
* @see org.bouncycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters)
|
||||
*/
|
||||
protected override void SetParams(PkixParameters parameters)
|
||||
{
|
||||
base.SetParams(parameters);
|
||||
if (parameters is PkixBuilderParameters _params)
|
||||
{
|
||||
maxPathLength = _params.maxPathLength;
|
||||
excludedCerts = new HashSet<X509Certificate>(_params.excludedCerts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of this <code>PKIXParameters</code> object. Changes to the
|
||||
* copy will not affect the original and vice versa.
|
||||
*
|
||||
* @return a copy of this <code>PKIXParameters</code> object
|
||||
*/
|
||||
public override object Clone()
|
||||
{
|
||||
PkixBuilderParameters parameters = new PkixBuilderParameters(
|
||||
GetTrustAnchors(),
|
||||
GetTargetConstraintsCert(),
|
||||
GetTargetConstraintsAttrCert());
|
||||
parameters.SetParams(this);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.AppendLine("PkixBuilderParameters [");
|
||||
s.Append(base.ToString());
|
||||
s.Append(" Maximum Path Length: ");
|
||||
s.Append(MaxPathLength);
|
||||
s.AppendLine();
|
||||
s.AppendLine("]");
|
||||
return s.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4976f361ba4e5544681c44a8ec8d928c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,423 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.OpenSsl;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/**
|
||||
* An immutable sequence of certificates (a certification path).<br />
|
||||
* <br />
|
||||
* This is an abstract class that defines the methods common to all CertPaths.
|
||||
* Subclasses can handle different kinds of certificates (X.509, PGP, etc.).<br />
|
||||
* <br />
|
||||
* All CertPath objects have a type, a list of Certificates, and one or more
|
||||
* supported encodings. Because the CertPath class is immutable, a CertPath
|
||||
* cannot change in any externally visible way after being constructed. This
|
||||
* stipulation applies to all public fields and methods of this class and any
|
||||
* added or overridden by subclasses.<br />
|
||||
* <br />
|
||||
* The type is a string that identifies the type of Certificates in the
|
||||
* certification path. For each certificate cert in a certification path
|
||||
* certPath, cert.getType().equals(certPath.getType()) must be true.<br />
|
||||
* <br />
|
||||
* The list of Certificates is an ordered List of zero or more Certificates.
|
||||
* This List and all of the Certificates contained in it must be immutable.<br />
|
||||
* <br />
|
||||
* Each CertPath object must support one or more encodings so that the object
|
||||
* can be translated into a byte array for storage or transmission to other
|
||||
* parties. Preferably, these encodings should be well-documented standards
|
||||
* (such as PKCS#7). One of the encodings supported by a CertPath is considered
|
||||
* the default encoding. This encoding is used if no encoding is explicitly
|
||||
* requested (for the {@link #getEncoded()} method, for instance).<br />
|
||||
* <br />
|
||||
* All CertPath objects are also Serializable. CertPath objects are resolved
|
||||
* into an alternate {@link CertPathRep} object during serialization. This
|
||||
* allows a CertPath object to be serialized into an equivalent representation
|
||||
* regardless of its underlying implementation.<br />
|
||||
* <br />
|
||||
* CertPath objects can be created with a CertificateFactory or they can be
|
||||
* returned by other classes, such as a CertPathBuilder.<br />
|
||||
* <br />
|
||||
* By convention, X.509 CertPaths (consisting of X509Certificates), are ordered
|
||||
* starting with the target certificate and ending with a certificate issued by
|
||||
* the trust anchor. That is, the issuer of one certificate is the subject of
|
||||
* the following one. The certificate representing the
|
||||
* {@link TrustAnchor TrustAnchor} should not be included in the certification
|
||||
* path. Unvalidated X.509 CertPaths may not follow these conventions. PKIX
|
||||
* CertPathValidators will detect any departure from these conventions that
|
||||
* cause the certification path to be invalid and throw a
|
||||
* CertPathValidatorException.<br />
|
||||
* <br />
|
||||
* <strong>Concurrent Access</strong><br />
|
||||
* <br />
|
||||
* All CertPath objects must be thread-safe. That is, multiple threads may
|
||||
* concurrently invoke the methods defined in this class on a single CertPath
|
||||
* object (or more than one) with no ill effects. This is also true for the List
|
||||
* returned by CertPath.getCertificates.<br />
|
||||
* <br />
|
||||
* Requiring CertPath objects to be immutable and thread-safe allows them to be
|
||||
* passed around to various pieces of code without worrying about coordinating
|
||||
* access. Providing this thread-safety is generally not difficult, since the
|
||||
* CertPath and List objects in question are immutable.
|
||||
*
|
||||
* @see CertificateFactory
|
||||
* @see CertPathBuilder
|
||||
*/
|
||||
/// <summary>
|
||||
/// CertPath implementation for X.509 certificates.
|
||||
/// </summary>
|
||||
public class PkixCertPath
|
||||
// : CertPath
|
||||
{
|
||||
internal static readonly List<string> m_encodings = new List<string>{ "PkiPath", "PEM", "PKCS7" };
|
||||
|
||||
private readonly IList<X509Certificate> m_certificates;
|
||||
|
||||
private static IList<X509Certificate> SortCerts(IList<X509Certificate> certs)
|
||||
{
|
||||
if (certs.Count < 2)
|
||||
return certs;
|
||||
|
||||
X509Name issuer = certs[0].IssuerDN;
|
||||
bool okay = true;
|
||||
|
||||
for (int i = 1; i != certs.Count; i++)
|
||||
{
|
||||
X509Certificate cert = certs[i];
|
||||
|
||||
if (issuer.Equivalent(cert.SubjectDN, true))
|
||||
{
|
||||
issuer = cert.IssuerDN;
|
||||
}
|
||||
else
|
||||
{
|
||||
okay = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (okay)
|
||||
return certs;
|
||||
|
||||
// find end-entity cert
|
||||
var retList = new List<X509Certificate>(certs.Count);
|
||||
var orig = new List<X509Certificate>(certs);
|
||||
|
||||
for (int i = 0; i < certs.Count; i++)
|
||||
{
|
||||
X509Certificate cert = certs[i];
|
||||
bool found = false;
|
||||
|
||||
X509Name subject = cert.SubjectDN;
|
||||
foreach (X509Certificate c in certs)
|
||||
{
|
||||
if (c.IssuerDN.Equivalent(subject, true))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
retList.Add(cert);
|
||||
certs.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
// can only have one end entity cert - something's wrong, give up.
|
||||
if (retList.Count > 1)
|
||||
return orig;
|
||||
|
||||
for (int i = 0; i != retList.Count; i++)
|
||||
{
|
||||
issuer = retList[i].IssuerDN;
|
||||
|
||||
for (int j = 0; j < certs.Count; j++)
|
||||
{
|
||||
X509Certificate c = certs[j];
|
||||
if (issuer.Equivalent(c.SubjectDN, true))
|
||||
{
|
||||
retList.Add(c);
|
||||
certs.RemoveAt(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure all certificates are accounted for.
|
||||
if (certs.Count > 0)
|
||||
return orig;
|
||||
|
||||
return retList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CertPath of the specified type.
|
||||
* This constructor is protected because most users should use
|
||||
* a CertificateFactory to create CertPaths.
|
||||
* @param type the standard name of the type of Certificatesin this path
|
||||
**/
|
||||
public PkixCertPath(IList<X509Certificate> certificates)
|
||||
{
|
||||
m_certificates = SortCerts(new List<X509Certificate>(certificates));
|
||||
}
|
||||
|
||||
public PkixCertPath(Stream inStream)
|
||||
: this(inStream, "PkiPath")
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CertPath of the specified type.
|
||||
* This constructor is protected because most users should use
|
||||
* a CertificateFactory to create CertPaths.
|
||||
*
|
||||
* @param type the standard name of the type of Certificatesin this path
|
||||
**/
|
||||
public PkixCertPath(Stream inStream, string encoding)
|
||||
{
|
||||
//string upper = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(encoding);
|
||||
|
||||
IList<X509Certificate> certs;
|
||||
try
|
||||
{
|
||||
if (Org.BouncyCastle.Utilities.Platform.EqualsIgnoreCase("PkiPath", encoding))
|
||||
{
|
||||
Asn1InputStream derInStream = new Asn1InputStream(inStream);
|
||||
Asn1Object derObject = derInStream.ReadObject();
|
||||
if (!(derObject is Asn1Sequence))
|
||||
{
|
||||
throw new CertificateException(
|
||||
"input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath");
|
||||
}
|
||||
|
||||
certs = new List<X509Certificate>();
|
||||
|
||||
foreach (Asn1Encodable ae in (Asn1Sequence)derObject)
|
||||
{
|
||||
byte[] derBytes = ae.GetEncoded(Asn1Encodable.Der);
|
||||
Stream certInStream = new MemoryStream(derBytes, false);
|
||||
|
||||
// TODO Is inserting at the front important (list will be sorted later anyway)?
|
||||
certs.Insert(0, new X509CertificateParser().ReadCertificate(certInStream));
|
||||
}
|
||||
}
|
||||
else if (Org.BouncyCastle.Utilities.Platform.EqualsIgnoreCase("PEM", encoding) ||
|
||||
Org.BouncyCastle.Utilities.Platform.EqualsIgnoreCase("PKCS7", encoding))
|
||||
{
|
||||
certs = new X509CertificateParser().ReadCertificates(inStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CertificateException("unsupported encoding: " + encoding);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new CertificateException(
|
||||
"IOException throw while decoding CertPath:\n"
|
||||
+ ex.ToString());
|
||||
}
|
||||
|
||||
m_certificates = SortCerts(certs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iteration of the encodings supported by this
|
||||
* certification path, with the default encoding
|
||||
* first. Attempts to modify the returned Iterator via its
|
||||
* remove method result in an UnsupportedOperationException.
|
||||
*
|
||||
* @return an Iterator over the names of the supported encodings (as Strings)
|
||||
**/
|
||||
public virtual IEnumerable<string> Encodings
|
||||
{
|
||||
get { return CollectionUtilities.Proxy(m_encodings); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this certification path for equality with the specified object.
|
||||
* Two CertPaths are equal if and only if their types are equal and their
|
||||
* certificate Lists (and by implication the Certificates in those Lists)
|
||||
* are equal. A CertPath is never equal to an object that is not a CertPath.<br />
|
||||
* <br />
|
||||
* This algorithm is implemented by this method. If it is overridden, the
|
||||
* behavior specified here must be maintained.
|
||||
*
|
||||
* @param other
|
||||
* the object to test for equality with this certification path
|
||||
*
|
||||
* @return true if the specified object is equal to this certification path,
|
||||
* false otherwise
|
||||
*
|
||||
* @see Object#hashCode() Object.hashCode()
|
||||
*/
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj is PkixCertPath that))
|
||||
return false;
|
||||
|
||||
var thisCerts = this.Certificates;
|
||||
var thatCerts = that.Certificates;
|
||||
|
||||
if (thisCerts.Count != thatCerts.Count)
|
||||
return false;
|
||||
|
||||
var e1 = thisCerts.GetEnumerator();
|
||||
var e2 = thatCerts.GetEnumerator();
|
||||
|
||||
while (e1.MoveNext())
|
||||
{
|
||||
e2.MoveNext();
|
||||
|
||||
if (!Equals(e1.Current, e2.Current))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_certificates.GetHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded form of this certification path, using
|
||||
* the default encoding.
|
||||
*
|
||||
* @return the encoded bytes
|
||||
* @exception CertificateEncodingException if an encoding error occurs
|
||||
**/
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
return GetEncoded(m_encodings[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded form of this certification path, using
|
||||
* the specified encoding.
|
||||
*
|
||||
* @param encoding the name of the encoding to use
|
||||
* @return the encoded bytes
|
||||
* @exception CertificateEncodingException if an encoding error
|
||||
* occurs or the encoding requested is not supported
|
||||
*
|
||||
*/
|
||||
public virtual byte[] GetEncoded(string encoding)
|
||||
{
|
||||
if (Org.BouncyCastle.Utilities.Platform.EqualsIgnoreCase(encoding, "PkiPath"))
|
||||
{
|
||||
Asn1EncodableVector v = new Asn1EncodableVector(m_certificates.Count);
|
||||
for (int i = m_certificates.Count - 1; i >= 0; i--)
|
||||
{
|
||||
v.Add(ToAsn1Object(m_certificates[i]));
|
||||
}
|
||||
|
||||
return ToDerEncoded(new DerSequence(v));
|
||||
}
|
||||
else if (Org.BouncyCastle.Utilities.Platform.EqualsIgnoreCase(encoding, "PKCS7"))
|
||||
{
|
||||
ContentInfo encInfo = new ContentInfo(PkcsObjectIdentifiers.Data, null);
|
||||
|
||||
Asn1EncodableVector v = new Asn1EncodableVector(m_certificates.Count);
|
||||
foreach (var cert in m_certificates)
|
||||
{
|
||||
v.Add(ToAsn1Object(cert));
|
||||
}
|
||||
|
||||
SignedData sd = new SignedData(
|
||||
new DerInteger(1),
|
||||
new DerSet(),
|
||||
encInfo,
|
||||
new DerSet(v),
|
||||
null,
|
||||
new DerSet());
|
||||
|
||||
return ToDerEncoded(new ContentInfo(PkcsObjectIdentifiers.SignedData, sd));
|
||||
}
|
||||
else if (Org.BouncyCastle.Utilities.Platform.EqualsIgnoreCase(encoding, "PEM"))
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
|
||||
try
|
||||
{
|
||||
using (var pWrt = new PemWriter(new StreamWriter(bOut)))
|
||||
{
|
||||
foreach (var cert in m_certificates)
|
||||
{
|
||||
pWrt.WriteObject(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new CertificateEncodingException("can't encode certificate for PEM encoded path");
|
||||
}
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CertificateEncodingException("unsupported encoding: " + encoding);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the list of certificates in this certification
|
||||
/// path.
|
||||
/// </summary>
|
||||
public virtual IList<X509Certificate> Certificates
|
||||
{
|
||||
get { return CollectionUtilities.ReadOnly(m_certificates); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a DERObject containing the encoded certificate.
|
||||
*
|
||||
* @param cert the X509Certificate object to be encoded
|
||||
*
|
||||
* @return the DERObject
|
||||
**/
|
||||
private Asn1Object ToAsn1Object(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
return cert.CertificateStructure.ToAsn1Object();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateEncodingException("Exception while encoding certificate", e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ToDerEncoded(Asn1Encodable obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
return obj.GetEncoded(Asn1Encodable.Der);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CertificateEncodingException("Exception thrown", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 565bdea7eb2a46d40ad29b81bc563819
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,173 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/**
|
||||
* Implements the PKIX CertPathBuilding algorithm for BouncyCastle.
|
||||
*
|
||||
* @see CertPathBuilderSpi
|
||||
*/
|
||||
public class PkixCertPathBuilder
|
||||
{
|
||||
/**
|
||||
* Build and validate a CertPath using the given parameter.
|
||||
*
|
||||
* @param params PKIXBuilderParameters object containing all information to
|
||||
* build the CertPath
|
||||
*/
|
||||
public virtual PkixCertPathBuilderResult Build(PkixBuilderParameters pkixParams)
|
||||
{
|
||||
// search target certificates
|
||||
|
||||
var certSelector = pkixParams.GetTargetConstraintsCert();
|
||||
|
||||
var targets = new HashSet<X509Certificate>();
|
||||
try
|
||||
{
|
||||
CollectionUtilities.CollectMatches(targets, certSelector, pkixParams.GetStoresCert());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathBuilderException(
|
||||
"Error finding target certificate.", e);
|
||||
}
|
||||
|
||||
if (targets.Count < 1)
|
||||
throw new PkixCertPathBuilderException("No certificate found matching targetConstraints.");
|
||||
|
||||
PkixCertPathBuilderResult result = null;
|
||||
var certPathList = new List<X509Certificate>();
|
||||
|
||||
// check all potential target certificates
|
||||
foreach (X509Certificate cert in targets)
|
||||
{
|
||||
result = Build(cert, pkixParams, certPathList);
|
||||
|
||||
if (result != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == null && certPathException != null)
|
||||
throw new PkixCertPathBuilderException(certPathException.Message, certPathException.InnerException);
|
||||
|
||||
if (result == null && certPathException == null)
|
||||
throw new PkixCertPathBuilderException("Unable to find certificate chain.");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Exception certPathException;
|
||||
|
||||
protected virtual PkixCertPathBuilderResult Build(
|
||||
X509Certificate tbvCert,
|
||||
PkixBuilderParameters pkixParams,
|
||||
IList<X509Certificate> tbvPath)
|
||||
{
|
||||
// If tbvCert is already present in tbvPath, it indicates having run into a cycle in the PKI graph.
|
||||
if (tbvPath.Contains(tbvCert))
|
||||
return null;
|
||||
|
||||
// step out, the certificate is not allowed to appear in a certification chain.
|
||||
if (pkixParams.GetExcludedCerts().Contains(tbvCert))
|
||||
return null;
|
||||
|
||||
// test if certificate path exceeds maximum length
|
||||
if (pkixParams.MaxPathLength != -1)
|
||||
{
|
||||
if (tbvPath.Count - 1 > pkixParams.MaxPathLength)
|
||||
return null;
|
||||
}
|
||||
|
||||
tbvPath.Add(tbvCert);
|
||||
|
||||
PkixCertPathBuilderResult builderResult = null;
|
||||
PkixCertPathValidator validator = new PkixCertPathValidator();
|
||||
|
||||
try
|
||||
{
|
||||
// check whether the issuer of <tbvCert> is a TrustAnchor
|
||||
if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
|
||||
{
|
||||
// exception message from possibly later tried certification chains
|
||||
PkixCertPath certPath;
|
||||
try
|
||||
{
|
||||
certPath = new PkixCertPath(tbvPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Certification path could not be constructed from certificate list.", e);
|
||||
}
|
||||
|
||||
PkixCertPathValidatorResult result;
|
||||
try
|
||||
{
|
||||
result = validator.Validate(certPath, pkixParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception(
|
||||
"Certification path could not be validated.", e);
|
||||
}
|
||||
|
||||
return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, result.PolicyTree,
|
||||
result.SubjectPublicKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add additional X.509 stores from locations in certificate
|
||||
try
|
||||
{
|
||||
PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams);
|
||||
}
|
||||
catch (CertificateParsingException e)
|
||||
{
|
||||
throw new Exception("No additiontal X.509 stores can be added from certificate locations.", e);
|
||||
}
|
||||
|
||||
// try to get the issuer certificate from one of the stores
|
||||
ISet<X509Certificate> issuers;
|
||||
try
|
||||
{
|
||||
issuers = PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
|
||||
}
|
||||
|
||||
if (issuers.Count < 1)
|
||||
throw new Exception("No issuer certificate for certificate in certification path found.");
|
||||
|
||||
foreach (X509Certificate issuer in issuers)
|
||||
{
|
||||
builderResult = Build(issuer, pkixParams, tbvPath);
|
||||
|
||||
if (builderResult != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
certPathException = e;
|
||||
}
|
||||
|
||||
if (builderResult == null)
|
||||
{
|
||||
tbvPath.Remove(tbvCert);
|
||||
}
|
||||
|
||||
return builderResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b141fdaa90999d4f848152c584ce4e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
[Serializable]
|
||||
public class PkixCertPathBuilderException
|
||||
: GeneralSecurityException
|
||||
{
|
||||
public PkixCertPathBuilderException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathBuilderException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathBuilderException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected PkixCertPathBuilderException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25a59fe00cb35544dbfaae6c24af2f68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for PkixCertPathBuilderResult.
|
||||
/// </summary>
|
||||
public class PkixCertPathBuilderResult
|
||||
: PkixCertPathValidatorResult//, ICertPathBuilderResult
|
||||
{
|
||||
private PkixCertPath 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 PkixCertPath CertPath
|
||||
{
|
||||
get { return certPath; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("SimplePKIXCertPathBuilderResult: [");
|
||||
sb.Append(" Certification Path: ").Append(CertPath).AppendLine();
|
||||
sb.Append(" Trust Anchor: ").Append(TrustAnchor.TrustedCert.IssuerDN).AppendLine();
|
||||
sb.Append(" Subject Public Key: ").Append(SubjectPublicKey).AppendLine();
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bb663b8ed6b4c04ead1d50f1b83b3f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,104 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
public abstract class PkixCertPathChecker
|
||||
{
|
||||
protected PkixCertPathChecker()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the internal state of this <code>PKIXCertPathChecker</code>.
|
||||
* <p>
|
||||
* The <code>forward</code> flag specifies the order that certificates
|
||||
* will be passed to the {@link #check check} method (forward or reverse). A
|
||||
* <code>PKIXCertPathChecker</code> <b>must</b> support reverse checking
|
||||
* and <b>may</b> support forward checking.
|
||||
* </p>
|
||||
*
|
||||
* @param forward
|
||||
* the order that certificates are presented to the
|
||||
* <code>check</code> method. If <code>true</code>,
|
||||
* certificates are presented from target to most-trusted CA
|
||||
* (forward); if <code>false</code>, from most-trusted CA to
|
||||
* target (reverse).
|
||||
* @exception CertPathValidatorException
|
||||
* if this <code>PKIXCertPathChecker</code> is unable to
|
||||
* check certificates in the specified order; it should never
|
||||
* be thrown if the forward flag is false since reverse
|
||||
* checking must be supported
|
||||
*/
|
||||
public abstract void Init(bool forward);
|
||||
//throws CertPathValidatorException;
|
||||
|
||||
/**
|
||||
* Indicates if forward checking is supported. Forward checking refers to
|
||||
* the ability of the <code>PKIXCertPathChecker</code> to perform its
|
||||
* checks when certificates are presented to the <code>check</code> method
|
||||
* in the forward direction (from target to most-trusted CA).
|
||||
*
|
||||
* @return <code>true</code> if forward checking is supported,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public abstract bool IsForwardCheckingSupported();
|
||||
|
||||
/**
|
||||
* Returns an immutable <code>Set</code> of X.509 certificate extensions
|
||||
* that this <code>PKIXCertPathChecker</code> supports (i.e. recognizes,
|
||||
* is able to process), or <code>null</code> if no extensions are
|
||||
* supported.
|
||||
* <p>
|
||||
* Each element of the set is a <code>String</code> representing the
|
||||
* Object Identifier (OID) of the X.509 extension that is supported. The OID
|
||||
* is represented by a set of nonnegative integers separated by periods.
|
||||
* </p><p>
|
||||
* All X.509 certificate extensions that a <code>PKIXCertPathChecker</code>
|
||||
* might possibly be able to process should be included in the set.
|
||||
* </p>
|
||||
*
|
||||
* @return an immutable <code>Set</code> of X.509 extension OIDs (in
|
||||
* <code>String</code> format) supported by this
|
||||
* <code>PKIXCertPathChecker</code>, or <code>null</code> if no
|
||||
* extensions are supported
|
||||
*/
|
||||
public abstract ISet<string> GetSupportedExtensions();
|
||||
|
||||
/**
|
||||
* Performs the check(s) on the specified certificate using its internal
|
||||
* state and removes any critical extensions that it processes from the
|
||||
* specified collection of OID strings that represent the unresolved
|
||||
* critical extensions. The certificates are presented in the order
|
||||
* specified by the <code>init</code> method.
|
||||
*
|
||||
* @param cert
|
||||
* the <code>Certificate</code> to be checked
|
||||
* @param unresolvedCritExts
|
||||
* a <code>Collection</code> of OID strings representing the
|
||||
* current set of unresolved critical extensions
|
||||
* @exception CertPathValidatorException
|
||||
* if the specified certificate does not pass the check
|
||||
*/
|
||||
public abstract void Check(X509Certificate cert, ISet<string> unresolvedCritExts);
|
||||
//throws CertPathValidatorException;
|
||||
|
||||
/**
|
||||
* Returns a clone of this object. Calls the <code>Object.clone()</code>
|
||||
* method. All subclasses which maintain state must support and override
|
||||
* this method, if necessary.
|
||||
*
|
||||
* @return a copy of this <code>PKIXCertPathChecker</code>
|
||||
*/
|
||||
public virtual object Clone()
|
||||
{
|
||||
// TODO Check this
|
||||
return base.MemberwiseClone();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43f01d4bd4f27a943bb693735147c260
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,442 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/**
|
||||
* The <i>Service Provider Interface</i> (<b>SPI</b>)
|
||||
* for the {@link CertPathValidator CertPathValidator} class. All
|
||||
* <code>CertPathValidator</code> implementations must include a class (the
|
||||
* SPI class) that extends this class (<code>CertPathValidatorSpi</code>)
|
||||
* and implements all of its methods. In general, instances of this class
|
||||
* should only be accessed through the <code>CertPathValidator</code> class.
|
||||
* For details, see the Java Cryptography Architecture.<br />
|
||||
* <br />
|
||||
* <b>Concurrent Access</b><br />
|
||||
* <br />
|
||||
* Instances of this class need not be protected against concurrent
|
||||
* access from multiple threads. Threads that need to access a single
|
||||
* <code>CertPathValidatorSpi</code> instance concurrently should synchronize
|
||||
* amongst themselves and provide the necessary locking before calling the
|
||||
* wrapping <code>CertPathValidator</code> object.<br />
|
||||
* <br />
|
||||
* However, implementations of <code>CertPathValidatorSpi</code> may still
|
||||
* encounter concurrency issues, since multiple threads each
|
||||
* manipulating a different <code>CertPathValidatorSpi</code> instance need not
|
||||
* synchronize.
|
||||
*/
|
||||
/// <summary>
|
||||
/// CertPathValidatorSpi implementation for X.509 Certificate validation a la RFC
|
||||
/// 3280.
|
||||
/// </summary>
|
||||
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.",
|
||||
nameof(paramsPkix));
|
||||
}
|
||||
|
||||
//
|
||||
// 6.1.1 - inputs
|
||||
//
|
||||
|
||||
//
|
||||
// (a)
|
||||
//
|
||||
var certs = certPath.Certificates;
|
||||
int n = certs.Count;
|
||||
|
||||
if (n == 0)
|
||||
throw new PkixCertPathValidatorException("Certification path is empty.", null, 0);
|
||||
|
||||
//
|
||||
// (b)
|
||||
//
|
||||
// DateTime validDate = PkixCertPathValidatorUtilities.GetValidDate(paramsPkix);
|
||||
|
||||
//
|
||||
// (c)
|
||||
//
|
||||
var userInitialPolicySet = paramsPkix.GetInitialPolicies();
|
||||
|
||||
//
|
||||
// (d)
|
||||
//
|
||||
TrustAnchor trust;
|
||||
try
|
||||
{
|
||||
trust = PkixCertPathValidatorUtilities.FindTrustAnchor(certs[certs.Count - 1],
|
||||
paramsPkix.GetTrustAnchors());
|
||||
|
||||
if (trust == null)
|
||||
throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, -1);
|
||||
|
||||
CheckCertificate(trust.TrustedCert);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(e.Message, e.InnerException, certs.Count - 1);
|
||||
}
|
||||
|
||||
//
|
||||
// (e), (f), (g) are part of the paramsPkix object.
|
||||
//
|
||||
int index = 0;
|
||||
int i;
|
||||
// Certificate for each interation of the validation loop
|
||||
// Signature information for each iteration of the validation loop
|
||||
//
|
||||
// 6.1.2 - setup
|
||||
//
|
||||
|
||||
//
|
||||
// (a)
|
||||
//
|
||||
var policyNodes = new List<PkixPolicyNode>[n + 1];
|
||||
for (int j = 0; j < policyNodes.Length; j++)
|
||||
{
|
||||
policyNodes[j] = new List<PkixPolicyNode>();
|
||||
}
|
||||
|
||||
var policySet = new HashSet<string>();
|
||||
|
||||
policySet.Add(Rfc3280CertPathUtilities.ANY_POLICY);
|
||||
|
||||
var validPolicyTree = new PkixPolicyNode(new List<PkixPolicyNode>(), 0, policySet, null,
|
||||
new HashSet<PolicyQualifierInfo>(), Rfc3280CertPathUtilities.ANY_POLICY, false);
|
||||
|
||||
policyNodes[0].Add(validPolicyTree);
|
||||
|
||||
//
|
||||
// (b) and (c)
|
||||
//
|
||||
PkixNameConstraintValidator nameConstraintValidator = new PkixNameConstraintValidator();
|
||||
|
||||
// (d)
|
||||
//
|
||||
int explicitPolicy;
|
||||
var acceptablePolicies = new HashSet<string>();
|
||||
|
||||
if (paramsPkix.IsExplicitPolicyRequired)
|
||||
{
|
||||
explicitPolicy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
explicitPolicy = n + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// (e)
|
||||
//
|
||||
int inhibitAnyPolicy;
|
||||
|
||||
if (paramsPkix.IsAnyPolicyInhibited)
|
||||
{
|
||||
inhibitAnyPolicy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
inhibitAnyPolicy = n + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// (f)
|
||||
//
|
||||
int policyMapping;
|
||||
|
||||
if (paramsPkix.IsPolicyMappingInhibited)
|
||||
{
|
||||
policyMapping = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
policyMapping = n + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// (g), (h), (i), (j)
|
||||
//
|
||||
AsymmetricKeyParameter workingPublicKey;
|
||||
X509Name workingIssuerName;
|
||||
|
||||
X509Certificate sign = trust.TrustedCert;
|
||||
try
|
||||
{
|
||||
if (sign != null)
|
||||
{
|
||||
workingIssuerName = sign.SubjectDN;
|
||||
workingPublicKey = sign.GetPublicKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
workingIssuerName = new X509Name(trust.CAName);
|
||||
workingPublicKey = trust.CAPublicKey;
|
||||
}
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, -1);
|
||||
}
|
||||
|
||||
AlgorithmIdentifier workingAlgId = null;
|
||||
try
|
||||
{
|
||||
workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey);
|
||||
}
|
||||
catch (PkixCertPathValidatorException e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Algorithm identifier of public key of trust anchor could not be read.", e, -1);
|
||||
}
|
||||
|
||||
// DerObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.Algorithm;
|
||||
// Asn1Encodable workingPublicKeyParameters = workingAlgId.Parameters;
|
||||
|
||||
//
|
||||
// (k)
|
||||
//
|
||||
int maxPathLength = n;
|
||||
|
||||
//
|
||||
// 6.1.3
|
||||
//
|
||||
|
||||
var targetConstraints = paramsPkix.GetTargetConstraintsCert();
|
||||
if (targetConstraints != null && !targetConstraints.Match((X509Certificate)certs[0]))
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Target certificate in certification path does not match targetConstraints.", null, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// initialize CertPathChecker's
|
||||
//
|
||||
var certPathCheckers = paramsPkix.GetCertPathCheckers();
|
||||
foreach (PkixCertPathChecker certPathChecker in certPathCheckers)
|
||||
{
|
||||
certPathChecker.Init(false);
|
||||
}
|
||||
|
||||
X509Certificate cert = null;
|
||||
|
||||
for (index = certs.Count - 1; index >= 0; index--)
|
||||
{
|
||||
// try
|
||||
// {
|
||||
//
|
||||
// i as defined in the algorithm description
|
||||
//
|
||||
i = n - index;
|
||||
|
||||
//
|
||||
// set certificate to be checked in this round
|
||||
// sign and workingPublicKey and workingIssuerName are set
|
||||
// at the end of the for loop and initialized the
|
||||
// first time from the TrustAnchor
|
||||
//
|
||||
cert = (X509Certificate)certs[index];
|
||||
|
||||
try
|
||||
{
|
||||
CheckCertificate(cert);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(e.Message, e.InnerException, index);
|
||||
}
|
||||
|
||||
//
|
||||
// 6.1.3
|
||||
//
|
||||
|
||||
Rfc3280CertPathUtilities.ProcessCertA(certPath, paramsPkix, index, workingPublicKey,
|
||||
workingIssuerName, sign);
|
||||
|
||||
Rfc3280CertPathUtilities.ProcessCertBC(certPath, index, nameConstraintValidator);
|
||||
|
||||
validPolicyTree = Rfc3280CertPathUtilities.ProcessCertD(certPath, index,
|
||||
acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy);
|
||||
|
||||
validPolicyTree = Rfc3280CertPathUtilities.ProcessCertE(certPath, index, validPolicyTree);
|
||||
|
||||
Rfc3280CertPathUtilities.ProcessCertF(certPath, index, validPolicyTree, explicitPolicy);
|
||||
|
||||
//
|
||||
// 6.1.4
|
||||
//
|
||||
|
||||
if (i != n)
|
||||
{
|
||||
if (cert != null && cert.Version == 1)
|
||||
{
|
||||
// we've found the trust anchor at the top of the path, ignore and keep going
|
||||
if ((i == 1) && cert.Equals(trust.TrustedCert))
|
||||
continue;
|
||||
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Version 1 certificates can't be used as CA ones.", null, index);
|
||||
}
|
||||
|
||||
Rfc3280CertPathUtilities.PrepareNextCertA(certPath, index);
|
||||
|
||||
validPolicyTree = Rfc3280CertPathUtilities.PrepareCertB(certPath, index, policyNodes,
|
||||
validPolicyTree, policyMapping);
|
||||
|
||||
Rfc3280CertPathUtilities.PrepareNextCertG(certPath, index, nameConstraintValidator);
|
||||
|
||||
// (h)
|
||||
explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertH1(certPath, index, explicitPolicy);
|
||||
policyMapping = Rfc3280CertPathUtilities.PrepareNextCertH2(certPath, index, policyMapping);
|
||||
inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertH3(certPath, index, inhibitAnyPolicy);
|
||||
|
||||
//
|
||||
// (i)
|
||||
//
|
||||
explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertI1(certPath, index, explicitPolicy);
|
||||
policyMapping = Rfc3280CertPathUtilities.PrepareNextCertI2(certPath, index, policyMapping);
|
||||
|
||||
// (j)
|
||||
inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertJ(certPath, index, inhibitAnyPolicy);
|
||||
|
||||
// (k)
|
||||
Rfc3280CertPathUtilities.PrepareNextCertK(certPath, index);
|
||||
|
||||
// (l)
|
||||
maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertL(certPath, index, maxPathLength);
|
||||
|
||||
// (m)
|
||||
maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertM(certPath, index, maxPathLength);
|
||||
|
||||
// (n)
|
||||
Rfc3280CertPathUtilities.PrepareNextCertN(certPath, index);
|
||||
|
||||
var criticalExtensions1 = cert.GetCriticalExtensionOids();
|
||||
|
||||
if (criticalExtensions1 != null)
|
||||
{
|
||||
criticalExtensions1 = new HashSet<string>(criticalExtensions1);
|
||||
|
||||
// these extensions are handled by the algorithm
|
||||
criticalExtensions1.Remove(X509Extensions.KeyUsage.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.CertificatePolicies.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.PolicyMappings.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.InhibitAnyPolicy.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.IssuingDistributionPoint.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.DeltaCrlIndicator.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.PolicyConstraints.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.BasicConstraints.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.SubjectAlternativeName.Id);
|
||||
criticalExtensions1.Remove(X509Extensions.NameConstraints.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
criticalExtensions1 = new HashSet<string>();
|
||||
}
|
||||
|
||||
// (o)
|
||||
Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, certPathCheckers);
|
||||
|
||||
// set signing certificate for next round
|
||||
sign = cert;
|
||||
|
||||
// (c)
|
||||
workingIssuerName = sign.SubjectDN;
|
||||
|
||||
// (d)
|
||||
try
|
||||
{
|
||||
workingPublicKey = PkixCertPathValidatorUtilities.GetNextWorkingKey(certPath.Certificates, index);
|
||||
}
|
||||
catch (PkixCertPathValidatorException e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, index);
|
||||
}
|
||||
|
||||
workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey);
|
||||
// (f)
|
||||
// workingPublicKeyAlgorithm = workingAlgId.Algorithm;
|
||||
// (e)
|
||||
// workingPublicKeyParameters = workingAlgId.Parameters;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 6.1.5 Wrap-up procedure
|
||||
//
|
||||
|
||||
explicitPolicy = Rfc3280CertPathUtilities.WrapupCertA(explicitPolicy, cert);
|
||||
|
||||
explicitPolicy = Rfc3280CertPathUtilities.WrapupCertB(certPath, index + 1, explicitPolicy);
|
||||
|
||||
//
|
||||
// (c) (d) and (e) are already done
|
||||
//
|
||||
|
||||
//
|
||||
// (f)
|
||||
//
|
||||
var criticalExtensions = cert.GetCriticalExtensionOids();
|
||||
|
||||
if (criticalExtensions != null)
|
||||
{
|
||||
criticalExtensions = new HashSet<string>(criticalExtensions);
|
||||
|
||||
// Requires .Id
|
||||
// these extensions are handled by the algorithm
|
||||
criticalExtensions.Remove(X509Extensions.KeyUsage.Id);
|
||||
criticalExtensions.Remove(X509Extensions.CertificatePolicies.Id);
|
||||
criticalExtensions.Remove(X509Extensions.PolicyMappings.Id);
|
||||
criticalExtensions.Remove(X509Extensions.InhibitAnyPolicy.Id);
|
||||
criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id);
|
||||
criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id);
|
||||
criticalExtensions.Remove(X509Extensions.PolicyConstraints.Id);
|
||||
criticalExtensions.Remove(X509Extensions.BasicConstraints.Id);
|
||||
criticalExtensions.Remove(X509Extensions.SubjectAlternativeName.Id);
|
||||
criticalExtensions.Remove(X509Extensions.NameConstraints.Id);
|
||||
criticalExtensions.Remove(X509Extensions.CrlDistributionPoints.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
criticalExtensions = new HashSet<string>();
|
||||
}
|
||||
|
||||
Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, certPathCheckers, criticalExtensions);
|
||||
|
||||
PkixPolicyNode intersection = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix,
|
||||
userInitialPolicySet, index + 1, policyNodes, validPolicyTree, acceptablePolicies);
|
||||
|
||||
if ((explicitPolicy > 0) || (intersection != null))
|
||||
{
|
||||
return new PkixCertPathValidatorResult(trust, intersection, cert.GetPublicKey());
|
||||
}
|
||||
|
||||
throw new PkixCertPathValidatorException("Path processing failed on policy.", null, index);
|
||||
}
|
||||
|
||||
internal static void CheckCertificate(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
TbsCertificateStructure.GetInstance(cert.CertificateStructure.TbsCertificate);
|
||||
}
|
||||
catch (CertificateEncodingException e)
|
||||
{
|
||||
throw new Exception("unable to process TBSCertificate", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1230039d20abc264894f233518e57548
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/**
|
||||
* An exception indicating one of a variety of problems encountered when
|
||||
* validating a certification path. <br />
|
||||
* <br />
|
||||
* A <code>CertPathValidatorException</code> provides support for wrapping
|
||||
* exceptions. The {@link #getCause getCause} method returns the throwable,
|
||||
* if any, that caused this exception to be thrown. <br />
|
||||
* <br />
|
||||
* A <code>CertPathValidatorException</code> may also include the
|
||||
* certification path that was being validated when the exception was thrown
|
||||
* and the index of the certificate in the certification path that caused the
|
||||
* exception to be thrown. Use the {@link #getCertPath getCertPath} and
|
||||
* {@link #getIndex getIndex} methods to retrieve this information.<br />
|
||||
* <br />
|
||||
* <b>Concurrent Access</b><br />
|
||||
* <br />
|
||||
* Unless otherwise specified, the methods defined in this class are not
|
||||
* thread-safe. Multiple threads that need to access a single
|
||||
* object concurrently should synchronize amongst themselves and
|
||||
* provide the necessary locking. Multiple threads each manipulating
|
||||
* separate objects need not synchronize.
|
||||
*
|
||||
* @see CertPathValidator
|
||||
**/
|
||||
[Serializable]
|
||||
public class PkixCertPathValidatorException
|
||||
: GeneralSecurityException
|
||||
{
|
||||
protected readonly int m_index = -1;
|
||||
|
||||
public PkixCertPathValidatorException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathValidatorException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkixCertPathValidatorException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <code>PkixCertPathValidatorException</code> with the specified
|
||||
/// detail message, cause, certification path, and index.
|
||||
/// </summary>
|
||||
/// <param name="message">the detail message (or <code>null</code> if none)</param>
|
||||
/// <param name="innerException">the cause (or <code>null</code> if none)</param>
|
||||
/// <param name="index">the index of the certificate in the certification path that</param> *
|
||||
public PkixCertPathValidatorException(string message, Exception innerException, int index)
|
||||
: base(message, innerException)
|
||||
{
|
||||
if (index < -1)
|
||||
throw new ArgumentException("cannot be < -1", nameof(index));
|
||||
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
protected PkixCertPathValidatorException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
m_index = info.GetInt32("index");
|
||||
}
|
||||
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("index", m_index);
|
||||
}
|
||||
|
||||
/// <summary> eturns the index of the certificate in the certification path that caused the exception to be
|
||||
/// thrown.</summary>
|
||||
/// <remarks>
|
||||
/// Note that the list of certificates in a <see cref="PkixCertPath"/> is zero based. If no index has been set,
|
||||
/// -1 is returned.
|
||||
/// </remarks>
|
||||
/// <returns>The index that has been set, or -1 if none has been set.</returns>
|
||||
public int Index
|
||||
{
|
||||
get { return m_index; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db2fbbf90588ea041ab1bf5b62f86bea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for PkixCertPathValidatorResult.
|
||||
/// </summary>
|
||||
public class PkixCertPathValidatorResult
|
||||
//: ICertPathValidatorResult
|
||||
{
|
||||
private TrustAnchor trustAnchor;
|
||||
private PkixPolicyNode policyTree;
|
||||
private AsymmetricKeyParameter subjectPublicKey;
|
||||
|
||||
public PkixPolicyNode PolicyTree
|
||||
{
|
||||
get { return this.policyTree; }
|
||||
}
|
||||
|
||||
public TrustAnchor TrustAnchor
|
||||
{
|
||||
get { return this.trustAnchor; }
|
||||
}
|
||||
|
||||
public AsymmetricKeyParameter SubjectPublicKey
|
||||
{
|
||||
get { return this.subjectPublicKey; }
|
||||
}
|
||||
|
||||
public PkixCertPathValidatorResult(TrustAnchor trustAnchor, PkixPolicyNode policyTree,
|
||||
AsymmetricKeyParameter subjectPublicKey)
|
||||
{
|
||||
if (trustAnchor == null)
|
||||
throw new ArgumentNullException(nameof(trustAnchor));
|
||||
if (subjectPublicKey == null)
|
||||
throw new ArgumentNullException(nameof(subjectPublicKey));
|
||||
|
||||
this.trustAnchor = trustAnchor;
|
||||
this.policyTree = policyTree;
|
||||
this.subjectPublicKey = subjectPublicKey;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new PkixCertPathValidatorResult(this.TrustAnchor, this.PolicyTree, this.SubjectPublicKey);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("PKIXCertPathValidatorResult: [");
|
||||
sb.Append(" Trust Anchor: ").Append(TrustAnchor).AppendLine();
|
||||
sb.Append(" Policy Tree: ").Append(PolicyTree).AppendLine();
|
||||
sb.Append(" Subject Public Key: ").Append(SubjectPublicKey).AppendLine();
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0872050d12dad44abb76c1745b5f870
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7825ba3fb6db65f428b313e1641e481b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,109 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
public class PkixCrlUtilities
|
||||
{
|
||||
public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix,
|
||||
DateTime currentDate)
|
||||
{
|
||||
HashSet<X509Crl> initialSet;
|
||||
|
||||
// get complete CRL(s)
|
||||
try
|
||||
{
|
||||
initialSet = FindCrls(crlSelector, paramsPkix.GetStoresCrl());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Exception obtaining complete CRLs.", e);
|
||||
}
|
||||
|
||||
var finalSet = new HashSet<X509Crl>();
|
||||
DateTime validityDate = currentDate;
|
||||
|
||||
if (paramsPkix.Date != null)
|
||||
{
|
||||
validityDate = paramsPkix.Date.Value;
|
||||
}
|
||||
|
||||
// based on RFC 5280 6.3.3
|
||||
foreach (X509Crl crl in initialSet)
|
||||
{
|
||||
DateTime? nextUpdate = crl.NextUpdate;
|
||||
|
||||
if (null == nextUpdate || nextUpdate.Value.CompareTo(validityDate) > 0)
|
||||
{
|
||||
X509Certificate cert = crlSelector.CertificateChecking;
|
||||
|
||||
if (null == cert || crl.ThisUpdate.CompareTo(cert.NotAfter) < 0)
|
||||
{
|
||||
finalSet.Add(crl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return finalSet;
|
||||
}
|
||||
|
||||
public virtual ISet<X509Crl> FindCrls(X509CrlStoreSelector crlSelector, PkixParameters paramsPkix)
|
||||
{
|
||||
// get complete CRL(s)
|
||||
try
|
||||
{
|
||||
return FindCrls(crlSelector, paramsPkix.GetStoresCrl());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Exception obtaining complete CRLs.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// crl checking
|
||||
/// Return a Collection of all CRLs found in the X509Store's that are
|
||||
/// matching the crlSelect criteriums.
|
||||
/// </summary>
|
||||
/// <param name="crlSelector">a {@link X509CRLStoreSelector} object that will be used
|
||||
/// to select the CRLs</param>
|
||||
/// <param name="crlStores">a List containing only {@link org.bouncycastle.x509.X509Store
|
||||
/// X509Store} objects. These are used to search for CRLs</param>
|
||||
/// <returns>a Collection of all found {@link X509CRL X509CRL} objects. May be
|
||||
/// empty but never <code>null</code>.
|
||||
/// </returns>
|
||||
private HashSet<X509Crl> FindCrls(ISelector<X509Crl> crlSelector, IList<IStore<X509Crl>> crlStores)
|
||||
{
|
||||
var crls = new HashSet<X509Crl>();
|
||||
|
||||
Exception lastException = null;
|
||||
bool foundValidStore = false;
|
||||
|
||||
foreach (var crlStore in crlStores)
|
||||
{
|
||||
try
|
||||
{
|
||||
crls.UnionWith(crlStore.EnumerateMatches(crlSelector));
|
||||
foundValidStore = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
lastException = new Exception("Exception searching in X.509 CRL store.", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundValidStore && lastException != null)
|
||||
throw lastException;
|
||||
|
||||
return crls;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7931f13e3f4ffef48a585b19606b249f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f526512b4e00a18408980528de75bc05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
[Serializable]
|
||||
public class PkixNameConstraintValidatorException
|
||||
: Exception
|
||||
{
|
||||
public PkixNameConstraintValidatorException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public PkixNameConstraintValidatorException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PkixNameConstraintValidatorException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected PkixNameConstraintValidatorException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7731ec37d612ebe4998773dbfb370c49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,794 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for PkixParameters.
|
||||
/// </summary>
|
||||
public class PkixParameters
|
||||
{
|
||||
/**
|
||||
* This is the default PKIX validity model. Actually there are two variants
|
||||
* of this: The PKIX model and the modified PKIX model. The PKIX model
|
||||
* verifies that all involved certificates must have been valid at the
|
||||
* current time. The modified PKIX model verifies that all involved
|
||||
* certificates were valid at the signing time. Both are indirectly choosen
|
||||
* with the {@link PKIXParameters#setDate(java.util.Date)} method, so this
|
||||
* methods sets the Date when <em>all</em> certificates must have been
|
||||
* valid.
|
||||
*/
|
||||
public const int PkixValidityModel = 0;
|
||||
|
||||
/**
|
||||
* This model uses the following validity model. Each certificate must have
|
||||
* been valid at the moment where is was used. That means the end
|
||||
* certificate must have been valid at the time the signature was done. The
|
||||
* CA certificate which signed the end certificate must have been valid,
|
||||
* when the end certificate was signed. The CA (or Root CA) certificate must
|
||||
* have been valid, when the CA certificate was signed and so on. So the
|
||||
* {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when
|
||||
* the <em>end certificate</em> must have been valid. <p/> It is used e.g.
|
||||
* in the German signature law.
|
||||
*/
|
||||
public const int ChainValidityModel = 1;
|
||||
|
||||
private HashSet<TrustAnchor> trustAnchors;
|
||||
private DateTime? date;
|
||||
private List<PkixCertPathChecker> m_checkers;
|
||||
private bool revocationEnabled = true;
|
||||
private HashSet<string> initialPolicies;
|
||||
//private bool checkOnlyEECertificateCrl = false;
|
||||
private bool explicitPolicyRequired = false;
|
||||
private bool anyPolicyInhibited = false;
|
||||
private bool policyMappingInhibited = false;
|
||||
private bool policyQualifiersRejected = true;
|
||||
|
||||
private List<IStore<X509V2AttributeCertificate>> m_storesAttrCert;
|
||||
private List<IStore<X509Certificate>> m_storesCert;
|
||||
private List<IStore<X509Crl>> m_storesCrl;
|
||||
|
||||
private ISelector<X509V2AttributeCertificate> m_targetConstraintsAttrCert;
|
||||
private ISelector<X509Certificate> m_targetConstraintsCert;
|
||||
|
||||
private bool additionalLocationsEnabled;
|
||||
private ISet<TrustAnchor> trustedACIssuers;
|
||||
private ISet<string> necessaryACAttributes;
|
||||
private ISet<string> prohibitedACAttributes;
|
||||
private ISet<PkixAttrCertChecker> attrCertCheckers;
|
||||
private int validityModel = PkixValidityModel;
|
||||
private bool useDeltas = false;
|
||||
|
||||
/**
|
||||
* Creates an instance of PKIXParameters with the specified Set of
|
||||
* most-trusted CAs. Each element of the set is a TrustAnchor.<br />
|
||||
* <br />
|
||||
* Note that the Set is copied to protect against subsequent modifications.
|
||||
*
|
||||
* @param trustAnchors
|
||||
* a Set of TrustAnchors
|
||||
*
|
||||
* @exception InvalidAlgorithmParameterException
|
||||
* if the specified Set is empty
|
||||
* <code>(trustAnchors.isEmpty() == true)</code>
|
||||
* @exception NullPointerException
|
||||
* if the specified Set is <code>null</code>
|
||||
* @exception ClassCastException
|
||||
* if any of the elements in the Set are not of type
|
||||
* <code>java.security.cert.TrustAnchor</code>
|
||||
*/
|
||||
public PkixParameters(ISet<TrustAnchor> trustAnchors)
|
||||
{
|
||||
SetTrustAnchors(trustAnchors);
|
||||
|
||||
this.initialPolicies = new HashSet<string>();
|
||||
this.m_checkers = new List<PkixCertPathChecker>();
|
||||
this.m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>();
|
||||
this.m_storesCert = new List<IStore<X509Certificate>>();
|
||||
this.m_storesCrl = new List<IStore<X509Crl>>();
|
||||
this.trustedACIssuers = new HashSet<TrustAnchor>();
|
||||
this.necessaryACAttributes = new HashSet<string>();
|
||||
this.prohibitedACAttributes = new HashSet<string>();
|
||||
this.attrCertCheckers = new HashSet<PkixAttrCertChecker>();
|
||||
}
|
||||
|
||||
// // TODO implement for other keystores (see Java build)?
|
||||
// /**
|
||||
// * Creates an instance of <code>PKIXParameters</code> that
|
||||
// * populates the set of most-trusted CAs from the trusted
|
||||
// * certificate entries contained in the specified <code>KeyStore</code>.
|
||||
// * Only keystore entries that contain trusted <code>X509Certificates</code>
|
||||
// * are considered; all other certificate types are ignored.
|
||||
// *
|
||||
// * @param keystore a <code>KeyStore</code> from which the set of
|
||||
// * most-trusted CAs will be populated
|
||||
// * @throws KeyStoreException if the keystore has not been initialized
|
||||
// * @throws InvalidAlgorithmParameterException if the keystore does
|
||||
// * not contain at least one trusted certificate entry
|
||||
// * @throws NullPointerException if the keystore is <code>null</code>
|
||||
// */
|
||||
// public PkixParameters(
|
||||
// Pkcs12Store keystore)
|
||||
//// throws KeyStoreException, InvalidAlgorithmParameterException
|
||||
// {
|
||||
// if (keystore == null)
|
||||
// throw new ArgumentNullException("keystore");
|
||||
// ISet trustAnchors = new HashSet();
|
||||
// foreach (string alias in keystore.Aliases)
|
||||
// {
|
||||
// if (keystore.IsCertificateEntry(alias))
|
||||
// {
|
||||
// X509CertificateEntry x509Entry = keystore.GetCertificate(alias);
|
||||
// trustAnchors.Add(new TrustAnchor(x509Entry.Certificate, null));
|
||||
// }
|
||||
// }
|
||||
// SetTrustAnchors(trustAnchors);
|
||||
//
|
||||
// this.initialPolicies = new HashSet();
|
||||
// this.certPathCheckers = new ArrayList();
|
||||
// this.stores = new ArrayList();
|
||||
// this.additionalStores = new ArrayList();
|
||||
// this.trustedACIssuers = new HashSet();
|
||||
// this.necessaryACAttributes = new HashSet();
|
||||
// this.prohibitedACAttributes = new HashSet();
|
||||
// this.attrCertCheckers = new HashSet();
|
||||
// }
|
||||
|
||||
public virtual bool IsRevocationEnabled
|
||||
{
|
||||
get { return revocationEnabled; }
|
||||
set { revocationEnabled = value; }
|
||||
}
|
||||
|
||||
public virtual bool IsExplicitPolicyRequired
|
||||
{
|
||||
get { return explicitPolicyRequired; }
|
||||
set { this.explicitPolicyRequired = value; }
|
||||
}
|
||||
|
||||
public virtual bool IsAnyPolicyInhibited
|
||||
{
|
||||
get { return anyPolicyInhibited; }
|
||||
set { this.anyPolicyInhibited = value; }
|
||||
}
|
||||
|
||||
public virtual bool IsPolicyMappingInhibited
|
||||
{
|
||||
get { return policyMappingInhibited; }
|
||||
set { this.policyMappingInhibited = value; }
|
||||
}
|
||||
|
||||
public virtual bool IsPolicyQualifiersRejected
|
||||
{
|
||||
get { return policyQualifiersRejected; }
|
||||
set { this.policyQualifiersRejected = value; }
|
||||
}
|
||||
|
||||
//public bool IsCheckOnlyEECertificateCrl
|
||||
//{
|
||||
// get { return this.checkOnlyEECertificateCrl; }
|
||||
// set { this.checkOnlyEECertificateCrl = value; }
|
||||
//}
|
||||
|
||||
public virtual DateTime? Date
|
||||
{
|
||||
get { return this.date; }
|
||||
set { this.date = value; }
|
||||
}
|
||||
|
||||
// Returns a Set of the most-trusted CAs.
|
||||
public virtual ISet<TrustAnchor> GetTrustAnchors()
|
||||
{
|
||||
return new HashSet<TrustAnchor>(this.trustAnchors);
|
||||
}
|
||||
|
||||
// Sets the set of most-trusted CAs.
|
||||
// Set is copied to protect against subsequent modifications.
|
||||
public virtual void SetTrustAnchors(ISet<TrustAnchor> tas)
|
||||
{
|
||||
if (tas == null)
|
||||
throw new ArgumentNullException("value");
|
||||
if (tas.Count < 1)
|
||||
throw new ArgumentException("non-empty set required", "value");
|
||||
|
||||
// Explicit copy to enforce type-safety
|
||||
this.trustAnchors = new HashSet<TrustAnchor>();
|
||||
foreach (TrustAnchor ta in tas)
|
||||
{
|
||||
if (ta != null)
|
||||
{
|
||||
trustAnchors.Add(ta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the required constraints on the target certificate or attribute
|
||||
* certificate. The constraints are returned as an instance of
|
||||
* <code>IX509Selector</code>. If <code>null</code>, no constraints are
|
||||
* defined.
|
||||
*
|
||||
* <p>
|
||||
* The target certificate in a PKIX path may be a certificate or an
|
||||
* attribute certificate.
|
||||
* </p><p>
|
||||
* Note that the <code>IX509Selector</code> returned is cloned to protect
|
||||
* against subsequent modifications.
|
||||
* </p>
|
||||
* @return a <code>IX509Selector</code> specifying the constraints on the
|
||||
* target certificate or attribute certificate (or <code>null</code>)
|
||||
* @see #setTargetConstraints
|
||||
* @see X509CertStoreSelector
|
||||
* @see X509AttributeCertStoreSelector
|
||||
*/
|
||||
public virtual ISelector<X509V2AttributeCertificate> GetTargetConstraintsAttrCert()
|
||||
{
|
||||
return (ISelector<X509V2AttributeCertificate>)m_targetConstraintsAttrCert?.Clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the required constraints on the target certificate or attribute
|
||||
* certificate. The constraints are specified as an instance of
|
||||
* <code>IX509Selector</code>. If <code>null</code>, no constraints are
|
||||
* defined.
|
||||
* <p>
|
||||
* The target certificate in a PKIX path may be a certificate or an
|
||||
* attribute certificate.
|
||||
* </p><p>
|
||||
* Note that the <code>IX509Selector</code> specified is cloned to protect
|
||||
* against subsequent modifications.
|
||||
* </p>
|
||||
*
|
||||
* @param selector a <code>IX509Selector</code> specifying the constraints on
|
||||
* the target certificate or attribute certificate (or
|
||||
* <code>null</code>)
|
||||
* @see #getTargetConstraints
|
||||
* @see X509CertStoreSelector
|
||||
* @see X509AttributeCertStoreSelector
|
||||
*/
|
||||
public virtual void SetTargetConstraintsAttrCert(ISelector<X509V2AttributeCertificate> targetConstraintsAttrCert)
|
||||
{
|
||||
this.m_targetConstraintsAttrCert = (ISelector<X509V2AttributeCertificate>)targetConstraintsAttrCert?.Clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the required constraints on the target certificate. The
|
||||
* constraints are returned as an instance of CertSelector. If
|
||||
* <code>null</code>, no constraints are defined.<br />
|
||||
* <br />
|
||||
* Note that the CertSelector returned is cloned to protect against
|
||||
* subsequent modifications.
|
||||
*
|
||||
* @return a CertSelector specifying the constraints on the target
|
||||
* certificate (or <code>null</code>)
|
||||
*
|
||||
* @see #setTargetCertConstraints(CertSelector)
|
||||
*/
|
||||
public virtual ISelector<X509Certificate> GetTargetConstraintsCert()
|
||||
{
|
||||
return (ISelector<X509Certificate>)m_targetConstraintsCert?.Clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the required constraints on the target certificate. The constraints
|
||||
* are specified as an instance of CertSelector. If null, no constraints are
|
||||
* defined.<br />
|
||||
* <br />
|
||||
* Note that the CertSelector specified is cloned to protect against
|
||||
* subsequent modifications.
|
||||
*
|
||||
* @param selector
|
||||
* a CertSelector specifying the constraints on the target
|
||||
* certificate (or <code>null</code>)
|
||||
*
|
||||
* @see #getTargetCertConstraints()
|
||||
*/
|
||||
public virtual void SetTargetConstraintsCert(ISelector<X509Certificate> targetConstraintsCert)
|
||||
{
|
||||
m_targetConstraintsCert = (ISelector<X509Certificate>)targetConstraintsCert?.Clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable Set of initial policy identifiers (OID strings),
|
||||
* indicating that any one of these policies would be acceptable to the
|
||||
* certificate user for the purposes of certification path processing. The
|
||||
* default return value is an empty <code>Set</code>, which is
|
||||
* interpreted as meaning that any policy would be acceptable.
|
||||
*
|
||||
* @return an immutable <code>Set</code> of initial policy OIDs in String
|
||||
* format, or an empty <code>Set</code> (implying any policy is
|
||||
* acceptable). Never returns <code>null</code>.
|
||||
*
|
||||
* @see #setInitialPolicies(java.util.Set)
|
||||
*/
|
||||
public virtual ISet<string> GetInitialPolicies()
|
||||
{
|
||||
// TODO Can it really be null?
|
||||
if (initialPolicies == null)
|
||||
return new HashSet<string>();
|
||||
|
||||
return new HashSet<string>(initialPolicies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Set</code> of initial policy identifiers (OID strings),
|
||||
* indicating that any one of these policies would be acceptable to the
|
||||
* certificate user for the purposes of certification path processing. By
|
||||
* default, any policy is acceptable (i.e. all policies), so a user that
|
||||
* wants to allow any policy as acceptable does not need to call this
|
||||
* method, or can call it with an empty <code>Set</code> (or
|
||||
* <code>null</code>).<br />
|
||||
* <br />
|
||||
* Note that the Set is copied to protect against subsequent modifications.<br />
|
||||
* <br />
|
||||
*
|
||||
* @param initialPolicies
|
||||
* a Set of initial policy OIDs in String format (or
|
||||
* <code>null</code>)
|
||||
*
|
||||
* @exception ClassCastException
|
||||
* if any of the elements in the set are not of type String
|
||||
*
|
||||
* @see #getInitialPolicies()
|
||||
*/
|
||||
public virtual void SetInitialPolicies(ISet<string> initialPolicies)
|
||||
{
|
||||
this.initialPolicies = new HashSet<string>();
|
||||
if (initialPolicies != null)
|
||||
{
|
||||
foreach (string obj in initialPolicies)
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
this.initialPolicies.Add(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a <code>List</code> of additional certification path checkers. If
|
||||
* the specified List contains an object that is not a PKIXCertPathChecker,
|
||||
* it is ignored.<br />
|
||||
* <br />
|
||||
* Each <code>PKIXCertPathChecker</code> specified implements additional
|
||||
* checks on a certificate. Typically, these are checks to process and
|
||||
* verify private extensions contained in certificates. Each
|
||||
* <code>PKIXCertPathChecker</code> should be instantiated with any
|
||||
* initialization parameters needed to execute the check.<br />
|
||||
* <br />
|
||||
* This method allows sophisticated applications to extend a PKIX
|
||||
* <code>CertPathValidator</code> or <code>CertPathBuilder</code>. Each
|
||||
* of the specified PKIXCertPathCheckers will be called, in turn, by a PKIX
|
||||
* <code>CertPathValidator</code> or <code>CertPathBuilder</code> for
|
||||
* each certificate processed or validated.<br />
|
||||
* <br />
|
||||
* Regardless of whether these additional PKIXCertPathCheckers are set, a
|
||||
* PKIX <code>CertPathValidator</code> or <code>CertPathBuilder</code>
|
||||
* must perform all of the required PKIX checks on each certificate. The one
|
||||
* exception to this rule is if the RevocationEnabled flag is set to false
|
||||
* (see the {@link #setRevocationEnabled(boolean) setRevocationEnabled}
|
||||
* method).<br />
|
||||
* <br />
|
||||
* Note that the List supplied here is copied and each PKIXCertPathChecker
|
||||
* in the list is cloned to protect against subsequent modifications.
|
||||
*
|
||||
* @param checkers
|
||||
* a List of PKIXCertPathCheckers. May be null, in which case no
|
||||
* additional checkers will be used.
|
||||
* @exception ClassCastException
|
||||
* if any of the elements in the list are not of type
|
||||
* <code>java.security.cert.PKIXCertPathChecker</code>
|
||||
* @see #getCertPathCheckers()
|
||||
*/
|
||||
public virtual void SetCertPathCheckers(IList<PkixCertPathChecker> checkers)
|
||||
{
|
||||
m_checkers = new List<PkixCertPathChecker>();
|
||||
|
||||
if (checkers != null)
|
||||
{
|
||||
foreach (var checker in checkers)
|
||||
{
|
||||
m_checkers.Add((PkixCertPathChecker)checker.Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the List of certification path checkers. Each PKIXCertPathChecker
|
||||
* in the returned IList is cloned to protect against subsequent modifications.
|
||||
*
|
||||
* @return an immutable List of PKIXCertPathCheckers (may be empty, but not
|
||||
* <code>null</code>)
|
||||
*
|
||||
* @see #setCertPathCheckers(java.util.List)
|
||||
*/
|
||||
public virtual IList<PkixCertPathChecker> GetCertPathCheckers()
|
||||
{
|
||||
var result = new List<PkixCertPathChecker>(m_checkers.Count);
|
||||
foreach (var checker in m_checkers)
|
||||
{
|
||||
result.Add((PkixCertPathChecker)checker.Clone());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>PKIXCertPathChecker</code> to the list of certification
|
||||
* path checkers. See the {@link #setCertPathCheckers setCertPathCheckers}
|
||||
* method for more details.
|
||||
* <p>
|
||||
* Note that the <code>PKIXCertPathChecker</code> is cloned to protect
|
||||
* against subsequent modifications.</p>
|
||||
*
|
||||
* @param checker a <code>PKIXCertPathChecker</code> to add to the list of
|
||||
* checks. If <code>null</code>, the checker is ignored (not added to list).
|
||||
*/
|
||||
public virtual void AddCertPathChecker(PkixCertPathChecker checker)
|
||||
{
|
||||
if (checker != null)
|
||||
{
|
||||
m_checkers.Add((PkixCertPathChecker)checker.Clone());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
// FIXME Check this whole method against the Java implementation!
|
||||
|
||||
PkixParameters parameters = new PkixParameters(GetTrustAnchors());
|
||||
parameters.SetParams(this);
|
||||
return parameters;
|
||||
|
||||
|
||||
// PkixParameters obj = new PkixParameters(new HashSet());
|
||||
//// (PkixParameters) this.MemberwiseClone();
|
||||
// obj.x509Stores = new ArrayList(x509Stores);
|
||||
// obj.certPathCheckers = new ArrayList(certPathCheckers);
|
||||
//
|
||||
// //Iterator iter = certPathCheckers.iterator();
|
||||
// //obj.certPathCheckers = new ArrayList();
|
||||
// //while (iter.hasNext())
|
||||
// //{
|
||||
// // obj.certPathCheckers.add(((PKIXCertPathChecker)iter.next())
|
||||
// // .clone());
|
||||
// //}
|
||||
// //if (initialPolicies != null)
|
||||
// //{
|
||||
// // obj.initialPolicies = new HashSet(initialPolicies);
|
||||
// //}
|
||||
//// if (trustAnchors != null)
|
||||
//// {
|
||||
//// obj.trustAnchors = new HashSet(trustAnchors);
|
||||
//// }
|
||||
//// if (certSelector != null)
|
||||
//// {
|
||||
//// obj.certSelector = (X509CertStoreSelector) certSelector.Clone();
|
||||
//// }
|
||||
// return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to support <code>Clone()</code> under J2ME.
|
||||
* <code>super.Clone()</code> does not exist and fields are not copied.
|
||||
*
|
||||
* @param params Parameters to set. If this are
|
||||
* <code>ExtendedPkixParameters</code> they are copied to.
|
||||
*/
|
||||
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;
|
||||
SetTrustAnchors(parameters.GetTrustAnchors());
|
||||
|
||||
m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(parameters.m_storesAttrCert);
|
||||
m_storesCert = new List<IStore<X509Certificate>>(parameters.m_storesCert);
|
||||
m_storesCrl = new List<IStore<X509Crl>>(parameters.m_storesCrl);
|
||||
|
||||
SetTargetConstraintsAttrCert(parameters.GetTargetConstraintsAttrCert());
|
||||
SetTargetConstraintsCert(parameters.GetTargetConstraintsCert());
|
||||
|
||||
validityModel = parameters.validityModel;
|
||||
useDeltas = parameters.useDeltas;
|
||||
additionalLocationsEnabled = parameters.additionalLocationsEnabled;
|
||||
trustedACIssuers = new HashSet<TrustAnchor>(parameters.trustedACIssuers);
|
||||
prohibitedACAttributes = new HashSet<string>(parameters.prohibitedACAttributes);
|
||||
necessaryACAttributes = new HashSet<string>(parameters.necessaryACAttributes);
|
||||
attrCertCheckers = new HashSet<PkixAttrCertChecker>(parameters.attrCertCheckers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether delta CRLs should be used for checking the revocation status.
|
||||
* Defaults to <code>false</code>.
|
||||
*/
|
||||
public virtual bool IsUseDeltasEnabled
|
||||
{
|
||||
get { return useDeltas; }
|
||||
set { useDeltas = value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* The validity model.
|
||||
* @see #CHAIN_VALIDITY_MODEL
|
||||
* @see #PKIX_VALIDITY_MODEL
|
||||
*/
|
||||
public virtual int ValidityModel
|
||||
{
|
||||
get { return validityModel; }
|
||||
set { validityModel = value; }
|
||||
}
|
||||
|
||||
public virtual IList<IStore<X509V2AttributeCertificate>> GetStoresAttrCert()
|
||||
{
|
||||
return new List<IStore<X509V2AttributeCertificate>>(m_storesAttrCert);
|
||||
}
|
||||
|
||||
public virtual IList<IStore<X509Certificate>> GetStoresCert()
|
||||
{
|
||||
return new List<IStore<X509Certificate>>(m_storesCert);
|
||||
}
|
||||
|
||||
public virtual IList<IStore<X509Crl>> GetStoresCrl()
|
||||
{
|
||||
return new List<IStore<X509Crl>>(m_storesCrl);
|
||||
}
|
||||
|
||||
public virtual void SetAttrStoresCert(IList<IStore<X509V2AttributeCertificate>> storesAttrCert)
|
||||
{
|
||||
if (storesAttrCert == null)
|
||||
{
|
||||
m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storesAttrCert = new List<IStore<X509V2AttributeCertificate>>(storesAttrCert);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetStoresCert(IList<IStore<X509Certificate>> storesCert)
|
||||
{
|
||||
if (storesCert == null)
|
||||
{
|
||||
m_storesCert = new List<IStore<X509Certificate>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storesCert = new List<IStore<X509Certificate>>(storesCert);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetStoresCrl(IList<IStore<X509Crl>> storesCrl)
|
||||
{
|
||||
if (storesCrl == null)
|
||||
{
|
||||
m_storesCrl = new List<IStore<X509Crl>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storesCrl = new List<IStore<X509Crl>>(storesCrl);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddStoreAttrCert(IStore<X509V2AttributeCertificate> storeAttrCert)
|
||||
{
|
||||
if (storeAttrCert != null)
|
||||
{
|
||||
m_storesAttrCert.Add(storeAttrCert);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddStoreCert(IStore<X509Certificate> storeCert)
|
||||
{
|
||||
if (storeCert != null)
|
||||
{
|
||||
m_storesCert.Add(storeCert);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddStoreCrl(IStore<X509Crl> storeCrl)
|
||||
{
|
||||
if (storeCrl != null)
|
||||
{
|
||||
m_storesCrl.Add(storeCrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if additional {@link X509Store}s for locations like LDAP found
|
||||
* in certificates or CRLs should be used.
|
||||
*
|
||||
* @return Returns <code>true</code> if additional stores are used.
|
||||
*/
|
||||
public virtual bool IsAdditionalLocationsEnabled
|
||||
{
|
||||
get { return additionalLocationsEnabled; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if additional {@link X509Store}s for locations like LDAP found in
|
||||
* certificates or CRLs should be used.
|
||||
*
|
||||
* @param enabled <code>true</code> if additional stores are used.
|
||||
*/
|
||||
public virtual void SetAdditionalLocationsEnabled(
|
||||
bool enabled)
|
||||
{
|
||||
additionalLocationsEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the trusted attribute certificate issuers. If attribute
|
||||
* certificates is verified the trusted AC issuers must be set.
|
||||
* <p>
|
||||
* The returned <code>ISet</code> consists of <code>TrustAnchor</code>s.
|
||||
* </p><p>
|
||||
* The returned <code>ISet</code> is immutable. Never <code>null</code>
|
||||
* </p>
|
||||
*
|
||||
* @return Returns an immutable set of the trusted AC issuers.
|
||||
*/
|
||||
public virtual ISet<TrustAnchor> GetTrustedACIssuers()
|
||||
{
|
||||
return new HashSet<TrustAnchor>(trustedACIssuers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the trusted attribute certificate issuers. If attribute certificates
|
||||
* is verified the trusted AC issuers must be set.
|
||||
* <p>
|
||||
* The <code>trustedACIssuers</code> must be a <code>ISet</code> of
|
||||
* <code>TrustAnchor</code>
|
||||
* </p><p>
|
||||
* The given set is cloned.
|
||||
* </p>
|
||||
*
|
||||
* @param trustedACIssuers The trusted AC issuers to set. Is never
|
||||
* <code>null</code>.
|
||||
* @throws ClassCastException if an element of <code>stores</code> is not
|
||||
* a <code>TrustAnchor</code>.
|
||||
*/
|
||||
public virtual void SetTrustedACIssuers(ISet<TrustAnchor> trustedACIssuers)
|
||||
{
|
||||
if (trustedACIssuers == null)
|
||||
{
|
||||
this.trustedACIssuers = new HashSet<TrustAnchor>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.trustedACIssuers = new HashSet<TrustAnchor>(trustedACIssuers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the necessary attributes which must be contained in an attribute
|
||||
* certificate.
|
||||
* <p>
|
||||
* The returned <code>ISet</code> is immutable and contains
|
||||
* <code>String</code>s with the OIDs.
|
||||
* </p>
|
||||
*
|
||||
* @return Returns the necessary AC attributes.
|
||||
*/
|
||||
public virtual ISet<string> GetNecessaryACAttributes()
|
||||
{
|
||||
return new HashSet<string>(necessaryACAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the necessary which must be contained in an attribute certificate.
|
||||
* <p>
|
||||
* The <code>ISet</code> must contain <code>String</code>s with the
|
||||
* OIDs.
|
||||
* </p><p>
|
||||
* The set is cloned.
|
||||
* </p>
|
||||
*
|
||||
* @param necessaryACAttributes The necessary AC attributes to set.
|
||||
* @throws ClassCastException if an element of
|
||||
* <code>necessaryACAttributes</code> is not a
|
||||
* <code>String</code>.
|
||||
*/
|
||||
public virtual void SetNecessaryACAttributes(ISet<string> necessaryACAttributes)
|
||||
{
|
||||
if (necessaryACAttributes == null)
|
||||
{
|
||||
this.necessaryACAttributes = new HashSet<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.necessaryACAttributes = new HashSet<string>(necessaryACAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute certificates which are not allowed.
|
||||
* <p>
|
||||
* The returned <code>ISet</code> is immutable and contains
|
||||
* <code>String</code>s with the OIDs.
|
||||
* </p>
|
||||
*
|
||||
* @return Returns the prohibited AC attributes. Is never <code>null</code>.
|
||||
*/
|
||||
public virtual ISet<string> GetProhibitedACAttributes()
|
||||
{
|
||||
return new HashSet<string>(prohibitedACAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute certificates which are not allowed.
|
||||
* <p>
|
||||
* The <code>ISet</code> must contain <code>String</code>s with the
|
||||
* OIDs.
|
||||
* </p><p>
|
||||
* The set is cloned.
|
||||
* </p>
|
||||
*
|
||||
* @param prohibitedACAttributes The prohibited AC attributes to set.
|
||||
* @throws ClassCastException if an element of
|
||||
* <code>prohibitedACAttributes</code> is not a
|
||||
* <code>String</code>.
|
||||
*/
|
||||
public virtual void SetProhibitedACAttributes(ISet<string> prohibitedACAttributes)
|
||||
{
|
||||
if (prohibitedACAttributes == null)
|
||||
{
|
||||
this.prohibitedACAttributes = new HashSet<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.prohibitedACAttributes = new HashSet<string>(prohibitedACAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attribute certificate checker. The returned set contains
|
||||
* {@link PKIXAttrCertChecker}s and is immutable.
|
||||
*
|
||||
* @return Returns the attribute certificate checker. Is never
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public virtual ISet<PkixAttrCertChecker> GetAttrCertCheckers()
|
||||
{
|
||||
return new HashSet<PkixAttrCertChecker>(attrCertCheckers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute certificate checkers.
|
||||
* <p>
|
||||
* All elements in the <code>ISet</code> must a {@link PKIXAttrCertChecker}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The given set is cloned.
|
||||
* </p>
|
||||
*
|
||||
* @param attrCertCheckers The attribute certificate checkers to set. Is
|
||||
* never <code>null</code>.
|
||||
* @throws ClassCastException if an element of <code>attrCertCheckers</code>
|
||||
* is not a <code>PKIXAttrCertChecker</code>.
|
||||
*/
|
||||
public virtual void SetAttrCertCheckers(ISet<PkixAttrCertChecker> attrCertCheckers)
|
||||
{
|
||||
if (attrCertCheckers == null)
|
||||
{
|
||||
this.attrCertCheckers = new HashSet<PkixAttrCertChecker>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.attrCertCheckers = new HashSet<PkixAttrCertChecker>(attrCertCheckers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bddc2e795cf6cd046bbd64b225ce7cdc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,160 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for PkixPolicyNode.
|
||||
/// </summary>
|
||||
public class PkixPolicyNode
|
||||
// : IPolicyNode
|
||||
{
|
||||
protected IList<PkixPolicyNode> mChildren;
|
||||
protected int mDepth;
|
||||
protected ISet<string> mExpectedPolicies;
|
||||
protected PkixPolicyNode mParent;
|
||||
protected ISet<PolicyQualifierInfo> mPolicyQualifiers;
|
||||
protected string mValidPolicy;
|
||||
protected bool mCritical;
|
||||
|
||||
public virtual int Depth
|
||||
{
|
||||
get { return this.mDepth; }
|
||||
}
|
||||
|
||||
public virtual IEnumerable<PkixPolicyNode> Children
|
||||
{
|
||||
get { return CollectionUtilities.Proxy(mChildren); }
|
||||
}
|
||||
|
||||
public virtual bool IsCritical
|
||||
{
|
||||
get { return this.mCritical; }
|
||||
set { this.mCritical = value; }
|
||||
}
|
||||
|
||||
public virtual ISet<PolicyQualifierInfo> PolicyQualifiers
|
||||
{
|
||||
get { return new HashSet<PolicyQualifierInfo>(this.mPolicyQualifiers); }
|
||||
}
|
||||
|
||||
public virtual string ValidPolicy
|
||||
{
|
||||
get { return this.mValidPolicy; }
|
||||
}
|
||||
|
||||
public virtual bool HasChildren
|
||||
{
|
||||
get { return mChildren.Count != 0; }
|
||||
}
|
||||
|
||||
public virtual ISet<string> ExpectedPolicies
|
||||
{
|
||||
get { return new HashSet<string>(this.mExpectedPolicies); }
|
||||
set { this.mExpectedPolicies = new HashSet<string>(value); }
|
||||
}
|
||||
|
||||
public virtual PkixPolicyNode Parent
|
||||
{
|
||||
get { return this.mParent; }
|
||||
set { this.mParent = value; }
|
||||
}
|
||||
|
||||
/// Constructors
|
||||
public PkixPolicyNode(
|
||||
IEnumerable<PkixPolicyNode> children,
|
||||
int depth,
|
||||
ISet<string> expectedPolicies,
|
||||
PkixPolicyNode parent,
|
||||
ISet<PolicyQualifierInfo> policyQualifiers,
|
||||
string validPolicy,
|
||||
bool critical)
|
||||
{
|
||||
if (children == null)
|
||||
{
|
||||
this.mChildren = new List<PkixPolicyNode>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.mChildren = new List<PkixPolicyNode>(children);
|
||||
}
|
||||
|
||||
this.mDepth = depth;
|
||||
this.mExpectedPolicies = expectedPolicies;
|
||||
this.mParent = parent;
|
||||
this.mPolicyQualifiers = policyQualifiers;
|
||||
this.mValidPolicy = validPolicy;
|
||||
this.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 buf = new StringBuilder();
|
||||
buf.Append(indent);
|
||||
buf.Append(mValidPolicy);
|
||||
buf.AppendLine(" {");
|
||||
|
||||
foreach (PkixPolicyNode child in mChildren)
|
||||
{
|
||||
buf.Append(child.ToString(indent + " "));
|
||||
}
|
||||
|
||||
buf.Append(indent);
|
||||
buf.AppendLine("}");
|
||||
return buf.ToString();
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
return Copy();
|
||||
}
|
||||
|
||||
public virtual PkixPolicyNode Copy()
|
||||
{
|
||||
PkixPolicyNode node = new PkixPolicyNode(
|
||||
new List<PkixPolicyNode>(),
|
||||
mDepth,
|
||||
new HashSet<string>(mExpectedPolicies),
|
||||
null,
|
||||
new HashSet<PolicyQualifierInfo>(mPolicyQualifiers),
|
||||
mValidPolicy,
|
||||
mCritical);
|
||||
|
||||
foreach (PkixPolicyNode child in mChildren)
|
||||
{
|
||||
PkixPolicyNode copy = child.Copy();
|
||||
copy.Parent = node;
|
||||
node.AddChild(copy);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d33024da030accb498009e4aecd51fe9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,100 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// This class helps to handle CRL revocation reasons mask. Each CRL handles a
|
||||
/// certain set of revocation reasons.
|
||||
/// </summary>
|
||||
internal class ReasonsMask
|
||||
{
|
||||
private int _reasons;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs are reason mask with the reasons.
|
||||
/// </summary>
|
||||
/// <param name="reasons">The reasons.</param>
|
||||
internal ReasonsMask(
|
||||
int reasons)
|
||||
{
|
||||
_reasons = reasons;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A reason mask with no reason.
|
||||
/// </summary>
|
||||
internal ReasonsMask()
|
||||
: this(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A mask with all revocation reasons.
|
||||
/// </summary>
|
||||
internal static readonly ReasonsMask AllReasons = new ReasonsMask(
|
||||
ReasonFlags.AACompromise | ReasonFlags.AffiliationChanged | ReasonFlags.CACompromise
|
||||
| ReasonFlags.CertificateHold | ReasonFlags.CessationOfOperation
|
||||
| ReasonFlags.KeyCompromise | ReasonFlags.PrivilegeWithdrawn | ReasonFlags.Unused
|
||||
| ReasonFlags.Superseded);
|
||||
|
||||
/**
|
||||
* Adds all reasons from the reasons mask to this mask.
|
||||
*
|
||||
* @param mask The reasons mask to add.
|
||||
*/
|
||||
internal void AddReasons(
|
||||
ReasonsMask mask)
|
||||
{
|
||||
_reasons = _reasons | mask.Reasons.IntValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <code>true</code> if this reasons mask contains all possible
|
||||
/// reasons.
|
||||
/// </summary>
|
||||
/// <returns>true if this reasons mask contains all possible reasons.
|
||||
/// </returns>
|
||||
internal bool IsAllReasons
|
||||
{
|
||||
get { return _reasons == AllReasons._reasons; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intersects this mask with the given reasons mask.
|
||||
/// </summary>
|
||||
/// <param name="mask">mask The mask to intersect with.</param>
|
||||
/// <returns>The intersection of this and teh given mask.</returns>
|
||||
internal ReasonsMask Intersect(
|
||||
ReasonsMask mask)
|
||||
{
|
||||
ReasonsMask _mask = new ReasonsMask();
|
||||
_mask.AddReasons(new ReasonsMask(_reasons & mask.Reasons.IntValue));
|
||||
return _mask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the passed reasons mask has new reasons.
|
||||
/// </summary>
|
||||
/// <param name="mask">The reasons mask which should be tested for new reasons.</param>
|
||||
/// <returns><c>true</c> if the passed reasons mask has new reasons.</returns>
|
||||
internal bool HasNewReasons(
|
||||
ReasonsMask mask)
|
||||
{
|
||||
return ((_reasons | mask.Reasons.IntValue ^ _reasons) != 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the reasons in this mask.
|
||||
/// </summary>
|
||||
public ReasonFlags Reasons
|
||||
{
|
||||
get { return new ReasonFlags(_reasons); }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82782c3f371478d4788bfedceeac9754
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b4b0eb500c7b0446b1ae401484cb0ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,578 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
internal static class Rfc3281CertPathUtilities
|
||||
{
|
||||
internal static void ProcessAttrCert7(
|
||||
X509V2AttributeCertificate attrCert,
|
||||
PkixCertPath certPath,
|
||||
PkixCertPath holderCertPath,
|
||||
PkixParameters pkixParams)
|
||||
{
|
||||
// TODO:
|
||||
// AA Controls
|
||||
// Attribute encryption
|
||||
// Proxy
|
||||
var critExtOids = attrCert.GetCriticalExtensionOids();
|
||||
|
||||
// 7.1
|
||||
// process extensions
|
||||
|
||||
// target information checked in step 6 / X509AttributeCertStoreSelector
|
||||
if (critExtOids.Contains(X509Extensions.TargetInformation.Id))
|
||||
{
|
||||
try
|
||||
{
|
||||
TargetInformation.GetInstance(PkixCertPathValidatorUtilities
|
||||
.GetExtensionValue(attrCert, X509Extensions.TargetInformation));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Target information extension could not be read.", e);
|
||||
}
|
||||
}
|
||||
critExtOids.Remove(X509Extensions.TargetInformation.Id);
|
||||
foreach (PkixAttrCertChecker checker in pkixParams.GetAttrCertCheckers())
|
||||
{
|
||||
checker.Check(attrCert, certPath, holderCertPath, critExtOids);
|
||||
}
|
||||
if (critExtOids.Count > 0)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Attribute certificate contains unsupported critical extensions: " + critExtOids);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an attribute certificate is revoked.
|
||||
*
|
||||
* @param attrCert Attribute certificate to check if it is revoked.
|
||||
* @param paramsPKIX PKIX parameters.
|
||||
* @param issuerCert The issuer certificate of the attribute certificate
|
||||
* <code>attrCert</code>.
|
||||
* @param validDate The date when the certificate revocation status should
|
||||
* be checked.
|
||||
* @param certPathCerts The certificates of the certification path to be
|
||||
* checked.
|
||||
*
|
||||
* @throws CertPathValidatorException if the certificate is revoked or the
|
||||
* status cannot be checked or some error occurs.
|
||||
*/
|
||||
internal static void CheckCrls(
|
||||
X509V2AttributeCertificate attrCert,
|
||||
PkixParameters paramsPKIX,
|
||||
X509Certificate issuerCert,
|
||||
DateTime validDate,
|
||||
IList<X509Certificate> certPathCerts)
|
||||
{
|
||||
if (!paramsPKIX.IsRevocationEnabled)
|
||||
return;
|
||||
|
||||
// check if revocation is available
|
||||
if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
|
||||
{
|
||||
if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null ||
|
||||
attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"No rev avail extension is set, but also an AC revocation pointer.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CrlDistPoint crldp;
|
||||
try
|
||||
{
|
||||
crldp = CrlDistPoint.GetInstance(
|
||||
PkixCertPathValidatorUtilities.GetExtensionValue(attrCert, X509Extensions.CrlDistributionPoints));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("CRL distribution point extension could not be read.", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"No additional CRL locations could be decoded from CRL distribution point extension.", e);
|
||||
}
|
||||
|
||||
CertStatus certStatus = new CertStatus();
|
||||
ReasonsMask reasonsMask = new ReasonsMask();
|
||||
|
||||
Exception lastException = null;
|
||||
bool validCrlFound = false;
|
||||
// for each distribution point
|
||||
if (crldp != null)
|
||||
{
|
||||
DistributionPoint[] dps;
|
||||
try
|
||||
{
|
||||
dps = crldp.GetDistributionPoints();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException("Distribution points could not be read.", e);
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0;
|
||||
i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons;
|
||||
i++)
|
||||
{
|
||||
PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone();
|
||||
CheckCrl(dps[i], attrCert, paramsPKIXClone,validDate, issuerCert, certStatus, reasonsMask,
|
||||
certPathCerts);
|
||||
validCrlFound = true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
lastException = new Exception("No valid CRL for distribution point found.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the revocation status has not been determined, repeat the
|
||||
* process above with any available CRLs not specified in a
|
||||
* distribution point but issued by the certificate issuer.
|
||||
*/
|
||||
|
||||
if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons)
|
||||
{
|
||||
try
|
||||
{
|
||||
/*
|
||||
* assume a DP with both the reasons and the cRLIssuer
|
||||
* fields omitted and a distribution point name of the
|
||||
* certificate issuer.
|
||||
*/
|
||||
X509Name issuer;
|
||||
try
|
||||
{
|
||||
issuer = X509Name.GetInstance(attrCert.Issuer.GetPrincipals()[0].GetEncoded());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Issuer from certificate for CRL could not be reencoded.", e);
|
||||
}
|
||||
DistributionPoint dp = new DistributionPoint(
|
||||
new DistributionPointName(0, new GeneralNames(
|
||||
new GeneralName(GeneralName.DirectoryName, issuer))), null, null);
|
||||
PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX.Clone();
|
||||
CheckCrl(dp, attrCert, paramsPKIXClone, validDate,
|
||||
issuerCert, certStatus, reasonsMask, certPathCerts);
|
||||
validCrlFound = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
lastException = new Exception("No valid CRL for distribution point found.", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validCrlFound)
|
||||
throw new PkixCertPathValidatorException("No valid CRL found.", lastException);
|
||||
|
||||
if (certStatus.Status != CertStatus.Unrevoked)
|
||||
{
|
||||
// This format is enforced by the NistCertPath tests
|
||||
string formattedDate = certStatus.RevocationDate.Value.ToString("ddd MMM dd HH:mm:ss K yyyy");
|
||||
string message = "Attribute certificate revocation after " + formattedDate + ", reason: "
|
||||
+ Rfc3280CertPathUtilities.CrlReasons[certStatus.Status];
|
||||
throw new PkixCertPathValidatorException(message);
|
||||
}
|
||||
if (!reasonsMask.IsAllReasons
|
||||
&& certStatus.Status == CertStatus.Unrevoked)
|
||||
{
|
||||
certStatus.Status = CertStatus.Undetermined;
|
||||
}
|
||||
if (certStatus.Status == CertStatus.Undetermined)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Attribute certificate status could not be determined.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void AdditionalChecks(
|
||||
X509V2AttributeCertificate attrCert,
|
||||
PkixParameters pkixParams)
|
||||
{
|
||||
// 1
|
||||
foreach (string oid in pkixParams.GetProhibitedACAttributes())
|
||||
{
|
||||
if (attrCert.GetAttributes(oid) != null)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Attribute certificate contains prohibited attribute: "
|
||||
+ oid + ".");
|
||||
}
|
||||
}
|
||||
foreach (string oid in pkixParams.GetNecessaryACAttributes())
|
||||
{
|
||||
if (attrCert.GetAttributes(oid) == null)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Attribute certificate does not contain necessary attribute: "
|
||||
+ oid + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ProcessAttrCert5(
|
||||
X509V2AttributeCertificate attrCert,
|
||||
PkixParameters pkixParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
attrCert.CheckValidity(PkixCertPathValidatorUtilities.GetValidDate(pkixParams));
|
||||
}
|
||||
catch (CertificateExpiredException e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Attribute certificate is not valid.", e);
|
||||
}
|
||||
catch (CertificateNotYetValidException e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Attribute certificate is not valid.", e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ProcessAttrCert4(
|
||||
X509Certificate acIssuerCert,
|
||||
PkixParameters pkixParams)
|
||||
{
|
||||
var set = pkixParams.GetTrustedACIssuers();
|
||||
bool trusted = false;
|
||||
foreach (TrustAnchor anchor in set)
|
||||
{
|
||||
var symbols = X509Name.RFC2253Symbols;
|
||||
if (acIssuerCert.SubjectDN.ToString(false, symbols).Equals(anchor.CAName)
|
||||
|| acIssuerCert.Equals(anchor.TrustedCert))
|
||||
{
|
||||
trusted = true;
|
||||
}
|
||||
}
|
||||
if (!trusted)
|
||||
{
|
||||
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 validator = new PkixCertPathValidator();
|
||||
|
||||
try
|
||||
{
|
||||
return validator.Validate(certPath, pkixParams);
|
||||
}
|
||||
catch (PkixCertPathValidatorException e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Certification path for issuer certificate of attribute certificate could not be validated.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a holder public key certificate and verifies its
|
||||
* certification path.
|
||||
*
|
||||
* @param attrCert the attribute certificate.
|
||||
* @param pkixParams The PKIX parameters.
|
||||
* @return The certificate path of the holder certificate.
|
||||
* @throws Exception if
|
||||
* <ul>
|
||||
* <li>no public key certificate can be found although holder
|
||||
* information is given by an entity name or a base certificate
|
||||
* ID</li>
|
||||
* <li>support classes cannot be created</li>
|
||||
* <li>no certification path for the public key certificate can
|
||||
* be built</li>
|
||||
* </ul>
|
||||
*/
|
||||
internal static PkixCertPath ProcessAttrCert1(
|
||||
X509V2AttributeCertificate attrCert,
|
||||
PkixParameters pkixParams)
|
||||
{
|
||||
PkixCertPathBuilderResult result = null;
|
||||
// find holder PKCs
|
||||
var holderPKCs = new HashSet<X509Certificate>();
|
||||
if (attrCert.Holder.GetIssuer() != null)
|
||||
{
|
||||
X509CertStoreSelector selector = new X509CertStoreSelector();
|
||||
selector.SerialNumber = attrCert.Holder.SerialNumber;
|
||||
X509Name[] principals = attrCert.Holder.GetIssuer();
|
||||
for (int i = 0; i < principals.Length; i++)
|
||||
{
|
||||
// TODO Replace loop with a single multiprincipal selector (or don't even use selector)
|
||||
try
|
||||
{
|
||||
selector.Issuer = principals[i];
|
||||
|
||||
CollectionUtilities.CollectMatches(holderPKCs, selector, pkixParams.GetStoresCert());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Public key certificate for attribute certificate cannot be searched.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
if (holderPKCs.Count < 1)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Public key certificate specified in base certificate ID for attribute certificate cannot be found.");
|
||||
}
|
||||
}
|
||||
if (attrCert.Holder.GetEntityNames() != null)
|
||||
{
|
||||
X509CertStoreSelector selector = new X509CertStoreSelector();
|
||||
X509Name[] principals = attrCert.Holder.GetEntityNames();
|
||||
for (int i = 0; i < principals.Length; i++)
|
||||
{
|
||||
// TODO Replace loop with a single multiprincipal selector (or don't even use selector)
|
||||
try
|
||||
{
|
||||
selector.Issuer = principals[i];
|
||||
|
||||
CollectionUtilities.CollectMatches(holderPKCs, selector, pkixParams.GetStoresCert());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Public key certificate for attribute certificate cannot be searched.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
if (holderPKCs.Count < 1)
|
||||
{
|
||||
throw new PkixCertPathValidatorException(
|
||||
"Public key certificate specified in entity name for attribute certificate cannot be found.");
|
||||
}
|
||||
}
|
||||
|
||||
// verify cert paths for PKCs
|
||||
PkixBuilderParameters parameters = PkixBuilderParameters.GetInstance(pkixParams);
|
||||
|
||||
PkixCertPathValidatorException lastException = null;
|
||||
foreach (X509Certificate cert in holderPKCs)
|
||||
{
|
||||
X509CertStoreSelector certSelector = new X509CertStoreSelector();
|
||||
certSelector.Certificate = cert;
|
||||
|
||||
parameters.SetTargetConstraintsCert(certSelector);
|
||||
|
||||
PkixCertPathBuilder builder = new PkixCertPathBuilder();
|
||||
|
||||
try
|
||||
{
|
||||
result = builder.Build(parameters);
|
||||
}
|
||||
catch (PkixCertPathBuilderException e)
|
||||
{
|
||||
lastException = new PkixCertPathValidatorException(
|
||||
"Certification path for public key certificate of attribute certificate could not be build.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
if (lastException != null)
|
||||
{
|
||||
throw lastException;
|
||||
}
|
||||
return result.CertPath;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Checks a distribution point for revocation information for the
|
||||
* certificate <code>attrCert</code>.
|
||||
*
|
||||
* @param dp The distribution point to consider.
|
||||
* @param attrCert The attribute certificate which should be checked.
|
||||
* @param paramsPKIX PKIX parameters.
|
||||
* @param validDate The date when the certificate revocation status should
|
||||
* be checked.
|
||||
* @param issuerCert Certificate to check if it is revoked.
|
||||
* @param reasonMask The reasons mask which is already checked.
|
||||
* @param certPathCerts The certificates of the certification path to be
|
||||
* checked.
|
||||
* @throws Exception if the certificate is revoked or the status
|
||||
* cannot be checked or some error occurs.
|
||||
*/
|
||||
private static void CheckCrl(
|
||||
DistributionPoint dp,
|
||||
X509V2AttributeCertificate attrCert,
|
||||
PkixParameters paramsPKIX,
|
||||
DateTime validDate,
|
||||
X509Certificate issuerCert,
|
||||
CertStatus certStatus,
|
||||
ReasonsMask reasonMask,
|
||||
IList<X509Certificate> certPathCerts)
|
||||
{
|
||||
/*
|
||||
* 4.3.6 No Revocation Available
|
||||
*
|
||||
* The noRevAvail extension, defined in [X.509-2000], allows an AC
|
||||
* issuer to indicate that no revocation information will be made
|
||||
* available for this AC.
|
||||
*/
|
||||
if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
|
||||
return;
|
||||
|
||||
DateTime currentDate = DateTime.UtcNow;
|
||||
if (validDate.CompareTo(currentDate) > 0)
|
||||
throw new Exception("Validation time is in future.");
|
||||
|
||||
// (a)
|
||||
/*
|
||||
* We always get timely valid CRLs, so there is no step (a) (1).
|
||||
* "locally cached" CRLs are assumed to be in getStore(), additional
|
||||
* CRLs must be enabled in the ExtendedPkixParameters and are in
|
||||
* getAdditionalStore()
|
||||
*/
|
||||
var crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, currentDate, paramsPKIX);
|
||||
bool validCrlFound = false;
|
||||
Exception lastException = null;
|
||||
|
||||
var crl_iter = crls.GetEnumerator();
|
||||
|
||||
while (crl_iter.MoveNext()
|
||||
&& certStatus.Status == CertStatus.Unrevoked
|
||||
&& !reasonMask.IsAllReasons)
|
||||
{
|
||||
try
|
||||
{
|
||||
X509Crl crl = crl_iter.Current;
|
||||
|
||||
// (d)
|
||||
ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp);
|
||||
|
||||
// (e)
|
||||
/*
|
||||
* The reasons mask is updated at the end, so only valid CRLs
|
||||
* can update it. If this CRL does not contain new reasons it
|
||||
* must be ignored.
|
||||
*/
|
||||
if (!interimReasonsMask.HasNewReasons(reasonMask))
|
||||
continue;
|
||||
|
||||
// (f)
|
||||
var keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert,null, null, paramsPKIX,
|
||||
certPathCerts);
|
||||
|
||||
// (g)
|
||||
AsymmetricKeyParameter pubKey = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys);
|
||||
|
||||
X509Crl deltaCRL = null;
|
||||
|
||||
if (paramsPKIX.IsUseDeltasEnabled)
|
||||
{
|
||||
// get delta CRLs
|
||||
var deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl);
|
||||
|
||||
// we only want one valid delta CRL
|
||||
// (h)
|
||||
deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, pubKey);
|
||||
}
|
||||
|
||||
/*
|
||||
* CRL must be be valid at the current time, not the validation
|
||||
* time. If a certificate is revoked with reason keyCompromise,
|
||||
* cACompromise, it can be used for forgery, also for the past.
|
||||
* This reason may not be contained in older CRLs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* in the chain model signatures stay valid also after the
|
||||
* certificate has been expired, so they do not have to be in
|
||||
* the CRL vality time
|
||||
*/
|
||||
if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel)
|
||||
{
|
||||
/*
|
||||
* if a certificate has expired, but was revoked, it is not
|
||||
* more in the CRL, so it would be regarded as valid if the
|
||||
* first check is not done
|
||||
*/
|
||||
if (attrCert.NotAfter.CompareTo(crl.ThisUpdate) < 0)
|
||||
throw new Exception("No valid CRL for current time found.");
|
||||
}
|
||||
|
||||
Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, crl);
|
||||
|
||||
// (b) (2)
|
||||
Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, crl);
|
||||
|
||||
// (c)
|
||||
Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX);
|
||||
|
||||
// (i)
|
||||
Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL,
|
||||
attrCert, certStatus, paramsPKIX);
|
||||
|
||||
// (j)
|
||||
Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, attrCert,
|
||||
certStatus);
|
||||
|
||||
// (k)
|
||||
if (certStatus.Status == CrlReason.RemoveFromCrl)
|
||||
{
|
||||
certStatus.Status = CertStatus.Unrevoked;
|
||||
}
|
||||
|
||||
// update reasons mask
|
||||
reasonMask.AddReasons(interimReasonsMask);
|
||||
validCrlFound = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validCrlFound)
|
||||
throw lastException;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d710687c541762b48abd98c0e1a2246c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,261 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||||
{
|
||||
/// <summary>
|
||||
/// A trust anchor or most-trusted Certification Authority (CA).
|
||||
///
|
||||
/// This class represents a "most-trusted CA", which is used as a trust anchor
|
||||
/// for validating X.509 certification paths. A most-trusted CA includes the
|
||||
/// public key of the CA, the CA's name, and any constraints upon the set of
|
||||
/// paths which may be validated using this key. These parameters can be
|
||||
/// specified in the form of a trusted X509Certificate or as individual
|
||||
/// parameters.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of TrustAnchor with the specified X509Certificate and
|
||||
/// optional name constraints, which are intended to be used as additional
|
||||
/// constraints when validating an X.509 certification path.
|
||||
/// The name constraints are specified as a byte array. This byte array
|
||||
/// should contain the DER encoded form of the name constraints, as they
|
||||
/// would appear in the NameConstraints structure defined in RFC 2459 and
|
||||
/// X.509. The ASN.1 definition of this structure appears below.
|
||||
///
|
||||
/// <pre>
|
||||
/// NameConstraints ::= SEQUENCE {
|
||||
/// permittedSubtrees [0] GeneralSubtrees OPTIONAL,
|
||||
/// excludedSubtrees [1] GeneralSubtrees OPTIONAL }
|
||||
///
|
||||
/// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
|
||||
///
|
||||
/// GeneralSubtree ::= SEQUENCE {
|
||||
/// base GeneralName,
|
||||
/// minimum [0] BaseDistance DEFAULT 0,
|
||||
/// maximum [1] BaseDistance OPTIONAL }
|
||||
///
|
||||
/// BaseDistance ::= INTEGER (0..MAX)
|
||||
///
|
||||
/// GeneralName ::= CHOICE {
|
||||
/// otherName [0] OtherName,
|
||||
/// rfc822Name [1] IA5String,
|
||||
/// dNSName [2] IA5String,
|
||||
/// x400Address [3] ORAddress,
|
||||
/// directoryName [4] Name,
|
||||
/// ediPartyName [5] EDIPartyName,
|
||||
/// uniformResourceIdentifier [6] IA5String,
|
||||
/// iPAddress [7] OCTET STRING,
|
||||
/// registeredID [8] OBJECT IDENTIFIER}
|
||||
/// </pre>
|
||||
///
|
||||
/// Note that the name constraints byte array supplied is cloned to protect
|
||||
/// against subsequent modifications.
|
||||
/// </summary>
|
||||
/// <param name="trustedCert">a trusted X509Certificate</param>
|
||||
/// <param name="nameConstraints">a byte array containing the ASN.1 DER encoding of a
|
||||
/// NameConstraints extension to be used for checking name
|
||||
/// constraints. Only the value of the extension is included, not
|
||||
/// the OID or criticality flag. Specify null to omit the
|
||||
/// parameter.</param>
|
||||
/// <exception cref="ArgumentNullException">if the specified X509Certificate is null</exception>
|
||||
public TrustAnchor(
|
||||
X509Certificate trustedCert,
|
||||
byte[] nameConstraints)
|
||||
{
|
||||
if (trustedCert == null)
|
||||
throw new ArgumentNullException("trustedCert");
|
||||
|
||||
this.trustedCert = trustedCert;
|
||||
this.pubKey = null;
|
||||
this.caName = null;
|
||||
this.caPrincipal = null;
|
||||
setNameConstraints(nameConstraints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of <c>TrustAnchor</c> where the
|
||||
/// most-trusted CA is specified as an X500Principal and public key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Name constraints are an optional parameter, and are intended to be used
|
||||
/// as additional constraints when validating an X.509 certification path.
|
||||
/// </p><p>
|
||||
/// The name constraints are specified as a byte array. This byte array
|
||||
/// contains the DER encoded form of the name constraints, as they
|
||||
/// would appear in the NameConstraints structure defined in RFC 2459
|
||||
/// and X.509. The ASN.1 notation for this structure is supplied in the
|
||||
/// documentation for the other constructors.
|
||||
/// </p><p>
|
||||
/// Note that the name constraints byte array supplied here is cloned to
|
||||
/// protect against subsequent modifications.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="caPrincipal">the name of the most-trusted CA as X509Name</param>
|
||||
/// <param name="pubKey">the public key of the most-trusted CA</param>
|
||||
/// <param name="nameConstraints">
|
||||
/// a byte array containing the ASN.1 DER encoding of a NameConstraints extension to
|
||||
/// be used for checking name constraints. Only the value of the extension is included,
|
||||
/// not the OID or criticality flag. Specify <c>null</c> to omit the parameter.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// if <c>caPrincipal</c> or <c>pubKey</c> is null
|
||||
/// </exception>
|
||||
public TrustAnchor(
|
||||
X509Name caPrincipal,
|
||||
AsymmetricKeyParameter pubKey,
|
||||
byte[] nameConstraints)
|
||||
{
|
||||
if (caPrincipal == null)
|
||||
throw new ArgumentNullException("caPrincipal");
|
||||
if (pubKey == null)
|
||||
throw new ArgumentNullException("pubKey");
|
||||
|
||||
this.trustedCert = null;
|
||||
this.caPrincipal = caPrincipal;
|
||||
this.caName = caPrincipal.ToString();
|
||||
this.pubKey = pubKey;
|
||||
setNameConstraints(nameConstraints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of <code>TrustAnchor</code> where the most-trusted
|
||||
/// CA is specified as a distinguished name and public key. Name constraints
|
||||
/// are an optional parameter, and are intended to be used as additional
|
||||
/// constraints when validating an X.509 certification path.
|
||||
/// <br/>
|
||||
/// The name constraints are specified as a byte array. This byte array
|
||||
/// contains the DER encoded form of the name constraints, as they would
|
||||
/// appear in the NameConstraints structure defined in RFC 2459 and X.509.
|
||||
/// </summary>
|
||||
/// <param name="caName">the X.500 distinguished name of the most-trusted CA in RFC
|
||||
/// 2253 string format</param>
|
||||
/// <param name="pubKey">the public key of the most-trusted CA</param>
|
||||
/// <param name="nameConstraints">a byte array containing the ASN.1 DER encoding of a
|
||||
/// NameConstraints extension to be used for checking name
|
||||
/// constraints. Only the value of the extension is included, not
|
||||
/// the OID or criticality flag. Specify null to omit the
|
||||
/// parameter.</param>
|
||||
/// throws NullPointerException, IllegalArgumentException
|
||||
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");
|
||||
|
||||
this.caPrincipal = new X509Name(caName);
|
||||
this.pubKey = pubKey;
|
||||
this.caName = caName;
|
||||
this.trustedCert = null;
|
||||
setNameConstraints(nameConstraints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the most-trusted CA certificate.
|
||||
/// </summary>
|
||||
public X509Certificate TrustedCert
|
||||
{
|
||||
get { return this.trustedCert; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name of the most-trusted CA as an X509Name.
|
||||
/// </summary>
|
||||
public X509Name CA
|
||||
{
|
||||
get { return this.caPrincipal; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the name of the most-trusted CA in RFC 2253 string format.
|
||||
/// </summary>
|
||||
public string CAName
|
||||
{
|
||||
get { return this.caName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the public key of the most-trusted CA.
|
||||
/// </summary>
|
||||
public AsymmetricKeyParameter CAPublicKey
|
||||
{
|
||||
get { return this.pubKey; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decode the name constraints and clone them if not null.
|
||||
/// </summary>
|
||||
private void setNameConstraints(
|
||||
byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
ncBytes = null;
|
||||
nc = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ncBytes = (byte[]) bytes.Clone();
|
||||
// validate DER encoding
|
||||
//nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
|
||||
nc = NameConstraints.GetInstance(Asn1Object.FromByteArray(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetNameConstraints
|
||||
{
|
||||
get { return Arrays.Clone(ncBytes); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a formatted string describing the <code>TrustAnchor</code>.
|
||||
/// </summary>
|
||||
/// <returns>a formatted string describing the <code>TrustAnchor</code></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
// TODO Some of the sub-objects might not implement ToString() properly
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("[");
|
||||
if (this.pubKey != null)
|
||||
{
|
||||
sb.Append(" Trusted CA Public Key: ").Append(this.pubKey).AppendLine();
|
||||
sb.Append(" Trusted CA Issuer Name: ").Append(this.caName).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(" Trusted CA cert: ").Append(this.TrustedCert).AppendLine();
|
||||
}
|
||||
if (nc != null)
|
||||
{
|
||||
sb.Append(" Name Constraints: ").Append(nc).AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d36de1eed444fb4faa2bdef5ce1d96c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user