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