blob: bd8b27139abb0df364756a1a7725406ac8f75835 [file] [log] [blame]
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.crypto;
27
28import java.util.*;
29
30import java.security.*;
31import java.security.Provider.Service;
32import java.security.spec.*;
33
34import sun.security.jca.*;
35import sun.security.jca.GetInstance.Instance;
36
37/**
38 * This class represents a factory for secret keys.
39 *
40 * <P> Key factories are used to convert <I>keys</I> (opaque
41 * cryptographic keys of type <code>Key</code>) into <I>key specifications</I>
42 * (transparent representations of the underlying key material), and vice
43 * versa.
44 * Secret key factories operate only on secret (symmetric) keys.
45 *
46 * <P> Key factories are bi-directional, i.e., they allow to build an opaque
47 * key object from a given key specification (key material), or to retrieve
48 * the underlying key material of a key object in a suitable format.
49 *
50 * <P> Application developers should refer to their provider's documentation
51 * to find out which key specifications are supported by the
52 * {@link #generateSecret(java.security.spec.KeySpec) generateSecret} and
53 * {@link #getKeySpec(javax.crypto.SecretKey, java.lang.Class) getKeySpec}
54 * methods.
55 * For example, the DES secret-key factory supplied by the "SunJCE" provider
56 * supports <code>DESKeySpec</code> as a transparent representation of DES
57 * keys, and that provider's secret-key factory for Triple DES keys supports
58 * <code>DESedeKeySpec</code> as a transparent representation of Triple DES
59 * keys.
60 *
Przemyslaw Szczepaniak444325b2016-05-18 13:09:39 +010061 * <p> Android provides the following <code>SecretKeyFactory</code> algorithms:
62 * <table>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +000063 * <thead>
64 * <tr>
65 * <th>Algorithm</th>
66 * <th>Supported API Levels</th>
67 * </tr>
68 * </thead>
69 * <tbody>
70 * <tr>
71 * <td>AES</td>
72 * <td>23+</td>
73 * </tr>
74 * <tr>
75 * <td>DES</td>
76 * <td>1+</td>
77 * </tr>
78 * <tr>
79 * <td>DESede</td>
80 * <td>1+</td>
81 * </tr>
82 * <tr>
83 * <td>HmacSHA1</td>
84 * <td>23+</td>
85 * </tr>
86 * <tr>
87 * <td>HmacSHA224</td>
88 * <td>23+</td>
89 * </tr>
90 * <tr>
91 * <td>HmacSHA256</td>
92 * <td>23+</td>
93 * </tr>
94 * <tr>
95 * <td>HmacSHA384</td>
96 * <td>23+</td>
97 * </tr>
98 * <tr>
99 * <td>HmacSHA512</td>
100 * <td>23+</td>
101 * </tr>
102 * <tr>
103 * <td>PBEwithHmacSHA1</td>
104 * <td>1+</td>
105 * </tr>
106 * <tr>
107 * <td>PBEwithHmacSHA1AndAES_128</td>
108 * <td>26+</td>
109 * </tr>
110 * <tr>
111 * <td>PBEwithHmacSHA1AndAES_256</td>
112 * <td>26+</td>
113 * </tr>
114 * <tr>
115 * <td>PBEwithHmacSHA224AndAES_128</td>
116 * <td>26+</td>
117 * </tr>
118 * <tr>
119 * <td>PBEwithHmacSHA224AndAES_256</td>
120 * <td>26+</td>
121 * </tr>
122 * <tr>
123 * <td>PBEwithHmacSHA256AndAES_128</td>
124 * <td>26+</td>
125 * </tr>
126 * <tr>
127 * <td>PBEwithHmacSHA256AndAES_256</td>
128 * <td>26+</td>
129 * </tr>
130 * <tr>
131 * <td>PBEwithHmacSHA384AndAES_128</td>
132 * <td>26+</td>
133 * </tr>
134 * <tr>
135 * <td>PBEwithHmacSHA384AndAES_256</td>
136 * <td>26+</td>
137 * </tr>
138 * <tr>
139 * <td>PBEwithHmacSHA512AndAES_128</td>
140 * <td>26+</td>
141 * </tr>
142 * <tr>
143 * <td>PBEwithHmacSHA512AndAES_256</td>
144 * <td>26+</td>
145 * </tr>
146 * <tr>
147 * <td>PBEwithMD5AND128BITAES-CBC-OPENSSL</td>
148 * <td>1+</td>
149 * </tr>
150 * <tr>
151 * <td>PBEwithMD5AND192BITAES-CBC-OPENSSL</td>
152 * <td>1+</td>
153 * </tr>
154 * <tr>
155 * <td>PBEwithMD5AND256BITAES-CBC-OPENSSL</td>
156 * <td>1+</td>
157 * </tr>
158 * <tr>
159 * <td>PBEwithMD5ANDDES</td>
160 * <td>1+</td>
161 * </tr>
162 * <tr>
163 * <td>PBEwithMD5ANDRC2</td>
164 * <td>1+</td>
165 * </tr>
166 * <tr>
167 * <td>PBEwithSHA1ANDDES</td>
168 * <td>1+</td>
169 * </tr>
170 * <tr>
171 * <td>PBEwithSHA1ANDRC2</td>
172 * <td>1+</td>
173 * </tr>
174 * <tr>
175 * <td>PBEwithSHA256AND128BITAES-CBC-BC</td>
176 * <td>1+</td>
177 * </tr>
178 * <tr>
179 * <td>PBEwithSHA256AND192BITAES-CBC-BC</td>
180 * <td>1+</td>
181 * </tr>
182 * <tr>
183 * <td>PBEwithSHA256AND256BITAES-CBC-BC</td>
184 * <td>1+</td>
185 * </tr>
186 * <tr>
187 * <td>PBEwithSHAAND128BITAES-CBC-BC</td>
188 * <td>1+</td>
189 * </tr>
190 * <tr>
191 * <td>PBEwithSHAAND128BITRC2-CBC</td>
192 * <td>10+</td>
193 * </tr>
194 * <tr>
195 * <td>PBEwithSHAAND128BITRC4</td>
196 * <td>10+</td>
197 * </tr>
198 * <tr>
199 * <td>PBEwithSHAAND192BITAES-CBC-BC</td>
200 * <td>1+</td>
201 * </tr>
202 * <tr>
203 * <td>PBEwithSHAAND2-KEYTRIPLEDES-CBC</td>
204 * <td>1+</td>
205 * </tr>
206 * <tr>
207 * <td>PBEwithSHAAND256BITAES-CBC-BC</td>
208 * <td>1+</td>
209 * </tr>
210 * <tr>
211 * <td>PBEwithSHAAND3-KEYTRIPLEDES-CBC</td>
212 * <td>1+</td>
213 * </tr>
214 * <tr>
215 * <td>PBEwithSHAAND40BITRC2-CBC</td>
216 * <td>1+</td>
217 * </tr>
218 * <tr>
219 * <td>PBEwithSHAAND40BITRC4</td>
220 * <td>10+</td>
221 * </tr>
222 * <tr>
223 * <td>PBEwithSHAANDTWOFISH-CBC</td>
224 * <td>10+</td>
225 * </tr>
226 * <tr>
227 * <td>PBKDF2withHmacSHA1</td>
228 * <td>10+</td>
229 * </tr>
230 * <tr>
231 * <td>PBKDF2withHmacSHA1And8BIT</td>
232 * <td>19+</td>
233 * </tr>
234 * <tr>
235 * <td>PBKDF2withHmacSHA224</td>
236 * <td>26+</td>
237 * </tr>
238 * <tr>
239 * <td>PBKDF2withHmacSHA256</td>
240 * <td>26+</td>
241 * </tr>
242 * <tr>
243 * <td>PBKDF2withHmacSHA384</td>
244 * <td>26+</td>
245 * </tr>
246 * <tr>
247 * <td>PBKDF2withHmacSHA512</td>
248 * <td>26+</td>
249 * </tr>
250 * </tbody>
Przemyslaw Szczepaniak444325b2016-05-18 13:09:39 +0100251 * </table>
252 *
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000253 * These algorithms are described in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100254 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000255 * SecretKeyFactory section</a> of the
256 * Java Cryptography Architecture Standard Algorithm Name Documentation.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000257 *
258 * @author Jan Luehe
259 *
260 * @see SecretKey
261 * @see javax.crypto.spec.DESKeySpec
262 * @see javax.crypto.spec.DESedeKeySpec
263 * @see javax.crypto.spec.PBEKeySpec
264 * @since 1.4
265 */
266
267public class SecretKeyFactory {
268
269 // The provider
270 private Provider provider;
271
272 // The algorithm associated with this factory
273 private final String algorithm;
274
275 // The provider implementation (delegate)
276 private volatile SecretKeyFactorySpi spi;
277
278 // lock for mutex during provider selection
279 private final Object lock = new Object();
280
281 // remaining services to try in provider selection
282 // null once provider is selected
Sergio Giro534b21d2016-08-23 21:19:43 +0100283 private Iterator<Service> serviceIterator;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000284
285 /**
286 * Creates a SecretKeyFactory object.
287 *
288 * @param keyFacSpi the delegate
289 * @param provider the provider
290 * @param algorithm the secret-key algorithm
291 */
292 protected SecretKeyFactory(SecretKeyFactorySpi keyFacSpi,
293 Provider provider, String algorithm) {
294 this.spi = keyFacSpi;
295 this.provider = provider;
296 this.algorithm = algorithm;
297 }
298
299 private SecretKeyFactory(String algorithm) throws NoSuchAlgorithmException {
300 this.algorithm = algorithm;
Sergio Giro534b21d2016-08-23 21:19:43 +0100301 List<Service> list =
302 GetInstance.getServices("SecretKeyFactory", algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000303 serviceIterator = list.iterator();
304 // fetch and instantiate initial spi
305 if (nextSpi(null) == null) {
306 throw new NoSuchAlgorithmException
307 (algorithm + " SecretKeyFactory not available");
308 }
309 }
310
311 /**
312 * Returns a <code>SecretKeyFactory</code> object that converts
313 * secret keys of the specified algorithm.
314 *
315 * <p> This method traverses the list of registered security Providers,
316 * starting with the most preferred Provider.
317 * A new SecretKeyFactory object encapsulating the
318 * SecretKeyFactorySpi implementation from the first
319 * Provider that supports the specified algorithm is returned.
320 *
321 * <p> Note that the list of registered providers may be retrieved via
322 * the {@link Security#getProviders() Security.getProviders()} method.
323 *
324 * @param algorithm the standard name of the requested secret-key
325 * algorithm.
326 * See the SecretKeyFactory section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100327 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000328 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
329 * for information about standard algorithm names.
330 *
331 * @return the new <code>SecretKeyFactory</code> object.
332 *
333 * @exception NullPointerException if the specified algorithm
334 * is null.
335 *
336 * @exception NoSuchAlgorithmException if no Provider supports a
337 * SecretKeyFactorySpi implementation for the
338 * specified algorithm.
339 *
340 * @see java.security.Provider
341 */
342 public static final SecretKeyFactory getInstance(String algorithm)
343 throws NoSuchAlgorithmException {
344 return new SecretKeyFactory(algorithm);
345 }
346
347 /**
348 * Returns a <code>SecretKeyFactory</code> object that converts
349 * secret keys of the specified algorithm.
350 *
351 * <p> A new SecretKeyFactory object encapsulating the
352 * SecretKeyFactorySpi implementation from the specified provider
353 * is returned. The specified provider must be registered
354 * in the security provider list.
355 *
356 * <p> Note that the list of registered providers may be retrieved via
357 * the {@link Security#getProviders() Security.getProviders()} method.
358 *
359 * @param algorithm the standard name of the requested secret-key
360 * algorithm.
361 * See the SecretKeyFactory section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100362 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000363 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
364 * for information about standard algorithm names.
365 *
366 * @param provider the name of the provider.
367 *
368 * @return the new <code>SecretKeyFactory</code> object.
369 *
370 * @exception NoSuchAlgorithmException if a SecretKeyFactorySpi
371 * implementation for the specified algorithm is not
372 * available from the specified provider.
373 *
374 * @exception NullPointerException if the specified algorithm
375 * is null.
376 *
377 * @throws NoSuchProviderException if the specified provider is not
378 * registered in the security provider list.
379 *
380 * @exception IllegalArgumentException if the <code>provider</code>
381 * is null or empty.
382 *
383 * @see java.security.Provider
384 */
385 public static final SecretKeyFactory getInstance(String algorithm,
386 String provider) throws NoSuchAlgorithmException,
387 NoSuchProviderException {
Adam Vartanian491d8882017-10-10 11:43:32 +0100388 // Android-added: Check for Bouncy Castle deprecation
389 Providers.checkBouncyCastleDeprecation(provider, "SecretKeyFactory", algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000390 Instance instance = JceSecurity.getInstance("SecretKeyFactory",
391 SecretKeyFactorySpi.class, algorithm, provider);
392 return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl,
393 instance.provider, algorithm);
394 }
395
396 /**
397 * Returns a <code>SecretKeyFactory</code> object that converts
398 * secret keys of the specified algorithm.
399 *
400 * <p> A new SecretKeyFactory object encapsulating the
401 * SecretKeyFactorySpi implementation from the specified Provider
402 * object is returned. Note that the specified Provider object
403 * does not have to be registered in the provider list.
404 *
405 * @param algorithm the standard name of the requested secret-key
406 * algorithm.
407 * See the SecretKeyFactory section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100408 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000409 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
410 * for information about standard algorithm names.
411 *
412 * @param provider the provider.
413 *
414 * @return the new <code>SecretKeyFactory</code> object.
415 *
416 * @exception NullPointerException if the specified algorithm
417 * is null.
418 *
419 * @exception NoSuchAlgorithmException if a SecretKeyFactorySpi
420 * implementation for the specified algorithm is not available
421 * from the specified Provider object.
422 *
423 * @exception IllegalArgumentException if the <code>provider</code>
424 * is null.
425 *
426 * @see java.security.Provider
427 */
428 public static final SecretKeyFactory getInstance(String algorithm,
429 Provider provider) throws NoSuchAlgorithmException {
Adam Vartanian491d8882017-10-10 11:43:32 +0100430 // Android-added: Check for Bouncy Castle deprecation
431 Providers.checkBouncyCastleDeprecation(provider, "SecretKeyFactory", algorithm);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000432 Instance instance = JceSecurity.getInstance("SecretKeyFactory",
433 SecretKeyFactorySpi.class, algorithm, provider);
434 return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl,
435 instance.provider, algorithm);
436 }
437
438 /**
439 * Returns the provider of this <code>SecretKeyFactory</code> object.
440 *
441 * @return the provider of this <code>SecretKeyFactory</code> object
442 */
443 public final Provider getProvider() {
444 synchronized (lock) {
445 // disable further failover after this call
446 serviceIterator = null;
447 return provider;
448 }
449 }
450
451 /**
452 * Returns the algorithm name of this <code>SecretKeyFactory</code> object.
453 *
454 * <p>This is the same name that was specified in one of the
455 * <code>getInstance</code> calls that created this
456 * <code>SecretKeyFactory</code> object.
457 *
458 * @return the algorithm name of this <code>SecretKeyFactory</code>
459 * object.
460 */
461 public final String getAlgorithm() {
462 return this.algorithm;
463 }
464
465 /**
466 * Update the active spi of this class and return the next
467 * implementation for failover. If no more implemenations are
468 * available, this method returns null. However, the active spi of
469 * this class is never set to null.
470 */
471 private SecretKeyFactorySpi nextSpi(SecretKeyFactorySpi oldSpi) {
472 synchronized (lock) {
473 // somebody else did a failover concurrently
474 // try that spi now
475 if ((oldSpi != null) && (oldSpi != spi)) {
476 return spi;
477 }
478 if (serviceIterator == null) {
479 return null;
480 }
481 while (serviceIterator.hasNext()) {
Sergio Giro534b21d2016-08-23 21:19:43 +0100482 Service s = serviceIterator.next();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000483 if (JceSecurity.canUseProvider(s.getProvider()) == false) {
484 continue;
485 }
486 try {
487 Object obj = s.newInstance(null);
488 if (obj instanceof SecretKeyFactorySpi == false) {
489 continue;
490 }
491 SecretKeyFactorySpi spi = (SecretKeyFactorySpi)obj;
492 provider = s.getProvider();
493 this.spi = spi;
494 return spi;
495 } catch (NoSuchAlgorithmException e) {
496 // ignore
497 }
498 }
499 serviceIterator = null;
500 return null;
501 }
502 }
503
504 /**
505 * Generates a <code>SecretKey</code> object from the provided key
506 * specification (key material).
507 *
508 * @param keySpec the specification (key material) of the secret key
509 *
510 * @return the secret key
511 *
512 * @exception InvalidKeySpecException if the given key specification
513 * is inappropriate for this secret-key factory to produce a secret key.
514 */
515 public final SecretKey generateSecret(KeySpec keySpec)
516 throws InvalidKeySpecException {
517 if (serviceIterator == null) {
518 return spi.engineGenerateSecret(keySpec);
519 }
520 Exception failure = null;
521 SecretKeyFactorySpi mySpi = spi;
522 do {
523 try {
524 return mySpi.engineGenerateSecret(keySpec);
525 } catch (Exception e) {
526 if (failure == null) {
527 failure = e;
528 }
529 mySpi = nextSpi(mySpi);
530 }
531 } while (mySpi != null);
532 if (failure instanceof InvalidKeySpecException) {
533 throw (InvalidKeySpecException)failure;
534 }
535 throw new InvalidKeySpecException
536 ("Could not generate secret key", failure);
537 }
538
539 /**
540 * Returns a specification (key material) of the given key object
541 * in the requested format.
542 *
543 * @param key the key
544 * @param keySpec the requested format in which the key material shall be
545 * returned
546 *
547 * @return the underlying key specification (key material) in the
548 * requested format
549 *
550 * @exception InvalidKeySpecException if the requested key specification is
551 * inappropriate for the given key (e.g., the algorithms associated with
552 * <code>key</code> and <code>keySpec</code> do not match, or
553 * <code>key</code> references a key on a cryptographic hardware device
554 * whereas <code>keySpec</code> is the specification of a software-based
555 * key), or the given key cannot be dealt with
556 * (e.g., the given key has an algorithm or format not supported by this
557 * secret-key factory).
558 */
Sergio Giro534b21d2016-08-23 21:19:43 +0100559 public final KeySpec getKeySpec(SecretKey key, Class<?> keySpec)
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000560 throws InvalidKeySpecException {
561 if (serviceIterator == null) {
562 return spi.engineGetKeySpec(key, keySpec);
563 }
564 Exception failure = null;
565 SecretKeyFactorySpi mySpi = spi;
566 do {
567 try {
568 return mySpi.engineGetKeySpec(key, keySpec);
569 } catch (Exception e) {
570 if (failure == null) {
571 failure = e;
572 }
573 mySpi = nextSpi(mySpi);
574 }
575 } while (mySpi != null);
576 if (failure instanceof InvalidKeySpecException) {
577 throw (InvalidKeySpecException)failure;
578 }
579 throw new InvalidKeySpecException
580 ("Could not get key spec", failure);
581 }
582
583 /**
584 * Translates a key object, whose provider may be unknown or potentially
585 * untrusted, into a corresponding key object of this secret-key factory.
586 *
587 * @param key the key whose provider is unknown or untrusted
588 *
589 * @return the translated key
590 *
591 * @exception InvalidKeyException if the given key cannot be processed
592 * by this secret-key factory.
593 */
594 public final SecretKey translateKey(SecretKey key)
595 throws InvalidKeyException {
596 if (serviceIterator == null) {
597 return spi.engineTranslateKey(key);
598 }
599 Exception failure = null;
600 SecretKeyFactorySpi mySpi = spi;
601 do {
602 try {
603 return mySpi.engineTranslateKey(key);
604 } catch (Exception e) {
605 if (failure == null) {
606 failure = e;
607 }
608 mySpi = nextSpi(mySpi);
609 }
610 } while (mySpi != null);
611 if (failure instanceof InvalidKeyException) {
612 throw (InvalidKeyException)failure;
613 }
614 throw new InvalidKeyException
615 ("Could not translate key", failure);
616 }
617}