• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package javax.crypto;
19 
20 import java.security.AlgorithmParameters;
21 import java.security.InvalidAlgorithmParameterException;
22 import java.security.InvalidKeyException;
23 import java.security.Key;
24 import java.security.NoSuchAlgorithmException;
25 import java.security.NoSuchProviderException;
26 import java.security.Provider;
27 import java.security.Security;
28 import java.security.spec.AlgorithmParameterSpec;
29 import java.util.Arrays;
30 import org.apache.harmony.security.fortress.Engine;
31 
32 /**
33  * This class implements the functionality of an exemption mechanism such as
34  * <i>key recovery</i>, <i>key weakening</i>, or <i>key escrow</i>.
35  */
36 public class ExemptionMechanism {
37 
38     // Used to access common engine functionality
39     private static final Engine ENGINE = new Engine("ExemptionMechanism");
40 
41     // Store used provider
42     private final Provider provider;
43 
44     // Store used spi implementation
45     private final ExemptionMechanismSpi spiImpl;
46 
47     // Store mechanism name
48     private final String mechanism;
49 
50     // Store state (initialized or not)
51     private boolean isInit;
52 
53     // Store initKey value
54     private Key initKey;
55 
56     // Indicates if blob generated successfully
57     private boolean generated;
58 
59     /**
60      * Creates a {@code ExemptionMechanism} instance.
61      *
62      * @param exmechSpi
63      *            the implementation delegate.
64      * @param provider
65      *            the associated provider.
66      * @param mechanism
67      *            the name of the mechanism.
68      */
ExemptionMechanism(ExemptionMechanismSpi exmechSpi, Provider provider, String mechanism)69     protected ExemptionMechanism(ExemptionMechanismSpi exmechSpi,
70             Provider provider, String mechanism) {
71         this.mechanism = mechanism;
72         this.spiImpl = exmechSpi;
73         this.provider = provider;
74         isInit = false;
75     }
76 
77     /**
78      * Returns the name of this {@code ExemptionMechanism}.
79      *
80      * @return the name of this {@code ExemptionMechanism}.
81      */
getName()82     public final String getName() {
83         return mechanism;
84     }
85 
86     /**
87      * Returns a new {@code ExemptionMechanism} instance that provides the
88      * specified exemption mechanism algorithm.
89      *
90      * @param algorithm
91      *            the name of the requested exemption mechanism.
92      * @return the new {@code ExemptionMechanism} instance.
93      * @throws NoSuchAlgorithmException
94      *             if the specified algorithm is not available by any provider.
95      * @throws NullPointerException
96      *             if the algorithm parameter is {@code null}.
97      */
getInstance(String algorithm)98     public static final ExemptionMechanism getInstance(String algorithm)
99             throws NoSuchAlgorithmException {
100         if (algorithm == null) {
101             throw new NullPointerException("algorithm == null");
102         }
103         Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
104         return new ExemptionMechanism((ExemptionMechanismSpi) sap.spi, sap.provider, algorithm);
105     }
106 
107     /**
108      * Returns a new {@code ExemptionMechansm} instance that provides the
109      * specified exemption mechanism algorithm from the specified provider.
110      *
111      * @param algorithm
112      *            the name of the requested exemption mechanism.
113      * @param provider
114      *            the name of the provider that is providing the algorithm.
115      * @return the new {@code ExemptionMechanism} instance.
116      * @throws NoSuchAlgorithmException
117      *             if the specified algorithm is not provided by the specified
118      *             provider.
119      * @throws NoSuchProviderException
120      *             if the specified provider is not available.
121      * @throws NullPointerException
122      *             if the algorithm parameter is {@code null}.
123      * @throws IllegalArgumentException
124      *             if the provider parameter is {@code null}.
125      */
getInstance(String algorithm, String provider)126     public static final ExemptionMechanism getInstance(String algorithm,
127             String provider) throws NoSuchAlgorithmException,
128             NoSuchProviderException {
129         if (provider == null) {
130             throw new IllegalArgumentException("provider == null");
131         }
132         Provider impProvider = Security.getProvider(provider);
133         if (impProvider == null) {
134             throw new NoSuchProviderException(provider);
135         }
136         if (algorithm == null) {
137             throw new NullPointerException("algorithm == null");
138         }
139         return getInstance(algorithm, impProvider);
140     }
141 
142     /**
143      * Returns a new {@code ExemptionMechanism} instance that provides the
144      * specified exemption mechanism algorithm from the specified provider.
145      * The {@code provider} supplied does not have to be registered.
146      *
147      * @param algorithm
148      *            the name of the requested exemption mechanism.
149      * @param provider
150      *            the provider that is providing the algorithm.
151      * @return the new {@code ExemptionMechanism} instance.
152      * @throws NoSuchAlgorithmException
153      *             if the specified algorithm is not provided by the specified
154      *             provider.
155      * @throws NullPointerException
156      *             if the algorithm parameter is {@code null}.
157      * @throws IllegalArgumentException
158      *             if the provider parameter is {@code null}.
159      */
getInstance(String algorithm, Provider provider)160     public static final ExemptionMechanism getInstance(String algorithm,
161             Provider provider) throws NoSuchAlgorithmException {
162         if (algorithm == null) {
163             throw new NullPointerException("algorithm == null");
164         }
165         if (provider == null) {
166             throw new IllegalArgumentException("provider == null");
167         }
168         Object spi = ENGINE.getInstance(algorithm, provider, null);
169         return new ExemptionMechanism((ExemptionMechanismSpi) spi, provider, algorithm);
170     }
171 
172     /**
173      * Returns the provider of this {@code ExemptionMechanism} instance.
174      *
175      * @return the provider of this {@code ExemptionMechanism} instance.
176      */
getProvider()177     public final Provider getProvider() {
178         return provider;
179     }
180 
181     /**
182      * Returns whether the result blob for this {@code ExemptionMechanism}
183      * instance has been generated successfully and that the specified key is
184      * the same as the one that was used to initialize and generate.
185      *
186      * @param key
187      *            the key to verify.
188      * @return whether the result blob for this {@code ExemptionMechanism}
189      *         instance has been generated successfully.
190      * @throws ExemptionMechanismException
191      *             if an error occurs while determining whether the result blob
192      *             has been generated successfully.
193      */
isCryptoAllowed(Key key)194     public final boolean isCryptoAllowed(Key key)
195             throws ExemptionMechanismException {
196 
197         if (generated
198                 && (initKey.equals(key) || Arrays.equals(initKey.getEncoded(),
199                         key.getEncoded()))) {
200             return true;
201         }
202         return false;
203     }
204 
205     /**
206      * Returns the size in bytes for the output buffer needed to hold the output
207      * of the next {@link #genExemptionBlob} call, given the specified {@code
208      * inputLen} (in bytes).
209      *
210      * @param inputLen
211      *            the specified input length (in bytes).
212      * @return the size in bytes for the output buffer.
213      * @throws IllegalStateException
214      *             if this {@code ExemptionMechanism} instance is not
215      *             initialized.
216      */
getOutputSize(int inputLen)217     public final int getOutputSize(int inputLen) throws IllegalStateException {
218         if (!isInit) {
219             throw new IllegalStateException("ExemptionMechanism is not initialized");
220         }
221         return spiImpl.engineGetOutputSize(inputLen);
222     }
223 
224     /**
225      * Initializes this {@code ExemptionMechanism} instance with the
226      * specified key.
227      *
228      * @param key
229      *            the key to initialize this instance with.
230      * @throws InvalidKeyException
231      *             if the key cannot be used to initialize this mechanism.
232      * @throws ExemptionMechanismException
233      *             if error(s) occur during initialization.
234      */
init(Key key)235     public final void init(Key key) throws InvalidKeyException,
236             ExemptionMechanismException {
237         generated = false;
238         spiImpl.engineInit(key);
239         initKey = key;
240         isInit = true;
241     }
242 
243     /**
244      * Initializes this {@code ExemptionMechanism} instance with the
245      * specified key and algorithm parameters.
246      *
247      * @param key
248      *            the key to initialize this instance with.
249      * @param param
250      *            the parameters for this exemption mechanism algorithm.
251      * @throws InvalidKeyException
252      *             if the key cannot be used to initialize this mechanism.
253      * @throws InvalidAlgorithmParameterException
254      *             if the parameters cannot be used to initialize this
255      *             mechanism.
256      * @throws ExemptionMechanismException
257      *             if error(s) occur during initialization.
258      */
init(Key key, AlgorithmParameters param)259     public final void init(Key key, AlgorithmParameters param)
260             throws InvalidKeyException, InvalidAlgorithmParameterException,
261             ExemptionMechanismException {
262         generated = false;
263         spiImpl.engineInit(key, param);
264         initKey = key;
265         isInit = true;
266     }
267 
268     /**
269      * Initializes this {@code ExemptionMechanism} instance with the
270      * specified key and algorithm parameters.
271      *
272      * @param key
273      *            the key to initialize this instance with.
274      * @param param
275      *            the parameters for this exemption mechanism algorithm.
276      * @throws InvalidKeyException
277      *             if the key cannot be used to initialize this mechanism.
278      * @throws InvalidAlgorithmParameterException
279      *             the the parameters cannot be used to initialize this
280      *             mechanism.
281      * @throws ExemptionMechanismException
282      *             if error(s) occur during initialization.
283      */
init(Key key, AlgorithmParameterSpec param)284     public final void init(Key key, AlgorithmParameterSpec param)
285             throws InvalidKeyException, InvalidAlgorithmParameterException,
286             ExemptionMechanismException {
287         generated = false;
288         spiImpl.engineInit(key, param);
289         initKey = key;
290         isInit = true;
291     }
292 
293     /**
294      * Generates the result key blob for this exemption mechanism.
295      *
296      * @return the result key blob for this exemption mechanism.
297      * @throws IllegalStateException
298      *             if this {@code ExemptionMechanism} instance is not
299      *             initialized.
300      * @throws ExemptionMechanismException
301      *             if error(s) occur during generation.
302      */
genExemptionBlob()303     public final byte[] genExemptionBlob() throws IllegalStateException,
304             ExemptionMechanismException {
305         if (!isInit) {
306             throw new IllegalStateException("ExemptionMechanism is not initialized");
307         }
308         generated = false;
309         byte[] result = spiImpl.engineGenExemptionBlob();
310         generated = true;
311         return result;
312     }
313 
314     /**
315      * Generates the result key blob for this exemption mechanism and stores it
316      * into the {@code output} buffer.
317      *
318      * @param output
319      *            the output buffer for the result key blob.
320      * @return the number of bytes written to the {@code output} buffer.
321      * @throws IllegalStateException
322      *             if this {@code ExemptionMechanism} instance is not
323      *             initialized.
324      * @throws ShortBufferException
325      *             if the provided buffer is too small for the result key blob.
326      * @throws ExemptionMechanismException
327      *             if error(s) occur during generation.
328      */
genExemptionBlob(byte[] output)329     public final int genExemptionBlob(byte[] output)
330             throws IllegalStateException, ShortBufferException,
331             ExemptionMechanismException {
332         return genExemptionBlob(output, 0);
333     }
334 
335     /**
336      * Generates the result key blob for this exemption mechanism and stores it
337      * into the {@code output} buffer at offset {@code outputOffset}.
338      *
339      * @param output
340      *            the output buffer for the result key blob.
341      * @param outputOffset
342      *            the offset in the output buffer to start.
343      * @return the number of bytes written to the {@code output} buffer.
344      * @throws IllegalStateException
345      *             if this {@code ExemptionMechanism} instance is not
346      *             initialized.
347      * @throws ShortBufferException
348      *             if the provided buffer is too small for the result key blob.
349      * @throws ExemptionMechanismException
350      *             if error(s) occur during generation.
351      */
genExemptionBlob(byte[] output, int outputOffset)352     public final int genExemptionBlob(byte[] output, int outputOffset)
353             throws IllegalStateException, ShortBufferException,
354             ExemptionMechanismException {
355         if (!isInit) {
356             throw new IllegalStateException("ExemptionMechanism is not initialized");
357         }
358         generated = false;
359         int len = spiImpl.engineGenExemptionBlob(output, outputOffset);
360         generated = true;
361         return len;
362     }
363 
364     /**
365      * Override to clear any key state in the instance.
366      */
finalize()367     @Override protected void finalize() {
368         try {
369             super.finalize();
370         } catch (Throwable t) {
371             // for consistency with the RI, we must override Object.finalize() to
372             // remove the throws clause.
373             throw new AssertionError(t);
374         }
375     }
376 }
377