Validator.java revision 12745:f068a4ffddd2
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
26package sun.security.validator;
27
28import java.util.*;
29
30import java.security.AlgorithmConstraints;
31import java.security.KeyStore;
32import 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 */
87public abstract class Validator {
88
89    static final X509Certificate[] CHAIN0 = {};
90
91    /**
92     * Constant for a validator of type Simple.
93     * @see #getInstance
94     */
95    public static final String TYPE_SIMPLE = "Simple";
96
97    /**
98     * Constant for a validator of type PKIX.
99     * @see #getInstance
100     */
101    public static final String TYPE_PKIX = "PKIX";
102
103    /**
104     * Constant for a Generic variant of a validator.
105     * @see #getInstance
106     */
107    public static final String VAR_GENERIC = "generic";
108
109    /**
110     * Constant for a Code Signing variant of a validator.
111     * @see #getInstance
112     */
113    public static final 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 static final String VAR_JCE_SIGNING = "jce signing";
120
121    /**
122     * Constant for a TLS Client variant of a validator.
123     * @see #getInstance
124     */
125    public static final String VAR_TLS_CLIENT = "tls client";
126
127    /**
128     * Constant for a TLS Server variant of a validator.
129     * @see #getInstance
130     */
131    public static final String VAR_TLS_SERVER = "tls server";
132
133    /**
134     * Constant for a TSA Server variant of a validator.
135     * @see #getInstance
136     */
137    public static final 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 static final String VAR_PLUGIN_CODE_SIGNING = "plugin code signing";
145
146    private final String type;
147    final EndEntityChecker endEntityChecker;
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     *
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, Collections.emptyList(), null,
239                parameter);
240    }
241
242    /**
243     * Validate the given certificate chain.
244     *
245     * @param chain the target certificate chain
246     * @param otherCerts a Collection of additional X509Certificates that
247     *        could be helpful for path building (or null)
248     * @param responseList a List of zero or more byte arrays, each
249     *        one being a DER-encoded OCSP response (per RFC 6960).  Entries
250     *        in the List must match the order of the certificates in the
251     *        chain parameter.  It is possible that fewer responses may be
252     *        in the list than are elements in {@code chain} and a missing
253     *        response for a matching element in {@code chain} can be
254     *        represented with a zero-length byte array.
255     * @param constraints algorithm constraints for certification path
256     *        processing
257     * @param parameter an additional parameter with variant specific meaning.
258     *        Currently, it is only defined for TLS_SERVER variant validators,
259     *        where it must be non null and the name of the TLS key exchange
260     *        algorithm being used (see JSSE X509TrustManager specification).
261     *        In the future, it could be used to pass in a PKCS#7 object for
262     *        code signing to check time stamps.
263     * @return a non-empty chain that was used to validate the path. The
264     *        end entity cert is at index 0, the trust anchor at index n-1.
265     */
266    public final X509Certificate[] validate(X509Certificate[] chain,
267                Collection<X509Certificate> otherCerts,
268                List<byte[]> responseList,
269                AlgorithmConstraints constraints,
270                Object parameter) throws CertificateException {
271        chain = engineValidate(chain, otherCerts, responseList, constraints,
272                parameter);
273
274        // omit EE extension check if EE cert is also trust anchor
275        if (chain.length > 1) {
276            // EndEntityChecker does not need to check unresolved critical
277            // extensions when validating with a TYPE_PKIX Validator.
278            // A TYPE_PKIX Validator will already have run checks on all
279            // certs' extensions, including checks by any PKIXCertPathCheckers
280            // included in the PKIXParameters, so the extra checks would be
281            // redundant.
282            boolean checkUnresolvedCritExts =
283                    (type == TYPE_PKIX) ? false : true;
284            endEntityChecker.check(chain[0], parameter,
285                                   checkUnresolvedCritExts);
286        }
287
288        return chain;
289    }
290
291    abstract X509Certificate[] engineValidate(X509Certificate[] chain,
292                Collection<X509Certificate> otherCerts,
293                List<byte[]> responseList,
294                AlgorithmConstraints constraints,
295                Object parameter) throws CertificateException;
296
297    /**
298     * Returns an immutable Collection of the X509Certificates this instance
299     * uses as trust anchors.
300     */
301    public abstract Collection<X509Certificate> getTrustedCertificates();
302
303    /**
304     * Set the date to be used for subsequent validations. NOTE that
305     * this is not a supported API, it is provided to simplify
306     * writing tests only.
307     *
308     * @deprecated
309     */
310    @Deprecated
311    public void setValidationDate(Date validationDate) {
312        this.validationDate = validationDate;
313    }
314
315}
316