• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2001, 2008, 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</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  */
64 public 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      */
TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)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      */
TrustAnchor(X500Principal caPrincipal, PublicKey pubKey, byte[] nameConstraints)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      */
TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)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      */
getTrustedCert()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      */
getCA()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      */
getCAName()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      */
getCAPublicKey()266     public final PublicKey getCAPublicKey() {
267         return this.pubKey;
268     }
269 
270     /**
271      * Decode the name constraints and clone them if not null.
272      */
setNameConstraints(byte[] bytes)273     private void setNameConstraints(byte[] bytes) {
274         if (bytes == null) {
275             ncBytes = null;
276             nc = null;
277         } else {
278             ncBytes = 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      */
getNameConstraints()311     public final byte [] getNameConstraints() {
312         return ncBytes == null ? null : 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      */
toString()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 }
335