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