1. /*
  2. * @(#)TrustAnchor.java 1.10 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.security.cert;
  8. import java.io.IOException;
  9. import java.security.PublicKey;
  10. import javax.security.auth.x500.X500Principal;
  11. import sun.security.x509.NameConstraintsExtension;
  12. import sun.security.x509.X500Name;
  13. /**
  14. * A trust anchor or most-trusted Certification Authority (CA).
  15. * <p>
  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 <code>X509Certificate</code> or as
  21. * individual parameters.
  22. * <p>
  23. * <b>Concurrent Access</b>
  24. * <p>
  25. * <p>All <code>TrustAnchor</code> objects must be immutable and
  26. * thread-safe. That is, multiple threads may concurrently invoke the
  27. * methods defined in this class on a single <code>TrustAnchor</code>
  28. * object (or more than one) with no ill effects. Requiring
  29. * <code>TrustAnchor</code> objects to be immutable and thread-safe
  30. * allows them to be passed around to various pieces of code without
  31. * worrying about coordinating access. This stipulation applies to all
  32. * public fields and methods of this class and any added or overridden
  33. * by subclasses.
  34. *
  35. * @see PKIXParameters#PKIXParameters(Set)
  36. * @see PKIXBuilderParameters#PKIXBuilderParameters(Set, CertSelector)
  37. *
  38. * @version 1.10 12/19/03
  39. * @since 1.4
  40. * @author Sean Mullan
  41. */
  42. public class TrustAnchor {
  43. static {
  44. CertPathHelperImpl.initialize();
  45. }
  46. private final PublicKey pubKey;
  47. private final String caName;
  48. private final X500Principal caPrincipal;
  49. private final X509Certificate trustedCert;
  50. private byte[] ncBytes;
  51. private NameConstraintsExtension nc;
  52. /**
  53. * Creates an instance of <code>TrustAnchor</code> with the specified
  54. * <code>X509Certificate</code> and optional name constraints, which
  55. * are intended to be used as additional constraints when validating
  56. * an X.509 certification path.
  57. * <p>
  58. * The name constraints are specified as a byte array. This byte array
  59. * should contain the DER encoded form of the name constraints, as they
  60. * would appear in the NameConstraints structure defined in RFC 2459
  61. * and X.509. The ASN.1 definition of this structure appears below.
  62. *
  63. * <pre><code>
  64. * NameConstraints ::= SEQUENCE {
  65. * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
  66. * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
  67. *
  68. * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
  69. *
  70. * GeneralSubtree ::= SEQUENCE {
  71. * base GeneralName,
  72. * minimum [0] BaseDistance DEFAULT 0,
  73. * maximum [1] BaseDistance OPTIONAL }
  74. *
  75. * BaseDistance ::= INTEGER (0..MAX)
  76. *
  77. * GeneralName ::= CHOICE {
  78. * otherName [0] OtherName,
  79. * rfc822Name [1] IA5String,
  80. * dNSName [2] IA5String,
  81. * x400Address [3] ORAddress,
  82. * directoryName [4] Name,
  83. * ediPartyName [5] EDIPartyName,
  84. * uniformResourceIdentifier [6] IA5String,
  85. * iPAddress [7] OCTET STRING,
  86. * registeredID [8] OBJECT IDENTIFIER}
  87. * </code></pre>
  88. * <p>
  89. * Note that the name constraints byte array supplied is cloned to protect
  90. * against subsequent modifications.
  91. *
  92. * @param trustedCert a trusted <code>X509Certificate</code>
  93. * @param nameConstraints a byte array containing the ASN.1 DER encoding of
  94. * a NameConstraints extension to be used for checking name constraints.
  95. * Only the value of the extension is included, not the OID or criticality
  96. * flag. Specify <code>null</code> to omit the parameter.
  97. * @throws IllegalArgumentException if the name constraints cannot be
  98. * decoded
  99. * @throws NullPointerException if the specified
  100. * <code>X509Certificate</code> is <code>null</code>
  101. */
  102. public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
  103. {
  104. if (trustedCert == null)
  105. throw new NullPointerException("the trustedCert parameter must " +
  106. "be non-null");
  107. this.trustedCert = trustedCert;
  108. this.pubKey = null;
  109. this.caName = null;
  110. this.caPrincipal = null;
  111. setNameConstraints(nameConstraints);
  112. }
  113. /**
  114. * Creates an instance of <code>TrustAnchor</code> where the
  115. * most-trusted CA is specified as an X500Principal and public key.
  116. * Name constraints are an optional parameter, and are intended to be used
  117. * as additional constraints when validating an X.509 certification path.
  118. * <p>
  119. * The name constraints are specified as a byte array. This byte array
  120. * contains the DER encoded form of the name constraints, as they
  121. * would appear in the NameConstraints structure defined in RFC 2459
  122. * and X.509. The ASN.1 notation for this structure is supplied in the
  123. * documentation for
  124. * {@link #TrustAnchor(X509Certificate, byte[])
  125. * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
  126. * <p>
  127. * Note that the name constraints byte array supplied here is cloned to
  128. * protect against subsequent modifications.
  129. *
  130. * @param caPrincipal the name of the most-trusted CA as X500Principal
  131. * @param pubKey the public key of the most-trusted CA
  132. * @param nameConstraints a byte array containing the ASN.1 DER encoding of
  133. * a NameConstraints extension to be used for checking name constraints.
  134. * Only the value of the extension is included, not the OID or criticality
  135. * flag. Specify <code>null</code> to omit the parameter.
  136. * @throws NullPointerException if the specified <code>caPrincipal</code> or
  137. * <code>pubKey</code> parameter is <code>null</code>
  138. * @since 1.5
  139. */
  140. public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey,
  141. byte[] nameConstraints) {
  142. if ((caPrincipal == null) || (pubKey == null)) {
  143. throw new NullPointerException();
  144. }
  145. this.trustedCert = null;
  146. this.caPrincipal = caPrincipal;
  147. this.caName = caPrincipal.getName();
  148. this.pubKey = pubKey;
  149. setNameConstraints(nameConstraints);
  150. }
  151. /**
  152. * Creates an instance of <code>TrustAnchor</code> where the
  153. * most-trusted CA is specified as a distinguished name and public key.
  154. * Name constraints are an optional parameter, and are intended to be used
  155. * as additional constraints when validating an X.509 certification path.
  156. * <p>
  157. * The name constraints are specified as a byte array. This byte array
  158. * contains the DER encoded form of the name constraints, as they
  159. * would appear in the NameConstraints structure defined in RFC 2459
  160. * and X.509. The ASN.1 notation for this structure is supplied in the
  161. * documentation for
  162. * {@link #TrustAnchor(X509Certificate, byte[])
  163. * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
  164. * <p>
  165. * Note that the name constraints byte array supplied here is cloned to
  166. * protect against subsequent modifications.
  167. *
  168. * @param caName the X.500 distinguished name of the most-trusted CA in
  169. * RFC 2253 <code>String</code> format
  170. * @param pubKey the public key of the most-trusted CA
  171. * @param nameConstraints a byte array containing the ASN.1 DER encoding of
  172. * a NameConstraints extension to be used for checking name constraints.
  173. * Only the value of the extension is included, not the OID or criticality
  174. * flag. Specify <code>null</code> to omit the parameter.
  175. * @throws IllegalArgumentException if the specified <code>
  176. * caName</code> parameter is empty <code>(caName.length() == 0)</code>
  177. * or incorrectly formatted or the name constraints cannot be decoded
  178. * @throws NullPointerException if the specified <code>caName</code> or
  179. * <code>pubKey</code> parameter is <code>null</code>
  180. */
  181. public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)
  182. {
  183. if (pubKey == null)
  184. throw new NullPointerException("the pubKey parameter must be " +
  185. "non-null");
  186. if (caName == null)
  187. throw new NullPointerException("the caName parameter must be " +
  188. "non-null");
  189. if (caName.length() == 0)
  190. throw new IllegalArgumentException("the caName " +
  191. "parameter must be a non-empty String");
  192. // check if caName is formatted correctly
  193. this.caPrincipal = new X500Principal(caName);
  194. this.pubKey = pubKey;
  195. this.caName = caName;
  196. this.trustedCert = null;
  197. setNameConstraints(nameConstraints);
  198. }
  199. /**
  200. * Returns the most-trusted CA certificate.
  201. *
  202. * @return a trusted <code>X509Certificate</code> or <code>null</code>
  203. * if the trust anchor was not specified as a trusted certificate
  204. */
  205. public final X509Certificate getTrustedCert() {
  206. return this.trustedCert;
  207. }
  208. /**
  209. * Returns the name of the most-trusted CA as an X500Principal.
  210. *
  211. * @return the X.500 distinguished name of the most-trusted CA, or
  212. * <code>null</code> if the trust anchor was not specified as a trusted
  213. * public key and name or X500Principal pair
  214. * @since 1.5
  215. */
  216. public final X500Principal getCA() {
  217. return this.caPrincipal;
  218. }
  219. /**
  220. * Returns the name of the most-trusted CA in RFC 2253 <code>String</code>
  221. * format.
  222. *
  223. * @return the X.500 distinguished name of the most-trusted CA, or
  224. * <code>null</code> if the trust anchor was not specified as a trusted
  225. * public key and name or X500Principal pair
  226. */
  227. public final String getCAName() {
  228. return this.caName;
  229. }
  230. /**
  231. * Returns the public key of the most-trusted CA.
  232. *
  233. * @return the public key of the most-trusted CA, or <code>null</code>
  234. * if the trust anchor was not specified as a trusted public key and name
  235. * or X500Principal pair
  236. */
  237. public final PublicKey getCAPublicKey() {
  238. return this.pubKey;
  239. }
  240. /**
  241. * Decode the name constraints and clone them if not null.
  242. */
  243. private void setNameConstraints(byte[] bytes) {
  244. if (bytes == null) {
  245. ncBytes = null;
  246. nc = null;
  247. } else {
  248. ncBytes = (byte []) bytes.clone();
  249. // validate DER encoding
  250. try {
  251. nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
  252. } catch (IOException ioe) {
  253. IllegalArgumentException iae =
  254. new IllegalArgumentException(ioe.getMessage());
  255. iae.initCause(ioe);
  256. throw iae;
  257. }
  258. }
  259. }
  260. /**
  261. * Returns the name constraints parameter. The specified name constraints
  262. * are associated with this trust anchor and are intended to be used
  263. * as additional constraints when validating an X.509 certification path.
  264. * <p>
  265. * The name constraints are returned as a byte array. This byte array
  266. * contains the DER encoded form of the name constraints, as they
  267. * would appear in the NameConstraints structure defined in RFC 2459
  268. * and X.509. The ASN.1 notation for this structure is supplied in the
  269. * documentation for
  270. * {@link #TrustAnchor(X509Certificate, byte[])
  271. * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
  272. * <p>
  273. * Note that the byte array returned is cloned to protect against
  274. * subsequent modifications.
  275. *
  276. * @return a byte array containing the ASN.1 DER encoding of
  277. * a NameConstraints extension used for checking name constraints,
  278. * or <code>null</code> if not set.
  279. */
  280. public final byte [] getNameConstraints() {
  281. return (ncBytes == null ? null : (byte []) ncBytes.clone());
  282. }
  283. /**
  284. * Returns a formatted string describing the <code>TrustAnchor</code>.
  285. *
  286. * @return a formatted string describing the <code>TrustAnchor</code>
  287. */
  288. public String toString() {
  289. StringBuffer sb = new StringBuffer();
  290. sb.append("[\n");
  291. if (pubKey != null) {
  292. sb.append(" Trusted CA Public Key: " + pubKey.toString() + "\n");
  293. sb.append(" Trusted CA Issuer Name: "
  294. + String.valueOf(caName) + "\n");
  295. } else {
  296. sb.append(" Trusted CA cert: " + trustedCert.toString() + "\n");
  297. }
  298. if (nc != null)
  299. sb.append(" Name Constraints: " + nc.toString() + "\n");
  300. return sb.toString();
  301. }
  302. }