001 /* ExemptionMechanism.java -- Generic crypto-weakening mechanism.
002 Copyright (C) 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 javax.crypto;
040
041 import gnu.java.security.Engine;
042
043 import java.lang.reflect.InvocationTargetException;
044 import java.security.AlgorithmParameters;
045 import java.security.InvalidAlgorithmParameterException;
046 import java.security.InvalidKeyException;
047 import java.security.Key;
048 import java.security.NoSuchAlgorithmException;
049 import java.security.NoSuchProviderException;
050 import java.security.Provider;
051 import java.security.Security;
052 import 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 */
066 public 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 }