1 /* 2 * Copyright (c) 2001, 2013, 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://www.ietf.org/rfc/rfc3280">RFC 3280</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 */ TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)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 3280 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 */ TrustAnchor(X500Principal caPrincipal, PublicKey pubKey, byte[] nameConstraints)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 3280 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 */ TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)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.length() == 0) 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 */ getTrustedCert()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 */ getCA()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 */ getCAName()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 */ getCAPublicKey()265 public final PublicKey getCAPublicKey() { 266 return this.pubKey; 267 } 268 269 /** 270 * Decode the name constraints and clone them if not null. 271 */ setNameConstraints(byte[] bytes)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 3280 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 */ getNameConstraints()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 */ toString()319 public String toString() { 320 StringBuffer sb = new StringBuffer(); 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