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 }