blob: 8745b780cd23568fa2456b264d953b56bf9ba9d3 [file] [log] [blame]
The Android Open Source Projectadc854b2009-03-03 19:28:47 -08001/*
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
18package javax.crypto;
19
20import java.security.AlgorithmParameters;
21import java.security.InvalidAlgorithmParameterException;
22import java.security.InvalidKeyException;
23import java.security.Key;
24import java.security.NoSuchAlgorithmException;
25import java.security.NoSuchProviderException;
26import java.security.Provider;
27import java.security.Security;
28import java.security.spec.AlgorithmParameterSpec;
29import java.util.Arrays;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080030import 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>.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080035 */
36public class ExemptionMechanism {
37
38 // Used to access common engine functionality
Brian Carlstrom0a480842010-10-18 23:00:51 -070039 private static final Engine ENGINE = new Engine("ExemptionMechanism");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080040
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -070061 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080062 * @param exmechSpi
63 * the implementation delegate.
64 * @param provider
65 * the associated provider.
66 * @param mechanism
67 * the name of the mechanism.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080068 */
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}.
Jesse Wilsonce9ec012009-08-31 15:37:14 -070079 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080080 * @return the name of this {@code ExemptionMechanism}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080081 */
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -070089 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080090 * @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}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080097 */
98 public static final ExemptionMechanism getInstance(String algorithm)
99 throws NoSuchAlgorithmException {
100 if (algorithm == null) {
Kenny Root86acc042012-09-12 10:32:58 -0700101 throw new NullPointerException("algorithm == null");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800102 }
Brian Carlstrom6cdb6b72010-10-19 11:27:15 -0700103 Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
104 return new ExemptionMechanism((ExemptionMechanismSpi) sap.spi, sap.provider, algorithm);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800105 }
106
107 /**
108 * Returns a new {@code ExemptionMechansm} instance that provides the
109 * specified exemption mechanism algorithm from the specified provider.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700110 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800111 * @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}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800125 */
126 public static final ExemptionMechanism getInstance(String algorithm,
127 String provider) throws NoSuchAlgorithmException,
128 NoSuchProviderException {
129 if (provider == null) {
Elliott Hughes80a7fba2010-05-21 16:58:35 -0700130 throw new IllegalArgumentException("provider == null");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800131 }
132 Provider impProvider = Security.getProvider(provider);
133 if (impProvider == null) {
134 throw new NoSuchProviderException(provider);
135 }
136 if (algorithm == null) {
Kenny Root86acc042012-09-12 10:32:58 -0700137 throw new NullPointerException("algorithm == null");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800138 }
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700145 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800146 * @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}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800158 */
159 public static final ExemptionMechanism getInstance(String algorithm,
160 Provider provider) throws NoSuchAlgorithmException {
161 if (algorithm == null) {
Kenny Root86acc042012-09-12 10:32:58 -0700162 throw new NullPointerException("algorithm == null");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800163 }
164 if (provider == null) {
Elliott Hughes80a7fba2010-05-21 16:58:35 -0700165 throw new IllegalArgumentException("provider == null");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800166 }
Brian Carlstrom6cdb6b72010-10-19 11:27:15 -0700167 Object spi = ENGINE.getInstance(algorithm, provider, null);
168 return new ExemptionMechanism((ExemptionMechanismSpi) spi, provider, algorithm);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800169 }
170
171 /**
172 * Returns the provider of this {@code ExemptionMechanism} instance.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700173 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800174 * @return the provider of this {@code ExemptionMechanism} instance.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800175 */
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700184 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800185 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800192 */
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).
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700208 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800209 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800215 */
216 public final int getOutputSize(int inputLen) throws IllegalStateException {
217 if (!isInit) {
Elliott Hughes80a7fba2010-05-21 16:58:35 -0700218 throw new IllegalStateException("ExemptionMechanism is not initialized");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800219 }
220 return spiImpl.engineGetOutputSize(inputLen);
221 }
222
223 /**
224 * Initializes this {@code ExemptionMechanism} instance with the
225 * specified key.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700226 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800227 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800233 */
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700245 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800246 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800257 */
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700270 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800271 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800282 */
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700294 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800295 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800301 */
302 public final byte[] genExemptionBlob() throws IllegalStateException,
303 ExemptionMechanismException {
304 if (!isInit) {
Elliott Hughes80a7fba2010-05-21 16:58:35 -0700305 throw new IllegalStateException("ExemptionMechanism is not initialized");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800306 }
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.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700316 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800317 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800327 */
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}.
Jesse Wilsonce9ec012009-08-31 15:37:14 -0700337 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800338 * @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.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800350 */
351 public final int genExemptionBlob(byte[] output, int outputOffset)
352 throws IllegalStateException, ShortBufferException,
353 ExemptionMechanismException {
354 if (!isInit) {
Elliott Hughes80a7fba2010-05-21 16:58:35 -0700355 throw new IllegalStateException("ExemptionMechanism is not initialized");
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800356 }
357 generated = false;
358 int len = spiImpl.engineGenExemptionBlob(output, outputOffset);
359 generated = true;
360 return len;
361 }
362
363 /**
Brian Carlstrome2f58c92010-09-28 17:18:08 -0700364 * Override to clear any key state in the instance.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800365 */
Jesse Wilsonb17ebc12010-09-02 12:29:59 -0700366 @Override protected void finalize() {
367 try {
368 super.finalize();
Brian Carlstrome2f58c92010-09-28 17:18:08 -0700369 } catch (Throwable t) {
Jesse Wilsonb17ebc12010-09-02 12:29:59 -0700370 // for consistency with the RI, we must override Object.finalize() to
371 // remove the throws clause.
Brian Carlstrome2f58c92010-09-28 17:18:08 -0700372 throw new AssertionError(t);
Jesse Wilsonb17ebc12010-09-02 12:29:59 -0700373 }
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800374 }
Elliott Hughes80a7fba2010-05-21 16:58:35 -0700375}