001 /*
002 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.security.cert;
027
028 import java.security.AccessController;
029 import java.security.InvalidAlgorithmParameterException;
030 import java.security.NoSuchAlgorithmException;
031 import java.security.NoSuchProviderException;
032 import java.security.PrivilegedAction;
033 import java.security.Provider;
034 import java.security.Security;
035 import sun.security.util.Debug;
036
037 import sun.security.jca.*;
038 import sun.security.jca.GetInstance.Instance;
039
040 /**
041 * A class for validating certification paths (also known as certificate
042 * chains).
043 * <p>
044 * This class uses a provider-based architecture.
045 * To create a <code>CertPathValidator</code>,
046 * call one of the static <code>getInstance</code> methods, passing in the
047 * algorithm name of the <code>CertPathValidator</code> desired and
048 * optionally the name of the provider desired.
049 * <p>
050 * Once a <code>CertPathValidator</code> object has been created, it can
051 * be used to validate certification paths by calling the {@link #validate
052 * validate} method and passing it the <code>CertPath</code> to be validated
053 * and an algorithm-specific set of parameters. If successful, the result is
054 * returned in an object that implements the
055 * <code>CertPathValidatorResult</code> interface.
056 * <p>
057 * <b>Concurrent Access</b>
058 * <p>
059 * The static methods of this class are guaranteed to be thread-safe.
060 * Multiple threads may concurrently invoke the static methods defined in
061 * this class with no ill effects.
062 * <p>
063 * However, this is not true for the non-static methods defined by this class.
064 * Unless otherwise documented by a specific provider, threads that need to
065 * access a single <code>CertPathValidator</code> instance concurrently should
066 * synchronize amongst themselves and provide the necessary locking. Multiple
067 * threads each manipulating a different <code>CertPathValidator</code>
068 * instance need not synchronize.
069 *
070 * @see CertPath
071 *
072 * @version 1.20 05/05/07
073 * @since 1.4
074 * @author Yassir Elley
075 */
076 public class CertPathValidator {
077
078 /*
079 * Constant to lookup in the Security properties file to determine
080 * the default certpathvalidator type. In the Security properties file,
081 * the default certpathvalidator type is given as:
082 * <pre>
083 * certpathvalidator.type=PKIX
084 * </pre>
085 */
086 private static final String CPV_TYPE = "certpathvalidator.type";
087 private static final Debug debug = Debug.getInstance("certpath");
088 private CertPathValidatorSpi validatorSpi;
089 private Provider provider;
090 private String algorithm;
091
092 /**
093 * Creates a <code>CertPathValidator</code> object of the given algorithm,
094 * and encapsulates the given provider implementation (SPI object) in it.
095 *
096 * @param validatorSpi the provider implementation
097 * @param provider the provider
098 * @param algorithm the algorithm name
099 */
100 protected CertPathValidator(CertPathValidatorSpi validatorSpi,
101 Provider provider, String algorithm) {
102 this .validatorSpi = validatorSpi;
103 this .provider = provider;
104 this .algorithm = algorithm;
105 }
106
107 /**
108 * Returns a <code>CertPathValidator</code> object that implements the
109 * specified algorithm.
110 *
111 * <p> This method traverses the list of registered security Providers,
112 * starting with the most preferred Provider.
113 * A new CertPathValidator object encapsulating the
114 * CertPathValidatorSpi implementation from the first
115 * Provider that supports the specified algorithm is returned.
116 *
117 * <p> Note that the list of registered providers may be retrieved via
118 * the {@link Security#getProviders() Security.getProviders()} method.
119 *
120 * @param algorithm the name of the requested <code>CertPathValidator</code>
121 * algorithm. See Appendix A in the <a href=
122 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
123 * Java Certification Path API Programmer's Guide </a>
124 * for information about standard algorithm names.
125 *
126 * @return a <code>CertPathValidator</code> object that implements the
127 * specified algorithm.
128 *
129 * @exception NoSuchAlgorithmException if no Provider supports a
130 * CertPathValidatorSpi implementation for the
131 * specified algorithm.
132 *
133 * @see java.security.Provider
134 */
135 public static CertPathValidator getInstance(String algorithm)
136 throws NoSuchAlgorithmException {
137 Instance instance = GetInstance.getInstance(
138 "CertPathValidator", CertPathValidatorSpi.class,
139 algorithm);
140 return new CertPathValidator(
141 (CertPathValidatorSpi) instance.impl,
142 instance.provider, algorithm);
143 }
144
145 /**
146 * Returns a <code>CertPathValidator</code> object that implements the
147 * specified algorithm.
148 *
149 * <p> A new CertPathValidator object encapsulating the
150 * CertPathValidatorSpi implementation from the specified provider
151 * is returned. The specified provider must be registered
152 * in the security provider list.
153 *
154 * <p> Note that the list of registered providers may be retrieved via
155 * the {@link Security#getProviders() Security.getProviders()} method.
156 *
157 * @param algorithm the name of the requested <code>CertPathValidator</code>
158 * algorithm. See Appendix A in the <a href=
159 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
160 * Java Certification Path API Programmer's Guide </a>
161 * for information about standard algorithm names.
162 *
163 * @param provider the name of the provider.
164 *
165 * @return a <code>CertPathValidator</code> object that implements the
166 * specified algorithm.
167 *
168 * @exception NoSuchAlgorithmException if a CertPathValidatorSpi
169 * implementation for the specified algorithm is not
170 * available from the specified provider.
171 *
172 * @exception NoSuchProviderException if the specified provider is not
173 * registered in the security provider list.
174 *
175 * @exception IllegalArgumentException if the <code>provider</code> is
176 * null or empty.
177 *
178 * @see java.security.Provider
179 */
180 public static CertPathValidator getInstance(String algorithm,
181 String provider) throws NoSuchAlgorithmException,
182 NoSuchProviderException {
183 Instance instance = GetInstance.getInstance(
184 "CertPathValidator", CertPathValidatorSpi.class,
185 algorithm, provider);
186 return new CertPathValidator(
187 (CertPathValidatorSpi) instance.impl,
188 instance.provider, algorithm);
189 }
190
191 /**
192 * Returns a <code>CertPathValidator</code> object that implements the
193 * specified algorithm.
194 *
195 * <p> A new CertPathValidator object encapsulating the
196 * CertPathValidatorSpi implementation from the specified Provider
197 * object is returned. Note that the specified Provider object
198 * does not have to be registered in the provider list.
199 *
200 * @param algorithm the name of the requested
201 * <code>CertPathValidator</code> algorithm.
202 * See Appendix A in the <a href=
203 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
204 * Java Certification Path API Programmer's Guide </a>
205 * for information about standard algorithm names.
206 *
207 * @param provider the provider.
208 *
209 * @return a <code>CertPathValidator</code> object that implements the
210 * specified algorithm.
211 *
212 * @exception NoSuchAlgorithmException if a CertPathValidatorSpi
213 * implementation for the specified algorithm is not available
214 * from the specified Provider object.
215 *
216 * @exception IllegalArgumentException if the <code>provider</code> is
217 * null.
218 *
219 * @see java.security.Provider
220 */
221 public static CertPathValidator getInstance(String algorithm,
222 Provider provider) throws NoSuchAlgorithmException {
223 Instance instance = GetInstance.getInstance(
224 "CertPathValidator", CertPathValidatorSpi.class,
225 algorithm, provider);
226 return new CertPathValidator(
227 (CertPathValidatorSpi) instance.impl,
228 instance.provider, algorithm);
229 }
230
231 /**
232 * Returns the <code>Provider</code> of this
233 * <code>CertPathValidator</code>.
234 *
235 * @return the <code>Provider</code> of this <code>CertPathValidator</code>
236 */
237 public final Provider getProvider() {
238 return this .provider;
239 }
240
241 /**
242 * Returns the algorithm name of this <code>CertPathValidator</code>.
243 *
244 * @return the algorithm name of this <code>CertPathValidator</code>
245 */
246 public final String getAlgorithm() {
247 return this .algorithm;
248 }
249
250 /**
251 * Validates the specified certification path using the specified
252 * algorithm parameter set.
253 * <p>
254 * The <code>CertPath</code> specified must be of a type that is
255 * supported by the validation algorithm, otherwise an
256 * <code>InvalidAlgorithmParameterException</code> will be thrown. For
257 * example, a <code>CertPathValidator</code> that implements the PKIX
258 * algorithm validates <code>CertPath</code> objects of type X.509.
259 *
260 * @param certPath the <code>CertPath</code> to be validated
261 * @param params the algorithm parameters
262 * @return the result of the validation algorithm
263 * @exception CertPathValidatorException if the <code>CertPath</code>
264 * does not validate
265 * @exception InvalidAlgorithmParameterException if the specified
266 * parameters or the type of the specified <code>CertPath</code> are
267 * inappropriate for this <code>CertPathValidator</code>
268 */
269 public final CertPathValidatorResult validate(CertPath certPath,
270 CertPathParameters params)
271 throws CertPathValidatorException,
272 InvalidAlgorithmParameterException {
273 return validatorSpi.engineValidate(certPath, params);
274 }
275
276 /**
277 * Returns the default <code>CertPathValidator</code> type as specified in
278 * the Java security properties file, or the string "PKIX"
279 * if no such property exists. The Java security properties file is
280 * located in the file named <JAVA_HOME>/lib/security/java.security.
281 * <JAVA_HOME> refers to the value of the java.home system property,
282 * and specifies the directory where the JRE is installed.
283 *
284 * <p>The default <code>CertPathValidator</code> type can be used by
285 * applications that do not want to use a hard-coded type when calling one
286 * of the <code>getInstance</code> methods, and want to provide a default
287 * type in case a user does not specify its own.
288 *
289 * <p>The default <code>CertPathValidator</code> type can be changed by
290 * setting the value of the "certpathvalidator.type" security property
291 * (in the Java security properties file) to the desired type.
292 *
293 * @return the default <code>CertPathValidator</code> type as specified
294 * in the Java security properties file, or the string "PKIX"
295 * if no such property exists.
296 */
297 public final static String getDefaultType() {
298 String cpvtype;
299 cpvtype = AccessController
300 .doPrivileged(new PrivilegedAction<String>() {
301 public String run() {
302 return Security.getProperty(CPV_TYPE);
303 }
304 });
305 if (cpvtype == null) {
306 cpvtype = "PKIX";
307 }
308 return cpvtype;
309 }
310 }
|