• 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      *
146      * @param algorithm
147      *            the name of the requested exemption mechanism.
148      * @param provider
149      *            the provider that is providing the algorithm.
150      * @return the new {@code ExemptionMechanism} instance.
151      * @throws NoSuchAlgorithmException
152      *             if the specified algorithm is not provided by the specified
153      *             provider.
154      * @throws NullPointerException
155      *             if the algorithm parameter is {@code null}.
156      * @throws IllegalArgumentException
157      *             if the provider parameter is {@code null}.
158      */
getInstance(String algorithm, Provider provider)159     public static final ExemptionMechanism getInstance(String algorithm,
160             Provider provider) throws NoSuchAlgorithmException {
161         if (algorithm == null) {
162             throw new NullPointerException("algorithm == null");
163         }
164         if (provider == null) {
165             throw new IllegalArgumentException("provider == null");
166         }
167         Object spi = ENGINE.getInstance(algorithm, provider, null);
168         return new ExemptionMechanism((ExemptionMechanismSpi) spi, provider, algorithm);
169     }
170 
171     /**
172      * Returns the provider of this {@code ExemptionMechanism} instance.
173      *
174      * @return the provider of this {@code ExemptionMechanism} instance.
175      */
getProvider()176     public final Provider getProvider() {
177         return provider;
178     }
179 
180     /**
181      * Returns whether the result blob for this {@code ExemptionMechanism}
182      * instance has been generated successfully and that the specified key is
183      * the same as the one that was used to initialize and generate.
184      *
185      * @param key
186      *            the key to verify.
187      * @return whether the result blob for this {@code ExemptionMechanism}
188      *         instance has been generated successfully.
189      * @throws ExemptionMechanismException
190      *             if an error occurs while determining whether the result blob
191      *             has been generated successfully.
192      */
isCryptoAllowed(Key key)193     public final boolean isCryptoAllowed(Key key)
194             throws ExemptionMechanismException {
195 
196         if (generated
197                 && (initKey.equals(key) || Arrays.equals(initKey.getEncoded(),
198                         key.getEncoded()))) {
199             return true;
200         }
201         return false;
202     }
203 
204     /**
205      * Returns the size in bytes for the output buffer needed to hold the output
206      * of the next {@link #genExemptionBlob} call, given the specified {@code
207      * inputLen} (in bytes).
208      *
209      * @param inputLen
210      *            the specified input length (in bytes).
211      * @return the size in bytes for the output buffer.
212      * @throws IllegalStateException
213      *             if this {@code ExemptionMechanism} instance is not
214      *             initialized.
215      */
getOutputSize(int inputLen)216     public final int getOutputSize(int inputLen) throws IllegalStateException {
217         if (!isInit) {
218             throw new IllegalStateException("ExemptionMechanism is not initialized");
219         }
220         return spiImpl.engineGetOutputSize(inputLen);
221     }
222 
223     /**
224      * Initializes this {@code ExemptionMechanism} instance with the
225      * specified key.
226      *
227      * @param key
228      *            the key to initialize this instance with.
229      * @throws InvalidKeyException
230      *             if the key cannot be used to initialize this mechanism.
231      * @throws ExemptionMechanismException
232      *             if error(s) occur during initialization.
233      */
init(Key key)234     public final void init(Key key) throws InvalidKeyException,
235             ExemptionMechanismException {
236         generated = false;
237         spiImpl.engineInit(key);
238         initKey = key;
239         isInit = true;
240     }
241 
242     /**
243      * Initializes this {@code ExemptionMechanism} instance with the
244      * specified key and algorithm parameters.
245      *
246      * @param key
247      *            the key to initialize this instance with.
248      * @param param
249      *            the parameters for this exemption mechanism algorithm.
250      * @throws InvalidKeyException
251      *             if the key cannot be used to initialize this mechanism.
252      * @throws InvalidAlgorithmParameterException
253      *             if the parameters cannot be used to initialize this
254      *             mechanism.
255      * @throws ExemptionMechanismException
256      *             if error(s) occur during initialization.
257      */
init(Key key, AlgorithmParameters param)258     public final void init(Key key, AlgorithmParameters param)
259             throws InvalidKeyException, InvalidAlgorithmParameterException,
260             ExemptionMechanismException {
261         generated = false;
262         spiImpl.engineInit(key, param);
263         initKey = key;
264         isInit = true;
265     }
266 
267     /**
268      * Initializes this {@code ExemptionMechanism} instance with the
269      * specified key and algorithm parameters.
270      *
271      * @param key
272      *            the key to initialize this instance with.
273      * @param param
274      *            the parameters for this exemption mechanism algorithm.
275      * @throws InvalidKeyException
276      *             if the key cannot be used to initialize this mechanism.
277      * @throws InvalidAlgorithmParameterException
278      *             the the parameters cannot be used to initialize this
279      *             mechanism.
280      * @throws ExemptionMechanismException
281      *             if error(s) occur during initialization.
282      */
init(Key key, AlgorithmParameterSpec param)283     public final void init(Key key, AlgorithmParameterSpec param)
284             throws InvalidKeyException, InvalidAlgorithmParameterException,
285             ExemptionMechanismException {
286         generated = false;
287         spiImpl.engineInit(key, param);
288         initKey = key;
289         isInit = true;
290     }
291 
292     /**
293      * Generates the result key blob for this exemption mechanism.
294      *
295      * @return the result key blob for this exemption mechanism.
296      * @throws IllegalStateException
297      *             if this {@code ExemptionMechanism} instance is not
298      *             initialized.
299      * @throws ExemptionMechanismException
300      *             if error(s) occur during generation.
301      */
genExemptionBlob()302     public final byte[] genExemptionBlob() throws IllegalStateException,
303             ExemptionMechanismException {
304         if (!isInit) {
305             throw new IllegalStateException("ExemptionMechanism is not initialized");
306         }
307         generated = false;
308         byte[] result = spiImpl.engineGenExemptionBlob();
309         generated = true;
310         return result;
311     }
312 
313     /**
314      * Generates the result key blob for this exemption mechanism and stores it
315      * into the {@code output} buffer.
316      *
317      * @param output
318      *            the output buffer for the result key blob.
319      * @return the number of bytes written to the {@code output} buffer.
320      * @throws IllegalStateException
321      *             if this {@code ExemptionMechanism} instance is not
322      *             initialized.
323      * @throws ShortBufferException
324      *             if the provided buffer is too small for the result key blob.
325      * @throws ExemptionMechanismException
326      *             if error(s) occur during generation.
327      */
genExemptionBlob(byte[] output)328     public final int genExemptionBlob(byte[] output)
329             throws IllegalStateException, ShortBufferException,
330             ExemptionMechanismException {
331         return genExemptionBlob(output, 0);
332     }
333 
334     /**
335      * Generates the result key blob for this exemption mechanism and stores it
336      * into the {@code output} buffer at offset {@code outputOffset}.
337      *
338      * @param output
339      *            the output buffer for the result key blob.
340      * @param outputOffset
341      *            the offset in the output buffer to start.
342      * @return the number of bytes written to the {@code output} buffer.
343      * @throws IllegalStateException
344      *             if this {@code ExemptionMechanism} instance is not
345      *             initialized.
346      * @throws ShortBufferException
347      *             if the provided buffer is too small for the result key blob.
348      * @throws ExemptionMechanismException
349      *             if error(s) occur during generation.
350      */
genExemptionBlob(byte[] output, int outputOffset)351     public final int genExemptionBlob(byte[] output, int outputOffset)
352             throws IllegalStateException, ShortBufferException,
353             ExemptionMechanismException {
354         if (!isInit) {
355             throw new IllegalStateException("ExemptionMechanism is not initialized");
356         }
357         generated = false;
358         int len = spiImpl.engineGenExemptionBlob(output, outputOffset);
359         generated = true;
360         return len;
361     }
362 
363     /**
364      * Override to clear any key state in the instance.
365      */
finalize()366     @Override protected void finalize() {
367         try {
368             super.finalize();
369         } catch (Throwable t) {
370             // for consistency with the RI, we must override Object.finalize() to
371             // remove the throws clause.
372             throw new AssertionError(t);
373         }
374     }
375 }
376