1 /* 2 * Copyright (c) 2000, 2011, 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.security.AccessController; 29 import java.security.InvalidAlgorithmParameterException; 30 import java.security.NoSuchAlgorithmException; 31 import java.security.NoSuchProviderException; 32 import java.security.PrivilegedAction; 33 import java.security.Provider; 34 import java.security.Security; 35 import sun.security.util.Debug; 36 37 import sun.security.jca.*; 38 import sun.security.jca.GetInstance.Instance; 39 40 /** 41 * A class for building certification paths (also known as certificate chains). 42 * <p> 43 * This class uses a provider-based architecture. 44 * To create a <code>CertPathBuilder</code>, call 45 * one of the static <code>getInstance</code> methods, passing in the 46 * algorithm name of the <code>CertPathBuilder</code> desired and optionally 47 * the name of the provider desired. 48 * <p> 49 * Once a <code>CertPathBuilder</code> object has been created, certification 50 * paths can be constructed by calling the {@link #build build} method and 51 * passing it an algorithm-specific set of parameters. If successful, the 52 * result (including the <code>CertPath</code> that was built) is returned 53 * in an object that implements the <code>CertPathBuilderResult</code> 54 * interface. 55 * 56 * <p> Every implementation of the Java platform is required to support the 57 * following standard <code>CertPathBuilder</code> algorithm: 58 * <ul> 59 * <li><tt>PKIX</tt></li> 60 * </ul> 61 * This algorithm is described in the <a href= 62 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder"> 63 * CertPathBuilder section</a> of the 64 * Java Cryptography Architecture Standard Algorithm Name Documentation. 65 * Consult the release documentation for your implementation to see if any 66 * other algorithms are supported. 67 * 68 * <p> 69 * <b>Concurrent Access</b> 70 * <p> 71 * The static methods of this class are guaranteed to be thread-safe. 72 * Multiple threads may concurrently invoke the static methods defined in 73 * this class with no ill effects. 74 * <p> 75 * However, this is not true for the non-static methods defined by this class. 76 * Unless otherwise documented by a specific provider, threads that need to 77 * access a single <code>CertPathBuilder</code> instance concurrently should 78 * synchronize amongst themselves and provide the necessary locking. Multiple 79 * threads each manipulating a different <code>CertPathBuilder</code> instance 80 * need not synchronize. 81 * 82 * @see CertPath 83 * 84 * @since 1.4 85 * @author Sean Mullan 86 * @author Yassir Elley 87 */ 88 public class CertPathBuilder { 89 90 /* 91 * Constant to lookup in the Security properties file to determine 92 * the default certpathbuilder type. In the Security properties file, 93 * the default certpathbuilder type is given as: 94 * <pre> 95 * certpathbuilder.type=PKIX 96 * </pre> 97 */ 98 private static final String CPB_TYPE = "certpathbuilder.type"; 99 private static final Debug debug = Debug.getInstance("certpath"); 100 private CertPathBuilderSpi builderSpi; 101 private Provider provider; 102 private String algorithm; 103 104 /** 105 * Creates a <code>CertPathBuilder</code> object of the given algorithm, 106 * and encapsulates the given provider implementation (SPI object) in it. 107 * 108 * @param builderSpi the provider implementation 109 * @param provider the provider 110 * @param algorithm the algorithm name 111 */ 112 protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider, 113 String algorithm) 114 { 115 this.builderSpi = builderSpi; 116 this.provider = provider; 117 this.algorithm = algorithm; 118 } 119 120 /** 121 * Returns a <code>CertPathBuilder</code> object that implements the 122 * specified algorithm. 123 * 124 * <p> This method traverses the list of registered security Providers, 125 * starting with the most preferred Provider. 126 * A new CertPathBuilder object encapsulating the 127 * CertPathBuilderSpi implementation from the first 128 * Provider that supports the specified algorithm is returned. 129 * 130 * <p> Note that the list of registered providers may be retrieved via 131 * the {@link Security#getProviders() Security.getProviders()} method. 132 * 133 * @param algorithm the name of the requested <code>CertPathBuilder</code> 134 * algorithm. See the CertPathBuilder section in the <a href= 135 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder"> 136 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 137 * for information about standard algorithm names. 138 * 139 * @return a <code>CertPathBuilder</code> object that implements the 140 * specified algorithm. 141 * 142 * @throws NoSuchAlgorithmException if no Provider supports a 143 * CertPathBuilderSpi implementation for the 144 * specified algorithm. 145 * 146 * @see java.security.Provider 147 */ 148 public static CertPathBuilder getInstance(String algorithm) 149 throws NoSuchAlgorithmException { 150 Instance instance = GetInstance.getInstance("CertPathBuilder", 151 CertPathBuilderSpi.class, algorithm); 152 return new CertPathBuilder((CertPathBuilderSpi)instance.impl, 153 instance.provider, algorithm); 154 } 155 156 /** 157 * Returns a <code>CertPathBuilder</code> object that implements the 158 * specified algorithm. 159 * 160 * <p> A new CertPathBuilder object encapsulating the 161 * CertPathBuilderSpi implementation from the specified provider 162 * is returned. The specified provider must be registered 163 * in the security provider list. 164 * 165 * <p> Note that the list of registered providers may be retrieved via 166 * the {@link Security#getProviders() Security.getProviders()} method. 167 * 168 * @param algorithm the name of the requested <code>CertPathBuilder</code> 169 * algorithm. See the CertPathBuilder section in the <a href= 170 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder"> 171 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 172 * for information about standard algorithm names. 173 * 174 * @param provider the name of the provider. 175 * 176 * @return a <code>CertPathBuilder</code> object that implements the 177 * specified algorithm. 178 * 179 * @throws NoSuchAlgorithmException if a CertPathBuilderSpi 180 * implementation for the specified algorithm is not 181 * available from the specified provider. 182 * 183 * @throws NoSuchProviderException if the specified provider is not 184 * registered in the security provider list. 185 * 186 * @exception IllegalArgumentException if the <code>provider</code> is 187 * null or empty. 188 * 189 * @see java.security.Provider 190 */ 191 public static CertPathBuilder getInstance(String algorithm, String provider) 192 throws NoSuchAlgorithmException, NoSuchProviderException { 193 Instance instance = GetInstance.getInstance("CertPathBuilder", 194 CertPathBuilderSpi.class, algorithm, provider); 195 return new CertPathBuilder((CertPathBuilderSpi)instance.impl, 196 instance.provider, algorithm); 197 } 198 199 /** 200 * Returns a <code>CertPathBuilder</code> object that implements the 201 * specified algorithm. 202 * 203 * <p> A new CertPathBuilder object encapsulating the 204 * CertPathBuilderSpi implementation from the specified Provider 205 * object is returned. Note that the specified Provider object 206 * does not have to be registered in the provider list. 207 * 208 * @param algorithm the name of the requested <code>CertPathBuilder</code> 209 * algorithm. See the CertPathBuilder section in the <a href= 210 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder"> 211 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 212 * for information about standard algorithm names. 213 * 214 * @param provider the provider. 215 * 216 * @return a <code>CertPathBuilder</code> object that implements the 217 * specified algorithm. 218 * 219 * @exception NoSuchAlgorithmException if a CertPathBuilderSpi 220 * implementation for the specified algorithm is not available 221 * from the specified Provider object. 222 * 223 * @exception IllegalArgumentException if the <code>provider</code> is 224 * null. 225 * 226 * @see java.security.Provider 227 */ 228 public static CertPathBuilder getInstance(String algorithm, 229 Provider provider) throws NoSuchAlgorithmException { 230 Instance instance = GetInstance.getInstance("CertPathBuilder", 231 CertPathBuilderSpi.class, algorithm, provider); 232 return new CertPathBuilder((CertPathBuilderSpi)instance.impl, 233 instance.provider, algorithm); 234 } 235 236 /** 237 * Returns the provider of this <code>CertPathBuilder</code>. 238 * 239 * @return the provider of this <code>CertPathBuilder</code> 240 */ 241 public final Provider getProvider() { 242 return this.provider; 243 } 244 245 /** 246 * Returns the name of the algorithm of this <code>CertPathBuilder</code>. 247 * 248 * @return the name of the algorithm of this <code>CertPathBuilder</code> 249 */ 250 public final String getAlgorithm() { 251 return this.algorithm; 252 } 253 254 /** 255 * Attempts to build a certification path using the specified algorithm 256 * parameter set. 257 * 258 * @param params the algorithm parameters 259 * @return the result of the build algorithm 260 * @throws CertPathBuilderException if the builder is unable to construct 261 * a certification path that satisfies the specified parameters 262 * @throws InvalidAlgorithmParameterException if the specified parameters 263 * are inappropriate for this <code>CertPathBuilder</code> 264 */ 265 public final CertPathBuilderResult build(CertPathParameters params) 266 throws CertPathBuilderException, InvalidAlgorithmParameterException 267 { 268 return builderSpi.engineBuild(params); 269 } 270 271 /** 272 * Returns the default <code>CertPathBuilder</code> type as specified in 273 * the Java security properties file, or the string "PKIX" 274 * if no such property exists. The Java security properties file is 275 * located in the file named <JAVA_HOME>/lib/security/java.security. 276 * <JAVA_HOME> refers to the value of the java.home system property, 277 * and specifies the directory where the JRE is installed. 278 * 279 * <p>The default <code>CertPathBuilder</code> type can be used by 280 * applications that do not want to use a hard-coded type when calling one 281 * of the <code>getInstance</code> methods, and want to provide a default 282 * type in case a user does not specify its own. 283 * 284 * <p>The default <code>CertPathBuilder</code> type can be changed by 285 * setting the value of the "certpathbuilder.type" security property 286 * (in the Java security properties file) to the desired type. 287 * 288 * @return the default <code>CertPathBuilder</code> type as specified 289 * in the Java security properties file, or the string "PKIX" 290 * if no such property exists. 291 */ 292 public final static String getDefaultType() { 293 String cpbtype; 294 cpbtype = AccessController.doPrivileged(new PrivilegedAction<String>() { 295 public String run() { 296 return Security.getProperty(CPB_TYPE); 297 } 298 }); 299 if (cpbtype == null) { 300 cpbtype = "PKIX"; 301 } 302 return cpbtype; 303 } 304 }