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