001 /* CertPathValidator -- validates certificate paths.
002 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package java.security.cert;
040
041 import gnu.java.security.Engine;
042
043 import java.lang.reflect.InvocationTargetException;
044 import java.security.AccessController;
045 import java.security.InvalidAlgorithmParameterException;
046 import java.security.NoSuchAlgorithmException;
047 import java.security.NoSuchProviderException;
048 import java.security.PrivilegedAction;
049 import java.security.Provider;
050 import java.security.Security;
051
052 /**
053 * Generic interface to classes that validate certificate paths.
054 *
055 * <p>Using this class is similar to all the provider-based security
056 * classes; the method of interest, {@link
057 * #validate(java.security.cert.CertPath,java.security.cert.CertPathParameters)},
058 * which takes provider-specific implementations of {@link
059 * CertPathParameters}, and return provider-specific implementations of
060 * {@link CertPathValidatorResult}.
061 *
062 * @since JDK 1.4
063 * @see CertPath
064 */
065 public class CertPathValidator {
066
067 // Constants and fields.
068 // ------------------------------------------------------------------------
069
070 /** Service name for CertPathValidator. */
071 private static final String CERT_PATH_VALIDATOR = "CertPathValidator";
072
073 /** The underlying implementation. */
074 private final CertPathValidatorSpi validatorSpi;
075
076 /** The provider of this implementation. */
077 private final Provider provider;
078
079 /** The algorithm's name. */
080 private final String algorithm;
081
082 // Constructor.
083 // ------------------------------------------------------------------------
084
085 /**
086 * Creates a new CertPathValidator.
087 *
088 * @param validatorSpi The underlying implementation.
089 * @param provider The provider of the implementation.
090 * @param algorithm The algorithm name.
091 */
092 protected CertPathValidator(CertPathValidatorSpi validatorSpi,
093 Provider provider, String algorithm)
094 {
095 this.validatorSpi = validatorSpi;
096 this.provider = provider;
097 this.algorithm = algorithm;
098 }
099
100 // Class methods.
101 // ------------------------------------------------------------------------
102
103 /**
104 * Returns the default validator type.
105 *
106 * <p>This value may be set at run-time via the security property
107 * "certpathvalidator.type", or the value "PKIX" if this property is
108 * not set.
109 *
110 * @return The default validator type.
111 */
112 public static synchronized String getDefaultType() {
113 String type = (String) AccessController.doPrivileged(
114 new PrivilegedAction()
115 {
116 public Object run()
117 {
118 return Security.getProperty("certpathvalidator.type");
119 }
120 }
121 );
122 if (type == null)
123 type = "PKIX";
124 return type;
125 }
126
127 /**
128 * Returns an instance of the given validator from the first provider that
129 * implements it.
130 *
131 * @param algorithm The name of the algorithm to get.
132 * @return The new instance.
133 * @throws NoSuchAlgorithmException If no installed provider implements the
134 * requested algorithm.
135 * @throws IllegalArgumentException if <code>algorithm</code> is
136 * <code>null</code> or is an empty string.
137 */
138 public static CertPathValidator getInstance(String algorithm)
139 throws NoSuchAlgorithmException
140 {
141 Provider[] p = Security.getProviders();
142 NoSuchAlgorithmException lastException = null;
143 for (int i = 0; i < p.length; i++)
144 try
145 {
146 return getInstance(algorithm, p[i]);
147 }
148 catch (NoSuchAlgorithmException x)
149 {
150 lastException = x;
151 }
152 if (lastException != null)
153 throw lastException;
154 throw new NoSuchAlgorithmException(algorithm);
155 }
156
157 /**
158 * Returns an instance of the given validator from the named provider.
159 *
160 * @param algorithm The name of the algorithm to get.
161 * @param provider The name of the provider from which to get the
162 * implementation.
163 * @return The new instance.
164 * @throws NoSuchAlgorithmException If the named provider does not implement
165 * the algorithm.
166 * @throws NoSuchProviderException If no provider named <i>provider</i> is
167 * installed.
168 * @throws IllegalArgumentException if either <code>algorithm</code> or
169 * <code>provider</code> is <code>null</code>, or if
170 * <code>algorithm</code> is an empty string.
171 */
172 public static CertPathValidator getInstance(String algorithm, String provider)
173 throws NoSuchAlgorithmException, NoSuchProviderException
174 {
175 if (provider == null)
176 throw new IllegalArgumentException("provider MUST NOT be null");
177 Provider p = Security.getProvider(provider);
178 if (p == null)
179 throw new NoSuchProviderException(provider);
180 return getInstance(algorithm, p);
181 }
182
183 /**
184 * Returns an instance of the given validator from the given provider.
185 *
186 * @param algorithm The name of the algorithm to get.
187 * @param provider The provider from which to get the implementation.
188 * @return The new instance.
189 * @throws NoSuchAlgorithmException If the provider does not implement the
190 * algorithm.
191 * @throws IllegalArgumentException if either <code>algorithm</code> or
192 * <code>provider</code> is <code>null</code>, or if
193 * <code>algorithm</code> is an empty string.
194 */
195 public static CertPathValidator getInstance(String algorithm,
196 Provider provider)
197 throws NoSuchAlgorithmException
198 {
199 StringBuilder sb = new StringBuilder("CertPathValidator for algorithm [")
200 .append(algorithm).append("] from provider[")
201 .append(provider).append("] could not be created");
202 Throwable cause;
203 try
204 {
205 Object spi = Engine.getInstance(CERT_PATH_VALIDATOR, algorithm, provider);
206 return new CertPathValidator((CertPathValidatorSpi) spi, provider, algorithm);
207 }
208 catch (InvocationTargetException x)
209 {
210 cause = x.getCause();
211 if (cause instanceof NoSuchAlgorithmException)
212 throw (NoSuchAlgorithmException) cause;
213 if (cause == null)
214 cause = x;
215 }
216 catch (ClassCastException x)
217 {
218 cause = x;
219 }
220 NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
221 x.initCause(cause);
222 throw x;
223 }
224
225 /**
226 * Return the name of this validator.
227 *
228 * @return This validator's name.
229 */
230 public final String getAlgorithm()
231 {
232 return algorithm;
233 }
234
235 /**
236 * Return the provider of this implementation.
237 *
238 * @return The provider.
239 */
240 public final Provider getProvider()
241 {
242 return provider;
243 }
244
245 /**
246 * Attempt to validate a certificate path.
247 *
248 * @param certPath The path to validate.
249 * @param params The algorithm-specific parameters.
250 * @return The result of this validation attempt.
251 * @throws CertPathValidatorException If the certificate path cannot
252 * be validated.
253 * @throws InvalidAlgorithmParameterException If this implementation
254 * rejects the specified parameters.
255 */
256 public final CertPathValidatorResult validate(CertPath certPath,
257 CertPathParameters params)
258 throws CertPathValidatorException, InvalidAlgorithmParameterException
259 {
260 return validatorSpi.engineValidate(certPath, params);
261 }
262 }