1 /*
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.security.cert;
27
28 import java.io.IOException;
29 import java.security.PublicKey;
30
31 import javax.security.auth.x500.X500Principal;
32
33 import sun.security.x509.NameConstraintsExtension;
34 import sun.security.x509.X500Name;
35
36 /**
37 * A trust anchor or most-trusted Certification Authority (CA).
38 * <p>
39 * This class represents a "most-trusted CA", which is used as a trust anchor
40 * for validating X.509 certification paths. A most-trusted CA includes the
41 * public key of the CA, the CA's name, and any constraints upon the set of
42 * paths which may be validated using this key. These parameters can be
43 * specified in the form of a trusted {@code X509Certificate} or as
44 * individual parameters.
45 * <p>
46 * <b>Concurrent Access</b>
47 * <p>All {@code TrustAnchor} objects must be immutable and
48 * thread-safe. That is, multiple threads may concurrently invoke the
49 * methods defined in this class on a single {@code TrustAnchor}
50 * object (or more than one) with no ill effects. Requiring
51 * {@code TrustAnchor} objects to be immutable and thread-safe
52 * allows them to be passed around to various pieces of code without
53 * worrying about coordinating access. This stipulation applies to all
54 * public fields and methods of this class and any added or overridden
55 * by subclasses.
56 *
57 * @see PKIXParameters#PKIXParameters(Set)
58 * @see PKIXBuilderParameters#PKIXBuilderParameters(Set, CertSelector)
59 *
60 * @since 1.4
61 * @author Sean Mullan
62 */
63 public class TrustAnchor {
64
65 private final PublicKey pubKey;
66 private final String caName;
67 private final X500Principal caPrincipal;
68 private final X509Certificate trustedCert;
69 private byte[] ncBytes;
70 private NameConstraintsExtension nc;
71
72 /**
73 * Creates an instance of {@code TrustAnchor} with the specified
74 * {@code X509Certificate} and optional name constraints, which
75 * are intended to be used as additional constraints when validating
76 * an X.509 certification path.
77 * <p>
78 * The name constraints are specified as a byte array. This byte array
79 * should contain the DER encoded form of the name constraints, as they
80 * would appear in the NameConstraints structure defined in
81 * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280</a>
82 * and X.509. The ASN.1 definition of this structure appears below.
83 *
84 * <pre>{@code
85 * NameConstraints ::= SEQUENCE {
86 * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
87 * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
88 *
89 * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
90 *
91 * GeneralSubtree ::= SEQUENCE {
92 * base GeneralName,
93 * minimum [0] BaseDistance DEFAULT 0,
94 * maximum [1] BaseDistance OPTIONAL }
95 *
96 * BaseDistance ::= INTEGER (0..MAX)
97 *
98 * GeneralName ::= CHOICE {
99 * otherName [0] OtherName,
100 * rfc822Name [1] IA5String,
101 * dNSName [2] IA5String,
102 * x400Address [3] ORAddress,
103 * directoryName [4] Name,
104 * ediPartyName [5] EDIPartyName,
105 * uniformResourceIdentifier [6] IA5String,
106 * iPAddress [7] OCTET STRING,
107 * registeredID [8] OBJECT IDENTIFIER}
108 * }</pre>
109 * <p>
110 * Note that the name constraints byte array supplied is cloned to protect
111 * against subsequent modifications.
112 *
113 * @param trustedCert a trusted {@code X509Certificate}
114 * @param nameConstraints a byte array containing the ASN.1 DER encoding of
115 * a NameConstraints extension to be used for checking name constraints.
116 * Only the value of the extension is included, not the OID or criticality
117 * flag. Specify {@code null} to omit the parameter.
118 * @throws IllegalArgumentException if the name constraints cannot be
119 * decoded
120 * @throws NullPointerException if the specified
121 * {@code X509Certificate} is {@code null}
122 */
123 public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
124 {
125 if (trustedCert == null)
126 throw new NullPointerException("the trustedCert parameter must " +
127 "be non-null");
128 this.trustedCert = trustedCert;
129 this.pubKey = null;
130 this.caName = null;
131 this.caPrincipal = null;
132 setNameConstraints(nameConstraints);
133 }
134
135 /**
136 * Creates an instance of {@code TrustAnchor} where the
137 * most-trusted CA is specified as an X500Principal and public key.
138 * Name constraints are an optional parameter, and are intended to be used
139 * as additional constraints when validating an X.509 certification path.
140 * <p>
141 * The name constraints are specified as a byte array. This byte array
142 * contains the DER encoded form of the name constraints, as they
143 * would appear in the NameConstraints structure defined in RFC 5280
144 * and X.509. The ASN.1 notation for this structure is supplied in the
145 * documentation for
146 * {@link #TrustAnchor(X509Certificate, byte[])
147 * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
148 * <p>
149 * Note that the name constraints byte array supplied here is cloned to
150 * protect against subsequent modifications.
151 *
152 * @param caPrincipal the name of the most-trusted CA as X500Principal
153 * @param pubKey the public key of the most-trusted CA
154 * @param nameConstraints a byte array containing the ASN.1 DER encoding of
155 * a NameConstraints extension to be used for checking name constraints.
156 * Only the value of the extension is included, not the OID or criticality
157 * flag. Specify {@code null} to omit the parameter.
158 * @throws NullPointerException if the specified {@code caPrincipal} or
159 * {@code pubKey} parameter is {@code null}
160 * @since 1.5
161 */
162 public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey,
163 byte[] nameConstraints) {
164 if ((caPrincipal == null) || (pubKey == null)) {
165 throw new NullPointerException();
166 }
167 this.trustedCert = null;
168 this.caPrincipal = caPrincipal;
169 this.caName = caPrincipal.getName();
170 this.pubKey = pubKey;
171 setNameConstraints(nameConstraints);
172 }
173
174 /**
175 * Creates an instance of {@code TrustAnchor} where the
176 * most-trusted CA is specified as a distinguished name and public key.
177 * Name constraints are an optional parameter, and are intended to be used
178 * as additional constraints when validating an X.509 certification path.
179 * <p>
180 * The name constraints are specified as a byte array. This byte array
181 * contains the DER encoded form of the name constraints, as they
182 * would appear in the NameConstraints structure defined in RFC 5280
183 * and X.509. The ASN.1 notation for this structure is supplied in the
184 * documentation for
185 * {@link #TrustAnchor(X509Certificate, byte[])
186 * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
187 * <p>
188 * Note that the name constraints byte array supplied here is cloned to
189 * protect against subsequent modifications.
190 *
191 * @param caName the X.500 distinguished name of the most-trusted CA in
192 * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
193 * {@code String} format
194 * @param pubKey the public key of the most-trusted CA
195 * @param nameConstraints a byte array containing the ASN.1 DER encoding of
196 * a NameConstraints extension to be used for checking name constraints.
197 * Only the value of the extension is included, not the OID or criticality
198 * flag. Specify {@code null} to omit the parameter.
199 * @throws IllegalArgumentException if the specified
200 * {@code caName} parameter is empty {@code (caName.length() == 0)}
201 * or incorrectly formatted or the name constraints cannot be decoded
202 * @throws NullPointerException if the specified {@code caName} or
203 * {@code pubKey} parameter is {@code null}
204 */
205 public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)
206 {
207 if (pubKey == null)
208 throw new NullPointerException("the pubKey parameter must be " +
209 "non-null");
210 if (caName == null)
211 throw new NullPointerException("the caName parameter must be " +
212 "non-null");
213 if (caName.isEmpty())
214 throw new IllegalArgumentException("the caName " +
215 "parameter must be a non-empty String");
216 // check if caName is formatted correctly
217 this.caPrincipal = new X500Principal(caName);
218 this.pubKey = pubKey;
219 this.caName = caName;
220 this.trustedCert = null;
221 setNameConstraints(nameConstraints);
222 }
223
224 /**
225 * Returns the most-trusted CA certificate.
226 *
227 * @return a trusted {@code X509Certificate} or {@code null}
228 * if the trust anchor was not specified as a trusted certificate
229 */
230 public final X509Certificate getTrustedCert() {
231 return this.trustedCert;
232 }
233
234 /**
235 * Returns the name of the most-trusted CA as an X500Principal.
236 *
237 * @return the X.500 distinguished name of the most-trusted CA, or
238 * {@code null} if the trust anchor was not specified as a trusted
239 * public key and name or X500Principal pair
240 * @since 1.5
241 */
242 public final X500Principal getCA() {
243 return this.caPrincipal;
244 }
245
246 /**
247 * Returns the name of the most-trusted CA in RFC 2253 {@code String}
248 * format.
249 *
250 * @return the X.500 distinguished name of the most-trusted CA, or
251 * {@code null} if the trust anchor was not specified as a trusted
252 * public key and name or X500Principal pair
253 */
254 public final String getCAName() {
255 return this.caName;
256 }
257
258 /**
259 * Returns the public key of the most-trusted CA.
260 *
261 * @return the public key of the most-trusted CA, or {@code null}
262 * if the trust anchor was not specified as a trusted public key and name
263 * or X500Principal pair
264 */
265 public final PublicKey getCAPublicKey() {
266 return this.pubKey;
267 }
268
269 /**
270 * Decode the name constraints and clone them if not null.
271 */
272 private void setNameConstraints(byte[] bytes) {
273 if (bytes == null) {
274 ncBytes = null;
275 nc = null;
276 } else {
277 ncBytes = bytes.clone();
278 // validate DER encoding
279 try {
280 nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
281 } catch (IOException ioe) {
282 IllegalArgumentException iae =
283 new IllegalArgumentException(ioe.getMessage());
284 iae.initCause(ioe);
285 throw iae;
286 }
287 }
288 }
289
290 /**
291 * Returns the name constraints parameter. The specified name constraints
292 * are associated with this trust anchor and are intended to be used
293 * as additional constraints when validating an X.509 certification path.
294 * <p>
295 * The name constraints are returned as a byte array. This byte array
296 * contains the DER encoded form of the name constraints, as they
297 * would appear in the NameConstraints structure defined in RFC 5280
298 * and X.509. The ASN.1 notation for this structure is supplied in the
299 * documentation for
300 * {@link #TrustAnchor(X509Certificate, byte[])
301 * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
302 * <p>
303 * Note that the byte array returned is cloned to protect against
304 * subsequent modifications.
305 *
306 * @return a byte array containing the ASN.1 DER encoding of
307 * a NameConstraints extension used for checking name constraints,
308 * or {@code null} if not set.
309 */
310 public final byte [] getNameConstraints() {
311 return ncBytes == null ? null : ncBytes.clone();
312 }
313
314 /**
315 * Returns a formatted string describing the {@code TrustAnchor}.
316 *
317 * @return a formatted string describing the {@code TrustAnchor}
318 */
319 public String toString() {
320 StringBuilder sb = new StringBuilder();
321 sb.append("[\n");
322 if (pubKey != null) {
323 sb.append(" Trusted CA Public Key: " + pubKey.toString() + "\n");
324 sb.append(" Trusted CA Issuer Name: "
325 + String.valueOf(caName) + "\n");
326 } else {
327 sb.append(" Trusted CA cert: " + trustedCert.toString() + "\n");
328 }
329 if (nc != null)
330 sb.append(" Name Constraints: " + nc.toString() + "\n");
331 return sb.toString();
332 }
333 }
334