1 /* 2 * Copyright (c) 2000, 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.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 validating certification paths (also known as certificate 42 * chains). 43 * <p> 44 * This class uses a provider-based architecture. 45 * To create a {@code CertPathValidator}, 46 * call one of the static {@code getInstance} methods, passing in the 47 * algorithm name of the {@code CertPathValidator} desired and 48 * optionally the name of the provider desired. 49 * 50 * <p>Once a {@code CertPathValidator} object has been created, it can 51 * be used to validate certification paths by calling the {@link #validate 52 * validate} method and passing it the {@code CertPath} to be validated 53 * and an algorithm-specific set of parameters. If successful, the result is 54 * returned in an object that implements the 55 * {@code CertPathValidatorResult} interface. 56 * 57 * <p>The {@link #getRevocationChecker} method allows an application to specify 58 * additional algorithm-specific parameters and options used by the 59 * {@code CertPathValidator} when checking the revocation status of 60 * certificates. Here is an example demonstrating how it is used with the PKIX 61 * algorithm: 62 * 63 * <pre> 64 * CertPathValidator cpv = CertPathValidator.getInstance("PKIX"); 65 * PKIXRevocationChecker rc = (PKIXRevocationChecker)cpv.getRevocationChecker(); 66 * rc.setOptions(EnumSet.of(Option.SOFT_FAIL)); 67 * params.addCertPathChecker(rc); 68 * CertPathValidatorResult cpvr = cpv.validate(path, params); 69 * </pre> 70 * 71 * <p> Android provides the following {@code CertPathValidator} algorithms: 72 * <table> 73 * <thead> 74 * <tr> 75 * <th>Algorithm</th> 76 * <th>Supported API Levels</th> 77 * </tr> 78 * </thead> 79 * <tbody> 80 * <tr> 81 * <td>PKIX</td> 82 * <td>1+</td> 83 * </tr> 84 * </tbody> 85 * </table> 86 * 87 * This algorithm is described in the <a href= 88 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator"> 89 * CertPathValidator section</a> of the 90 * Java Cryptography Architecture Standard Algorithm Name Documentation. 91 * 92 * <p> 93 * <b>Concurrent Access</b> 94 * <p> 95 * The static methods of this class are guaranteed to be thread-safe. 96 * Multiple threads may concurrently invoke the static methods defined in 97 * this class with no ill effects. 98 * <p> 99 * However, this is not true for the non-static methods defined by this class. 100 * Unless otherwise documented by a specific provider, threads that need to 101 * access a single {@code CertPathValidator} instance concurrently should 102 * synchronize amongst themselves and provide the necessary locking. Multiple 103 * threads each manipulating a different {@code CertPathValidator} 104 * instance need not synchronize. 105 * 106 * @see CertPath 107 * 108 * @since 1.4 109 * @author Yassir Elley 110 */ 111 public class CertPathValidator { 112 113 /* 114 * Constant to lookup in the Security properties file to determine 115 * the default certpathvalidator type. In the Security properties file, 116 * the default certpathvalidator type is given as: 117 * <pre> 118 * certpathvalidator.type=PKIX 119 * </pre> 120 */ 121 private static final String CPV_TYPE = "certpathvalidator.type"; 122 private final CertPathValidatorSpi validatorSpi; 123 private final Provider provider; 124 private final String algorithm; 125 126 /** 127 * Creates a {@code CertPathValidator} object of the given algorithm, 128 * and encapsulates the given provider implementation (SPI object) in it. 129 * 130 * @param validatorSpi the provider implementation 131 * @param provider the provider 132 * @param algorithm the algorithm name 133 */ CertPathValidator(CertPathValidatorSpi validatorSpi, Provider provider, String algorithm)134 protected CertPathValidator(CertPathValidatorSpi validatorSpi, 135 Provider provider, String algorithm) 136 { 137 this.validatorSpi = validatorSpi; 138 this.provider = provider; 139 this.algorithm = algorithm; 140 } 141 142 /** 143 * Returns a {@code CertPathValidator} object that implements the 144 * specified algorithm. 145 * 146 * <p> This method traverses the list of registered security Providers, 147 * starting with the most preferred Provider. 148 * A new CertPathValidator object encapsulating the 149 * CertPathValidatorSpi implementation from the first 150 * Provider that supports the specified algorithm is returned. 151 * 152 * <p> Note that the list of registered providers may be retrieved via 153 * the {@link Security#getProviders() Security.getProviders()} method. 154 * 155 * @param algorithm the name of the requested {@code CertPathValidator} 156 * algorithm. See the CertPathValidator section in the <a href= 157 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator"> 158 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 159 * for information about standard algorithm names. 160 * 161 * @return a {@code CertPathValidator} object that implements the 162 * specified algorithm. 163 * 164 * @exception NoSuchAlgorithmException if no Provider supports a 165 * CertPathValidatorSpi implementation for the 166 * specified algorithm. 167 * 168 * @see java.security.Provider 169 */ getInstance(String algorithm)170 public static CertPathValidator getInstance(String algorithm) 171 throws NoSuchAlgorithmException { 172 Instance instance = GetInstance.getInstance("CertPathValidator", 173 CertPathValidatorSpi.class, algorithm); 174 return new CertPathValidator((CertPathValidatorSpi)instance.impl, 175 instance.provider, algorithm); 176 } 177 178 /** 179 * Returns a {@code CertPathValidator} object that implements the 180 * specified algorithm. 181 * 182 * <p> A new CertPathValidator object encapsulating the 183 * CertPathValidatorSpi implementation from the specified provider 184 * is returned. The specified provider must be registered 185 * in the security provider list. 186 * 187 * <p> Note that the list of registered providers may be retrieved via 188 * the {@link Security#getProviders() Security.getProviders()} method. 189 * 190 * @param algorithm the name of the requested {@code CertPathValidator} 191 * algorithm. See the CertPathValidator section in the <a href= 192 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator"> 193 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 194 * for information about standard algorithm names. 195 * 196 * @param provider the name of the provider. 197 * 198 * @return a {@code CertPathValidator} object that implements the 199 * specified algorithm. 200 * 201 * @exception NoSuchAlgorithmException if a CertPathValidatorSpi 202 * implementation for the specified algorithm is not 203 * available from the specified provider. 204 * 205 * @exception NoSuchProviderException if the specified provider is not 206 * registered in the security provider list. 207 * 208 * @exception IllegalArgumentException if the {@code provider} is 209 * null or empty. 210 * 211 * @see java.security.Provider 212 */ getInstance(String algorithm, String provider)213 public static CertPathValidator getInstance(String algorithm, 214 String provider) throws NoSuchAlgorithmException, 215 NoSuchProviderException { 216 Instance instance = GetInstance.getInstance("CertPathValidator", 217 CertPathValidatorSpi.class, algorithm, provider); 218 return new CertPathValidator((CertPathValidatorSpi)instance.impl, 219 instance.provider, algorithm); 220 } 221 222 /** 223 * Returns a {@code CertPathValidator} object that implements the 224 * specified algorithm. 225 * 226 * <p> A new CertPathValidator object encapsulating the 227 * CertPathValidatorSpi implementation from the specified Provider 228 * object is returned. Note that the specified Provider object 229 * does not have to be registered in the provider list. 230 * 231 * @param algorithm the name of the requested {@code CertPathValidator} 232 * algorithm. See the CertPathValidator section in the <a href= 233 * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathValidator"> 234 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 235 * for information about standard algorithm names. 236 * 237 * @param provider the provider. 238 * 239 * @return a {@code CertPathValidator} object that implements the 240 * specified algorithm. 241 * 242 * @exception NoSuchAlgorithmException if a CertPathValidatorSpi 243 * implementation for the specified algorithm is not available 244 * from the specified Provider object. 245 * 246 * @exception IllegalArgumentException if the {@code provider} is 247 * null. 248 * 249 * @see java.security.Provider 250 */ getInstance(String algorithm, Provider provider)251 public static CertPathValidator getInstance(String algorithm, 252 Provider provider) throws NoSuchAlgorithmException { 253 Instance instance = GetInstance.getInstance("CertPathValidator", 254 CertPathValidatorSpi.class, algorithm, provider); 255 return new CertPathValidator((CertPathValidatorSpi)instance.impl, 256 instance.provider, algorithm); 257 } 258 259 /** 260 * Returns the {@code Provider} of this 261 * {@code CertPathValidator}. 262 * 263 * @return the {@code Provider} of this {@code CertPathValidator} 264 */ getProvider()265 public final Provider getProvider() { 266 return this.provider; 267 } 268 269 /** 270 * Returns the algorithm name of this {@code CertPathValidator}. 271 * 272 * @return the algorithm name of this {@code CertPathValidator} 273 */ getAlgorithm()274 public final String getAlgorithm() { 275 return this.algorithm; 276 } 277 278 /** 279 * Validates the specified certification path using the specified 280 * algorithm parameter set. 281 * <p> 282 * The {@code CertPath} specified must be of a type that is 283 * supported by the validation algorithm, otherwise an 284 * {@code InvalidAlgorithmParameterException} will be thrown. For 285 * example, a {@code CertPathValidator} that implements the PKIX 286 * algorithm validates {@code CertPath} objects of type X.509. 287 * 288 * @param certPath the {@code CertPath} to be validated 289 * @param params the algorithm parameters 290 * @return the result of the validation algorithm 291 * @exception CertPathValidatorException if the {@code CertPath} 292 * does not validate 293 * @exception InvalidAlgorithmParameterException if the specified 294 * parameters or the type of the specified {@code CertPath} are 295 * inappropriate for this {@code CertPathValidator} 296 */ validate(CertPath certPath, CertPathParameters params)297 public final CertPathValidatorResult validate(CertPath certPath, 298 CertPathParameters params) 299 throws CertPathValidatorException, InvalidAlgorithmParameterException 300 { 301 return validatorSpi.engineValidate(certPath, params); 302 } 303 304 /** 305 * Returns the default {@code CertPathValidator} type as specified by 306 * the {@code certpathvalidator.type} security property, or the string 307 * {@literal "PKIX"} if no such property exists. 308 * 309 * <p>The default {@code CertPathValidator} type can be used by 310 * applications that do not want to use a hard-coded type when calling one 311 * of the {@code getInstance} methods, and want to provide a default 312 * type in case a user does not specify its own. 313 * 314 * <p>The default {@code CertPathValidator} type can be changed by 315 * setting the value of the {@code certpathvalidator.type} security 316 * property to the desired type. 317 * 318 * @see java.security.Security security properties 319 * @return the default {@code CertPathValidator} type as specified 320 * by the {@code certpathvalidator.type} security property, or the string 321 * {@literal "PKIX"} if no such property exists. 322 */ getDefaultType()323 public final static String getDefaultType() { 324 String cpvtype = 325 AccessController.doPrivileged(new PrivilegedAction<String>() { 326 public String run() { 327 return Security.getProperty(CPV_TYPE); 328 } 329 }); 330 return (cpvtype == null) ? "PKIX" : cpvtype; 331 } 332 333 /** 334 * Returns a {@code CertPathChecker} that the encapsulated 335 * {@code CertPathValidatorSpi} implementation uses to check the revocation 336 * status of certificates. A PKIX implementation returns objects of 337 * type {@code PKIXRevocationChecker}. Each invocation of this method 338 * returns a new instance of {@code CertPathChecker}. 339 * 340 * <p>The primary purpose of this method is to allow callers to specify 341 * additional input parameters and options specific to revocation checking. 342 * See the class description for an example. 343 * 344 * @return a {@code CertPathChecker} 345 * @throws UnsupportedOperationException if the service provider does not 346 * support this method 347 * @since 1.8 348 */ getRevocationChecker()349 public final CertPathChecker getRevocationChecker() { 350 return validatorSpi.engineGetRevocationChecker(); 351 } 352 } 353