You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
9.3 KiB
264 lines
9.3 KiB
8 months ago
|
#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
|
||
|
string nl = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.NewLine;
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
sb.Append("[");
|
||
|
sb.Append(nl);
|
||
|
if (this.pubKey != null)
|
||
|
{
|
||
|
sb.Append(" Trusted CA Public Key: ").Append(this.pubKey).Append(nl);
|
||
|
sb.Append(" Trusted CA Issuer Name: ").Append(this.caName).Append(nl);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sb.Append(" Trusted CA cert: ").Append(this.TrustedCert).Append(nl);
|
||
|
}
|
||
|
if (nc != null)
|
||
|
{
|
||
|
sb.Append(" Name Constraints: ").Append(nc).Append(nl);
|
||
|
}
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#pragma warning restore
|
||
|
#endif
|