001 /*
002 * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.security.cert;
027
028 import java.io.IOException;
029 import java.security.PublicKey;
030
031 import javax.security.auth.x500.X500Principal;
032
033 import sun.security.x509.NameConstraintsExtension;
034 import sun.security.x509.X500Name;
035
036 /**
037 * A trust anchor or most-trusted Certification Authority (CA).
038 * <p>
039 * This class represents a "most-trusted CA", which is used as a trust anchor
040 * for validating X.509 certification paths. A most-trusted CA includes the
041 * public key of the CA, the CA's name, and any constraints upon the set of
042 * paths which may be validated using this key. These parameters can be
043 * specified in the form of a trusted <code>X509Certificate</code> or as
044 * individual parameters.
045 * <p>
046 * <b>Concurrent Access</b>
047 * <p>
048 * <p>All <code>TrustAnchor</code> objects must be immutable and
049 * thread-safe. That is, multiple threads may concurrently invoke the
050 * methods defined in this class on a single <code>TrustAnchor</code>
051 * object (or more than one) with no ill effects. Requiring
052 * <code>TrustAnchor</code> objects to be immutable and thread-safe
053 * allows them to be passed around to various pieces of code without
054 * worrying about coordinating access. This stipulation applies to all
055 * public fields and methods of this class and any added or overridden
056 * by subclasses.
057 *
058 * @see PKIXParameters#PKIXParameters(Set)
059 * @see PKIXBuilderParameters#PKIXBuilderParameters(Set, CertSelector)
060 *
061 * @version 1.19 05/05/07
062 * @since 1.4
063 * @author Sean Mullan
064 */
065 public class TrustAnchor {
066
067 private final PublicKey pubKey;
068 private final String caName;
069 private final X500Principal caPrincipal;
070 private final X509Certificate trustedCert;
071 private byte[] ncBytes;
072 private NameConstraintsExtension nc;
073
074 /**
075 * Creates an instance of <code>TrustAnchor</code> with the specified
076 * <code>X509Certificate</code> and optional name constraints, which
077 * are intended to be used as additional constraints when validating
078 * an X.509 certification path.
079 * <p>
080 * The name constraints are specified as a byte array. This byte array
081 * should contain the DER encoded form of the name constraints, as they
082 * would appear in the NameConstraints structure defined in
083 * <a href="http://www.ietf.org/rfc/rfc3280">RFC 3280</a>
084 * and X.509. The ASN.1 definition of this structure appears below.
085 *
086 * <pre><code>
087 * NameConstraints ::= SEQUENCE {
088 * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
089 * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
090 *
091 * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
092 *
093 * GeneralSubtree ::= SEQUENCE {
094 * base GeneralName,
095 * minimum [0] BaseDistance DEFAULT 0,
096 * maximum [1] BaseDistance OPTIONAL }
097 *
098 * BaseDistance ::= INTEGER (0..MAX)
099 *
100 * GeneralName ::= CHOICE {
101 * otherName [0] OtherName,
102 * rfc822Name [1] IA5String,
103 * dNSName [2] IA5String,
104 * x400Address [3] ORAddress,
105 * directoryName [4] Name,
106 * ediPartyName [5] EDIPartyName,
107 * uniformResourceIdentifier [6] IA5String,
108 * iPAddress [7] OCTET STRING,
109 * registeredID [8] OBJECT IDENTIFIER}
110 * </code></pre>
111 * <p>
112 * Note that the name constraints byte array supplied is cloned to protect
113 * against subsequent modifications.
114 *
115 * @param trustedCert a trusted <code>X509Certificate</code>
116 * @param nameConstraints a byte array containing the ASN.1 DER encoding of
117 * a NameConstraints extension to be used for checking name constraints.
118 * Only the value of the extension is included, not the OID or criticality
119 * flag. Specify <code>null</code> to omit the parameter.
120 * @throws IllegalArgumentException if the name constraints cannot be
121 * decoded
122 * @throws NullPointerException if the specified
123 * <code>X509Certificate</code> is <code>null</code>
124 */
125 public TrustAnchor(X509Certificate trustedCert,
126 byte[] nameConstraints) {
127 if (trustedCert == null)
128 throw new NullPointerException(
129 "the trustedCert parameter must " + "be non-null");
130 this .trustedCert = trustedCert;
131 this .pubKey = null;
132 this .caName = null;
133 this .caPrincipal = null;
134 setNameConstraints(nameConstraints);
135 }
136
137 /**
138 * Creates an instance of <code>TrustAnchor</code> where the
139 * most-trusted CA is specified as an X500Principal and public key.
140 * Name constraints are an optional parameter, and are intended to be used
141 * as additional constraints when validating an X.509 certification path.
142 * <p>
143 * The name constraints are specified as a byte array. This byte array
144 * contains the DER encoded form of the name constraints, as they
145 * would appear in the NameConstraints structure defined in RFC 3280
146 * and X.509. The ASN.1 notation for this structure is supplied in the
147 * documentation for
148 * {@link #TrustAnchor(X509Certificate, byte[])
149 * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
150 * <p>
151 * Note that the name constraints byte array supplied here is cloned to
152 * protect against subsequent modifications.
153 *
154 * @param caPrincipal the name of the most-trusted CA as X500Principal
155 * @param pubKey the public key of the most-trusted CA
156 * @param nameConstraints a byte array containing the ASN.1 DER encoding of
157 * a NameConstraints extension to be used for checking name constraints.
158 * Only the value of the extension is included, not the OID or criticality
159 * flag. Specify <code>null</code> to omit the parameter.
160 * @throws NullPointerException if the specified <code>caPrincipal</code> or
161 * <code>pubKey</code> parameter is <code>null</code>
162 * @since 1.5
163 */
164 public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey,
165 byte[] nameConstraints) {
166 if ((caPrincipal == null) || (pubKey == null)) {
167 throw new NullPointerException();
168 }
169 this .trustedCert = null;
170 this .caPrincipal = caPrincipal;
171 this .caName = caPrincipal.getName();
172 this .pubKey = pubKey;
173 setNameConstraints(nameConstraints);
174 }
175
176 /**
177 * Creates an instance of <code>TrustAnchor</code> where the
178 * most-trusted CA is specified as a distinguished name and public key.
179 * Name constraints are an optional parameter, and are intended to be used
180 * as additional constraints when validating an X.509 certification path.
181 * <p>
182 * The name constraints are specified as a byte array. This byte array
183 * contains the DER encoded form of the name constraints, as they
184 * would appear in the NameConstraints structure defined in RFC 3280
185 * and X.509. The ASN.1 notation for this structure is supplied in the
186 * documentation for
187 * {@link #TrustAnchor(X509Certificate, byte[])
188 * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
189 * <p>
190 * Note that the name constraints byte array supplied here is cloned to
191 * protect against subsequent modifications.
192 *
193 * @param caName the X.500 distinguished name of the most-trusted CA in
194 * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
195 * <code>String</code> format
196 * @param pubKey the public key of the most-trusted CA
197 * @param nameConstraints a byte array containing the ASN.1 DER encoding of
198 * a NameConstraints extension to be used for checking name constraints.
199 * Only the value of the extension is included, not the OID or criticality
200 * flag. Specify <code>null</code> to omit the parameter.
201 * @throws IllegalArgumentException if the specified <code>
202 * caName</code> parameter is empty <code>(caName.length() == 0)</code>
203 * or incorrectly formatted or the name constraints cannot be decoded
204 * @throws NullPointerException if the specified <code>caName</code> or
205 * <code>pubKey</code> parameter is <code>null</code>
206 */
207 public TrustAnchor(String caName, PublicKey pubKey,
208 byte[] nameConstraints) {
209 if (pubKey == null)
210 throw new NullPointerException(
211 "the pubKey parameter must be " + "non-null");
212 if (caName == null)
213 throw new NullPointerException(
214 "the caName parameter must be " + "non-null");
215 if (caName.length() == 0)
216 throw new IllegalArgumentException("the caName "
217 + "parameter must be a non-empty String");
218 // check if caName is formatted correctly
219 this .caPrincipal = new X500Principal(caName);
220 this .pubKey = pubKey;
221 this .caName = caName;
222 this .trustedCert = null;
223 setNameConstraints(nameConstraints);
224 }
225
226 /**
227 * Returns the most-trusted CA certificate.
228 *
229 * @return a trusted <code>X509Certificate</code> or <code>null</code>
230 * if the trust anchor was not specified as a trusted certificate
231 */
232 public final X509Certificate getTrustedCert() {
233 return this .trustedCert;
234 }
235
236 /**
237 * Returns the name of the most-trusted CA as an X500Principal.
238 *
239 * @return the X.500 distinguished name of the most-trusted CA, or
240 * <code>null</code> if the trust anchor was not specified as a trusted
241 * public key and name or X500Principal pair
242 * @since 1.5
243 */
244 public final X500Principal getCA() {
245 return this .caPrincipal;
246 }
247
248 /**
249 * Returns the name of the most-trusted CA in RFC 2253 <code>String</code>
250 * format.
251 *
252 * @return the X.500 distinguished name of the most-trusted CA, or
253 * <code>null</code> if the trust anchor was not specified as a trusted
254 * public key and name or X500Principal pair
255 */
256 public final String getCAName() {
257 return this .caName;
258 }
259
260 /**
261 * Returns the public key of the most-trusted CA.
262 *
263 * @return the public key of the most-trusted CA, or <code>null</code>
264 * if the trust anchor was not specified as a trusted public key and name
265 * or X500Principal pair
266 */
267 public final PublicKey getCAPublicKey() {
268 return this .pubKey;
269 }
270
271 /**
272 * Decode the name constraints and clone them if not null.
273 */
274 private void setNameConstraints(byte[] bytes) {
275 if (bytes == null) {
276 ncBytes = null;
277 nc = null;
278 } else {
279 ncBytes = (byte[]) bytes.clone();
280 // validate DER encoding
281 try {
282 nc = new NameConstraintsExtension(Boolean.FALSE, bytes);
283 } catch (IOException ioe) {
284 IllegalArgumentException iae = new IllegalArgumentException(
285 ioe.getMessage());
286 iae.initCause(ioe);
287 throw iae;
288 }
289 }
290 }
291
292 /**
293 * Returns the name constraints parameter. The specified name constraints
294 * are associated with this trust anchor and are intended to be used
295 * as additional constraints when validating an X.509 certification path.
296 * <p>
297 * The name constraints are returned as a byte array. This byte array
298 * contains the DER encoded form of the name constraints, as they
299 * would appear in the NameConstraints structure defined in RFC 3280
300 * and X.509. The ASN.1 notation for this structure is supplied in the
301 * documentation for
302 * {@link #TrustAnchor(X509Certificate, byte[])
303 * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }.
304 * <p>
305 * Note that the byte array returned is cloned to protect against
306 * subsequent modifications.
307 *
308 * @return a byte array containing the ASN.1 DER encoding of
309 * a NameConstraints extension used for checking name constraints,
310 * or <code>null</code> if not set.
311 */
312 public final byte[] getNameConstraints() {
313 return (ncBytes == null ? null : (byte[]) ncBytes.clone());
314 }
315
316 /**
317 * Returns a formatted string describing the <code>TrustAnchor</code>.
318 *
319 * @return a formatted string describing the <code>TrustAnchor</code>
320 */
321 public String toString() {
322 StringBuffer sb = new StringBuffer();
323 sb.append("[\n");
324 if (pubKey != null) {
325 sb.append(" Trusted CA Public Key: " + pubKey.toString()
326 + "\n");
327 sb.append(" Trusted CA Issuer Name: "
328 + String.valueOf(caName) + "\n");
329 } else {
330 sb.append(" Trusted CA cert: " + trustedCert.toString()
331 + "\n");
332 }
333 if (nc != null)
334 sb.append(" Name Constraints: " + nc.toString() + "\n");
335 return sb.toString();
336 }
337 }
|