001/* ExemptionMechanism.java -- Generic crypto-weakening mechanism. 002 Copyright (C) 2004 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.crypto; 040 041import gnu.java.security.Engine; 042 043import java.lang.reflect.InvocationTargetException; 044import java.security.AlgorithmParameters; 045import java.security.InvalidAlgorithmParameterException; 046import java.security.InvalidKeyException; 047import java.security.Key; 048import java.security.NoSuchAlgorithmException; 049import java.security.NoSuchProviderException; 050import java.security.Provider; 051import java.security.Security; 052import java.security.spec.AlgorithmParameterSpec; 053 054/** 055 * An exemption mechanism, which will conditionally allow cryptography 056 * where it is not normally allowed, implements things such as <i>key 057 * recovery</i>, <i>key weakening</i>, or <i>key escrow</i>. 058 * 059 * <p><b>Implementation note</b>: this class is present for 060 * API-compatibility only; it is not actually used anywhere in this library 061 * and this library does not, in general, support crypto weakening. 062 * 063 * @author Casey Marshall (csm@gnu.org) 064 * @since 1.4 065 */ 066public class ExemptionMechanism 067{ 068 069 // Constants and fields. 070 // ------------------------------------------------------------------------ 071 072 private static final String SERVICE = "ExemptionMechanism"; 073 private ExemptionMechanismSpi emSpi; 074 private Provider provider; 075 private String mechanism; 076 private boolean virgin; 077 078 // Constructor. 079 // ------------------------------------------------------------------------ 080 081 protected ExemptionMechanism(ExemptionMechanismSpi emSpi, Provider provider, 082 String mechanism) 083 { 084 this.emSpi = emSpi; 085 this.provider = provider; 086 this.mechanism = mechanism; 087 virgin = true; 088 } 089 090 /** 091 * Create an instance of <code>ExemptionMechanism</code> for a designated 092 * <code>mechanism</code> from the first Security Provider offering it. 093 * 094 * @param mechanism the name of the exemption mechanism to create. 095 * @return a newly created instance of <code>ExemptionMechanism</code>. 096 * @throws IllegalArgumentException if the provider is null. 097 * @throws NoSuchAlgorithmException if no such exemption mechanism is 098 * available from any known Security Provider. 099 * @throws IllegalArgumentException if <code>mechanism</code> is 100 * <code>null</code> or is an empty string. 101 */ 102 public static final ExemptionMechanism getInstance(String mechanism) 103 throws NoSuchAlgorithmException 104 { 105 Provider[] p = Security.getProviders(); 106 NoSuchAlgorithmException lastException = null; 107 for (int i = 0; i < p.length; i++) 108 try 109 { 110 return getInstance(mechanism, p[i]); 111 } 112 catch (NoSuchAlgorithmException x) 113 { 114 lastException = x; 115 } 116 if (lastException != null) 117 throw lastException; 118 throw new NoSuchAlgorithmException(mechanism); 119 } 120 121 /** 122 * Create an instance of <code>ExemptionMechanism</code> for a designated 123 * <code>mechanism</code> from a named <code>provider</code>. 124 * 125 * @param mechanism the name of the exemption mechanism to create. 126 * @param provider the security provider to provide the exemption 127 * <code>mechanism</code>. 128 * @return a newly created instance of <code>ExemptionMechanism</code>. 129 * @throws NoSuchAlgorithmException if no such exemption mechanism is 130 * available from the named <code>provider</code>. 131 * @throws NoSuchProviderException if no Security Provider with the designated 132 * name is known to the underlying JVM. 133 * @throws IllegalArgumentException if either <code>mechanism</code> or 134 * <code>provider</code> is <code>null</code>, or if 135 * <code>mechanism</code> is an empty string. 136 */ 137 public static final ExemptionMechanism getInstance(String mechanism, 138 String provider) 139 throws NoSuchAlgorithmException, NoSuchProviderException 140 { 141 if (provider == null) 142 throw new IllegalArgumentException("provider MUST NOT be null"); 143 Provider p = Security.getProvider(provider); 144 if (p == null) 145 throw new NoSuchProviderException(provider); 146 return getInstance(mechanism, p); 147 } 148 149 /** 150 * Create an instance of <code>ExemptionMechanism</code> for a designated 151 * <code>mechanism</code> from a designated <code>provider</code>. 152 * 153 * @param mechanism the name of the exemption mechanism to create. 154 * @param provider the security provider to provide the exemption 155 * <code>mechanism</code>. 156 * @return a newly created instance of <code>ExemptionMechanism</code>. 157 * @throws NoSuchAlgorithmException if an exemption mechanism could not be 158 * created. 159 * @throws IllegalArgumentException if either <code>mechanism</code> or 160 * <code>provider</code> is <code>null</code>, or if 161 * <code>mechanism</code> is an empty string. 162 */ 163 public static final ExemptionMechanism getInstance(String mechanism, 164 Provider provider) 165 throws NoSuchAlgorithmException 166 { 167 StringBuilder sb = new StringBuilder("ExemptionMechanism [") 168 .append(mechanism).append("] from provider[") 169 .append(provider).append("] could not be created"); 170 Throwable cause; 171 try 172 { 173 Object spi = Engine.getInstance(SERVICE, mechanism, provider); 174 return new ExemptionMechanism((ExemptionMechanismSpi) spi, 175 provider, 176 mechanism); 177 } 178 catch (InvocationTargetException x) 179 { 180 cause = x.getCause(); 181 if (cause instanceof NoSuchAlgorithmException) 182 throw (NoSuchAlgorithmException) cause; 183 if (cause == null) 184 cause = x; 185 } 186 catch (ClassCastException x) 187 { 188 cause = x; 189 } 190 NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString()); 191 x.initCause(cause); 192 throw x; 193 } 194 195 public final byte[] genExemptionBlob() 196 throws IllegalStateException, ExemptionMechanismException 197 { 198 if (virgin) 199 { 200 throw new IllegalStateException("not initialized"); 201 } 202 return emSpi.engineGenExemptionBlob(); 203 } 204 205 public final int genExemptionBlob(byte[] output) 206 throws IllegalStateException, ExemptionMechanismException, 207 ShortBufferException 208 { 209 return genExemptionBlob(output, 0); 210 } 211 212 public final int genExemptionBlob(byte[] output, int outputOffset) 213 throws IllegalStateException, ExemptionMechanismException, 214 ShortBufferException 215 { 216 if (virgin) 217 { 218 throw new IllegalStateException("not initialized"); 219 } 220 return emSpi.engineGenExemptionBlob(output, outputOffset); 221 } 222 223 public final String getName() 224 { 225 return mechanism; 226 } 227 228 public final int getOutputSize(int inputLength) throws IllegalStateException 229 { 230 if (virgin) 231 { 232 throw new IllegalStateException("not initialized"); 233 } 234 return emSpi.engineGetOutputSize(inputLength); 235 } 236 237 public final Provider getProvider() 238 { 239 return provider; 240 } 241 242 public final void init(Key key) 243 throws ExemptionMechanismException, InvalidKeyException 244 { 245 emSpi.engineInit(key); 246 virgin = false; 247 } 248 249 public final void init(Key key, AlgorithmParameters params) 250 throws ExemptionMechanismException, InvalidAlgorithmParameterException, 251 InvalidKeyException 252 { 253 emSpi.engineInit(key, params); 254 virgin = false; 255 } 256 257 public final void init(Key key, AlgorithmParameterSpec params) 258 throws ExemptionMechanismException, InvalidAlgorithmParameterException, 259 InvalidKeyException 260 { 261 emSpi.engineInit(key, params); 262 virgin = false; 263 } 264 265 public final boolean isCryptoAllowed(Key key) 266 throws ExemptionMechanismException 267 { 268 return true; 269 } 270 271 protected void finalize() 272 { 273 } 274}