TrustAnchor.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using System.Text;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
  11. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
  12. {
  13. /// <summary>
  14. /// A trust anchor or most-trusted Certification Authority (CA).
  15. ///
  16. /// This class represents a "most-trusted CA", which is used as a trust anchor
  17. /// for validating X.509 certification paths. A most-trusted CA includes the
  18. /// public key of the CA, the CA's name, and any constraints upon the set of
  19. /// paths which may be validated using this key. These parameters can be
  20. /// specified in the form of a trusted X509Certificate or as individual
  21. /// parameters.
  22. /// </summary>
  23. public class TrustAnchor
  24. {
  25. private readonly AsymmetricKeyParameter pubKey;
  26. private readonly string caName;
  27. private readonly X509Name caPrincipal;
  28. private readonly X509Certificate trustedCert;
  29. private byte[] ncBytes;
  30. private NameConstraints nc;
  31. /// <summary>
  32. /// Creates an instance of TrustAnchor with the specified X509Certificate and
  33. /// optional name constraints, which are intended to be used as additional
  34. /// constraints when validating an X.509 certification path.
  35. /// The name constraints are specified as a byte array. This byte array
  36. /// should contain the DER encoded form of the name constraints, as they
  37. /// would appear in the NameConstraints structure defined in RFC 2459 and
  38. /// X.509. The ASN.1 definition of this structure appears below.
  39. ///
  40. /// <pre>
  41. /// NameConstraints ::= SEQUENCE {
  42. /// permittedSubtrees [0] GeneralSubtrees OPTIONAL,
  43. /// excludedSubtrees [1] GeneralSubtrees OPTIONAL }
  44. ///
  45. /// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
  46. ///
  47. /// GeneralSubtree ::= SEQUENCE {
  48. /// base GeneralName,
  49. /// minimum [0] BaseDistance DEFAULT 0,
  50. /// maximum [1] BaseDistance OPTIONAL }
  51. ///
  52. /// BaseDistance ::= INTEGER (0..MAX)
  53. ///
  54. /// GeneralName ::= CHOICE {
  55. /// otherName [0] OtherName,
  56. /// rfc822Name [1] IA5String,
  57. /// dNSName [2] IA5String,
  58. /// x400Address [3] ORAddress,
  59. /// directoryName [4] Name,
  60. /// ediPartyName [5] EDIPartyName,
  61. /// uniformResourceIdentifier [6] IA5String,
  62. /// iPAddress [7] OCTET STRING,
  63. /// registeredID [8] OBJECT IDENTIFIER}
  64. /// </pre>
  65. ///
  66. /// Note that the name constraints byte array supplied is cloned to protect
  67. /// against subsequent modifications.
  68. /// </summary>
  69. /// <param name="trustedCert">a trusted X509Certificate</param>
  70. /// <param name="nameConstraints">a byte array containing the ASN.1 DER encoding of a
  71. /// NameConstraints extension to be used for checking name
  72. /// constraints. Only the value of the extension is included, not
  73. /// the OID or criticality flag. Specify null to omit the
  74. /// parameter.</param>
  75. /// <exception cref="ArgumentNullException">if the specified X509Certificate is null</exception>
  76. public TrustAnchor(
  77. X509Certificate trustedCert,
  78. byte[] nameConstraints)
  79. {
  80. if (trustedCert == null)
  81. throw new ArgumentNullException("trustedCert");
  82. this.trustedCert = trustedCert;
  83. this.pubKey = null;
  84. this.caName = null;
  85. this.caPrincipal = null;
  86. setNameConstraints(nameConstraints);
  87. }
  88. /// <summary>
  89. /// Creates an instance of <c>TrustAnchor</c> where the
  90. /// most-trusted CA is specified as an X500Principal and public key.
  91. /// </summary>
  92. /// <remarks>
  93. /// <p>
  94. /// Name constraints are an optional parameter, and are intended to be used
  95. /// as additional constraints when validating an X.509 certification path.
  96. /// </p><p>
  97. /// The name constraints are specified as a byte array. This byte array
  98. /// contains the DER encoded form of the name constraints, as they
  99. /// would appear in the NameConstraints structure defined in RFC 2459
  100. /// and X.509. The ASN.1 notation for this structure is supplied in the
  101. /// documentation for the other constructors.
  102. /// </p><p>
  103. /// Note that the name constraints byte array supplied here is cloned to
  104. /// protect against subsequent modifications.
  105. /// </p>
  106. /// </remarks>
  107. /// <param name="caPrincipal">the name of the most-trusted CA as X509Name</param>
  108. /// <param name="pubKey">the public key of the most-trusted CA</param>
  109. /// <param name="nameConstraints">
  110. /// a byte array containing the ASN.1 DER encoding of a NameConstraints extension to
  111. /// be used for checking name constraints. Only the value of the extension is included,
  112. /// not the OID or criticality flag. Specify <c>null</c> to omit the parameter.
  113. /// </param>
  114. /// <exception cref="ArgumentNullException">
  115. /// if <c>caPrincipal</c> or <c>pubKey</c> is null
  116. /// </exception>
  117. public TrustAnchor(
  118. X509Name caPrincipal,
  119. AsymmetricKeyParameter pubKey,
  120. byte[] nameConstraints)
  121. {
  122. if (caPrincipal == null)
  123. throw new ArgumentNullException("caPrincipal");
  124. if (pubKey == null)
  125. throw new ArgumentNullException("pubKey");
  126. this.trustedCert = null;
  127. this.caPrincipal = caPrincipal;
  128. this.caName = caPrincipal.ToString();
  129. this.pubKey = pubKey;
  130. setNameConstraints(nameConstraints);
  131. }
  132. /// <summary>
  133. /// Creates an instance of <code>TrustAnchor</code> where the most-trusted
  134. /// CA is specified as a distinguished name and public key. Name constraints
  135. /// are an optional parameter, and are intended to be used as additional
  136. /// constraints when validating an X.509 certification path.
  137. /// <br/>
  138. /// The name constraints are specified as a byte array. This byte array
  139. /// contains the DER encoded form of the name constraints, as they would
  140. /// appear in the NameConstraints structure defined in RFC 2459 and X.509.
  141. /// </summary>
  142. /// <param name="caName">the X.500 distinguished name of the most-trusted CA in RFC
  143. /// 2253 string format</param>
  144. /// <param name="pubKey">the public key of the most-trusted CA</param>
  145. /// <param name="nameConstraints">a byte array containing the ASN.1 DER encoding of a
  146. /// NameConstraints extension to be used for checking name
  147. /// constraints. Only the value of the extension is included, not
  148. /// the OID or criticality flag. Specify null to omit the
  149. /// parameter.</param>
  150. /// throws NullPointerException, IllegalArgumentException
  151. public TrustAnchor(
  152. string caName,
  153. AsymmetricKeyParameter pubKey,
  154. byte[] nameConstraints)
  155. {
  156. if (caName == null)
  157. throw new ArgumentNullException("caName");
  158. if (pubKey == null)
  159. throw new ArgumentNullException("pubKey");
  160. if (caName.Length == 0)
  161. throw new ArgumentException("caName can not be an empty string");
  162. this.caPrincipal = new X509Name(caName);
  163. this.pubKey = pubKey;
  164. this.caName = caName;
  165. this.trustedCert = null;
  166. setNameConstraints(nameConstraints);
  167. }
  168. /// <summary>
  169. /// Returns the most-trusted CA certificate.
  170. /// </summary>
  171. public X509Certificate TrustedCert
  172. {
  173. get { return this.trustedCert; }
  174. }
  175. /// <summary>
  176. /// Returns the name of the most-trusted CA as an X509Name.
  177. /// </summary>
  178. public X509Name CA
  179. {
  180. get { return this.caPrincipal; }
  181. }
  182. /// <summary>
  183. /// Returns the name of the most-trusted CA in RFC 2253 string format.
  184. /// </summary>
  185. public string CAName
  186. {
  187. get { return this.caName; }
  188. }
  189. /// <summary>
  190. /// Returns the public key of the most-trusted CA.
  191. /// </summary>
  192. public AsymmetricKeyParameter CAPublicKey
  193. {
  194. get { return this.pubKey; }
  195. }
  196. /// <summary>
  197. /// Decode the name constraints and clone them if not null.
  198. /// </summary>
  199. private void setNameConstraints(
  200. byte[] bytes)
  201. {
  202. if (bytes == null)
  203. {
  204. ncBytes = null;
  205. nc = null;
  206. }
  207. else
  208. {
  209. ncBytes = (byte[]) bytes.Clone();
  210. // validate DER encoding
  211. //nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
  212. nc = NameConstraints.GetInstance(Asn1Object.FromByteArray(bytes));
  213. }
  214. }
  215. public byte[] GetNameConstraints
  216. {
  217. get { return Arrays.Clone(ncBytes); }
  218. }
  219. /// <summary>
  220. /// Returns a formatted string describing the <code>TrustAnchor</code>.
  221. /// </summary>
  222. /// <returns>a formatted string describing the <code>TrustAnchor</code></returns>
  223. public override string ToString()
  224. {
  225. // TODO Some of the sub-objects might not implement ToString() properly
  226. string nl = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.NewLine;
  227. StringBuilder sb = new StringBuilder();
  228. sb.Append("[");
  229. sb.Append(nl);
  230. if (this.pubKey != null)
  231. {
  232. sb.Append(" Trusted CA Public Key: ").Append(this.pubKey).Append(nl);
  233. sb.Append(" Trusted CA Issuer Name: ").Append(this.caName).Append(nl);
  234. }
  235. else
  236. {
  237. sb.Append(" Trusted CA cert: ").Append(this.TrustedCert).Append(nl);
  238. }
  239. if (nc != null)
  240. {
  241. sb.Append(" Name Constraints: ").Append(nc).Append(nl);
  242. }
  243. return sb.ToString();
  244. }
  245. }
  246. }
  247. #pragma warning restore
  248. #endif