diff --git a/Crypto/src/pkix/TrustAnchor.cs b/Crypto/src/pkix/TrustAnchor.cs
new file mode 100644
index 000000000..22078baf2
--- /dev/null
+++ b/Crypto/src/pkix/TrustAnchor.cs
@@ -0,0 +1,259 @@
+using System;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Pkix
+{
+ /// <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 = 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();
+ }
+ }
+}
\ No newline at end of file
|