1 /* 2 * Copyright (c) 2002, 2015, 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 sun.security.validator; 27 28 import java.util.*; 29 30 import java.security.AlgorithmConstraints; 31 import java.security.KeyStore; 32 import java.security.cert.*; 33 34 /** 35 * Validator abstract base class. Concrete classes are instantiated by calling 36 * one of the getInstance() methods. All methods defined in this class 37 * must be safe for concurrent use by multiple threads.<p> 38 * 39 * The model is that a Validator instance is created specifying validation 40 * settings, such as trust anchors or PKIX parameters. Then one or more 41 * paths are validated using those parameters. In some cases, additional 42 * information can be provided per path validation. This is independent of 43 * the validation parameters and currently only used for TLS server validation. 44 * <p> 45 * Path validation is performed by calling one of the validate() methods. It 46 * specifies a suggested path to be used for validation if available, or only 47 * the end entity certificate otherwise. Optionally additional certificates can 48 * be specified that the caller believes could be helpful. Implementations are 49 * free to make use of this information or validate the path using other means. 50 * validate() also checks that the end entity certificate is suitable for the 51 * intended purpose as described below. 52 * 53 * <p>There are two orthogonal parameters to select the Validator 54 * implementation: type and variant. Type selects the validation algorithm. 55 * Currently supported are TYPE_SIMPLE and TYPE_PKIX. See SimpleValidator and 56 * PKIXValidator for details. 57 * <p> 58 * Variant controls additional extension checks. Currently supported are 59 * five variants: 60 * <ul> 61 * <li>VAR_GENERIC (no additional checks), 62 * <li>VAR_TLS_CLIENT (TLS client specific checks) 63 * <li>VAR_TLS_SERVER (TLS server specific checks), and 64 * <li>VAR_CODE_SIGNING (code signing specific checks). 65 * <li>VAR_JCE_SIGNING (JCE code signing specific checks). 66 * <li>VAR_TSA_SERVER (TSA server specific checks). 67 * <li>VAR_PLUGIN_CODE_SIGNING (Plugin/WebStart code signing specific checks). 68 * </ul> 69 * See EndEntityChecker for more information. 70 * <p> 71 * Examples: 72 * <pre> 73 * // instantiate validator specifying type, variant, and trust anchors 74 * Validator validator = Validator.getInstance(Validator.TYPE_PKIX, 75 * Validator.VAR_TLS_CLIENT, 76 * trustedCerts); 77 * // validate one or more chains using the validator 78 * validator.validate(chain); // throws CertificateException if failed 79 * </pre> 80 * 81 * @see SimpleValidator 82 * @see PKIXValidator 83 * @see EndEntityChecker 84 * 85 * @author Andreas Sterbenz 86 */ 87 public abstract class Validator { 88 89 final static X509Certificate[] CHAIN0 = {}; 90 91 /** 92 * Constant for a validator of type Simple. 93 * @see #getInstance 94 */ 95 public final static String TYPE_SIMPLE = "Simple"; 96 97 /** 98 * Constant for a validator of type PKIX. 99 * @see #getInstance 100 */ 101 public final static String TYPE_PKIX = "PKIX"; 102 103 /** 104 * Constant for a Generic variant of a validator. 105 * @see #getInstance 106 */ 107 public final static String VAR_GENERIC = "generic"; 108 109 /** 110 * Constant for a Code Signing variant of a validator. 111 * @see #getInstance 112 */ 113 public final static String VAR_CODE_SIGNING = "code signing"; 114 115 /** 116 * Constant for a JCE Code Signing variant of a validator. 117 * @see #getInstance 118 */ 119 public final static String VAR_JCE_SIGNING = "jce signing"; 120 121 /** 122 * Constant for a TLS Client variant of a validator. 123 * @see #getInstance 124 */ 125 public final static String VAR_TLS_CLIENT = "tls client"; 126 127 /** 128 * Constant for a TLS Server variant of a validator. 129 * @see #getInstance 130 */ 131 public final static String VAR_TLS_SERVER = "tls server"; 132 133 /** 134 * Constant for a TSA Server variant of a validator. 135 * @see #getInstance 136 */ 137 public final static String VAR_TSA_SERVER = "tsa server"; 138 139 /** 140 * Constant for a Code Signing variant of a validator for use by 141 * the J2SE Plugin/WebStart code. 142 * @see #getInstance 143 */ 144 public final static String VAR_PLUGIN_CODE_SIGNING = "plugin code signing"; 145 146 final EndEntityChecker endEntityChecker; 147 final String type; 148 final String variant; 149 150 /** 151 * @deprecated 152 * @see #setValidationDate 153 */ 154 @Deprecated 155 volatile Date validationDate; 156 157 Validator(String type, String variant) { 158 this.type = type; 159 this.variant = variant; 160 endEntityChecker = EndEntityChecker.getInstance(type, variant); 161 } 162 163 /** 164 * Get a new Validator instance using the trusted certificates from the 165 * specified KeyStore as trust anchors. 166 */ 167 public static Validator getInstance(String type, String variant, 168 KeyStore ks) { 169 return getInstance(type, variant, KeyStores.getTrustedCerts(ks)); 170 } 171 172 /** 173 * Get a new Validator instance using the Set of X509Certificates as trust 174 * anchors. 175 */ 176 public static Validator getInstance(String type, String variant, 177 Collection<X509Certificate> trustedCerts) { 178 if (type.equals(TYPE_SIMPLE)) { 179 return new SimpleValidator(variant, trustedCerts); 180 } else if (type.equals(TYPE_PKIX)) { 181 return new PKIXValidator(variant, trustedCerts); 182 } else { 183 throw new IllegalArgumentException 184 ("Unknown validator type: " + type); 185 } 186 } 187 188 /** 189 * Get a new Validator instance using the provided PKIXBuilderParameters. 190 * This method can only be used with the PKIX validator. 191 */ 192 public static Validator getInstance(String type, String variant, 193 PKIXBuilderParameters params) { 194 if (type.equals(TYPE_PKIX) == false) { 195 throw new IllegalArgumentException 196 ("getInstance(PKIXBuilderParameters) can only be used " 197 + "with PKIX validator"); 198 } 199 return new PKIXValidator(variant, params); 200 } 201 202 /** 203 * Validate the given certificate chain. 204 */ 205 public final X509Certificate[] validate(X509Certificate[] chain) 206 throws CertificateException { 207 return validate(chain, null, null); 208 } 209 210 /** 211 * Validate the given certificate chain. If otherCerts is non-null, it is 212 * a Collection of additional X509Certificates that could be helpful for 213 * path building. 214 */ 215 public final X509Certificate[] validate(X509Certificate[] chain, 216 Collection<X509Certificate> otherCerts) throws CertificateException { 217 return validate(chain, otherCerts, null); 218 } 219 220 /** 221 * Validate the given certificate chain. If otherCerts is non-null, it is 222 * a Collection of additional X509Certificates that could be helpful for 223 * path building. 224 * <p> 225 * Parameter is an additional parameter with variant specific meaning. 226 * Currently, it is only defined for TLS_SERVER variant validators, where 227 * it must be non null and the name of the TLS key exchange algorithm being 228 * used (see JSSE X509TrustManager specification). In the future, it 229 * could be used to pass in a PKCS#7 object for code signing to check time 230 * stamps. 231 * <p> 232 * @return a non-empty chain that was used to validate the path. The 233 * end entity cert is at index 0, the trust anchor at index n-1. 234 */ 235 public final X509Certificate[] validate(X509Certificate[] chain, 236 Collection<X509Certificate> otherCerts, Object parameter) 237 throws CertificateException { 238 return validate(chain, otherCerts, null, parameter); 239 } 240 241 /** 242 * Validate the given certificate chain. 243 * 244 * @param chain the target certificate chain 245 * @param otherCerts a Collection of additional X509Certificates that 246 * could be helpful for path building (or null) 247 * @param constraints algorithm constraints for certification path 248 * processing 249 * @param parameter an additional parameter with variant specific meaning. 250 * Currently, it is only defined for TLS_SERVER variant validators, 251 * where it must be non null and the name of the TLS key exchange 252 * algorithm being used (see JSSE X509TrustManager specification). 253 * In the future, it could be used to pass in a PKCS#7 object for 254 * code signing to check time stamps. 255 * @return a non-empty chain that was used to validate the path. The 256 * end entity cert is at index 0, the trust anchor at index n-1. 257 */ 258 public final X509Certificate[] validate(X509Certificate[] chain, 259 Collection<X509Certificate> otherCerts, 260 AlgorithmConstraints constraints, 261 Object parameter) throws CertificateException { 262 chain = engineValidate(chain, otherCerts, constraints, parameter); 263 264 // omit EE extension check if EE cert is also trust anchor 265 if (chain.length > 1) { 266 // Only have EndEntityChecker check extra extensions when 267 // validating with a TYPE_SIMPLE Validator, which only checks 268 // extensions for CA certs. A TYPE_PKIX Validator, however, runs 269 // checks on all certs' extensions, including checks by 270 // any PKIXCertPathCheckers included in the PKIXParameters, 271 // so the extra checks would be redundant. 272 boolean checkExtraExtensions = 273 (type == TYPE_SIMPLE) ? true : false; 274 endEntityChecker.check(chain[0], parameter, checkExtraExtensions); 275 } 276 277 return chain; 278 } 279 280 abstract X509Certificate[] engineValidate(X509Certificate[] chain, 281 Collection<X509Certificate> otherCerts, 282 AlgorithmConstraints constraints, 283 Object parameter) throws CertificateException; 284 285 /** 286 * Returns an immutable Collection of the X509Certificates this instance 287 * uses as trust anchors. 288 */ 289 public abstract Collection<X509Certificate> getTrustedCertificates(); 290 291 /** 292 * Set the date to be used for subsequent validations. NOTE that 293 * this is not a supported API, it is provided to simplify 294 * writing tests only. 295 * 296 * @deprecated 297 */ 298 @Deprecated 299 public void setValidationDate(Date validationDate) { 300 this.validationDate = validationDate; 301 } 302 303 }