1 /*
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 
26 package javax.crypto;
27 
28 import java.util.*;
29 
30 import java.security.*;
31 import java.security.Provider.Service;
32 import java.security.spec.*;
33 
34 import sun.security.jca.*;
35 import 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  *
61  * <p> Android provides the following <code>SecretKeyFactory</code> algorithms:
62  * <table>
63  *   <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>
251  * </table>
252  *
253  * These algorithms are described in the <a href=
254  * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
255  * SecretKeyFactory section</a> of the
256  * Java Cryptography Architecture Standard Algorithm Name Documentation.
257  *
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 
267 public 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
283     private Iterator<Service> serviceIterator;
284 
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      */
SecretKeyFactory(SecretKeyFactorySpi keyFacSpi, Provider provider, String algorithm)292     protected SecretKeyFactory(SecretKeyFactorySpi keyFacSpi,
293                                Provider provider, String algorithm) {
294         this.spi = keyFacSpi;
295         this.provider = provider;
296         this.algorithm = algorithm;
297     }
298 
SecretKeyFactory(String algorithm)299     private SecretKeyFactory(String algorithm) throws NoSuchAlgorithmException {
300         this.algorithm = algorithm;
301         List<Service> list =
302                 GetInstance.getServices("SecretKeyFactory", algorithm);
303         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=
327      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
328      * 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      */
getInstance(String algorithm)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=
362      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
363      * 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      */
getInstance(String algorithm, String provider)385     public static final SecretKeyFactory getInstance(String algorithm,
386             String provider) throws NoSuchAlgorithmException,
387             NoSuchProviderException {
388         // Android-added: Check for Bouncy Castle deprecation
389         Providers.checkBouncyCastleDeprecation(provider, "SecretKeyFactory", algorithm);
390         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=
408      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
409      * 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      */
getInstance(String algorithm, Provider provider)428     public static final SecretKeyFactory getInstance(String algorithm,
429             Provider provider) throws NoSuchAlgorithmException {
430         // Android-added: Check for Bouncy Castle deprecation
431         Providers.checkBouncyCastleDeprecation(provider, "SecretKeyFactory", algorithm);
432         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      */
getProvider()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      */
getAlgorithm()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      */
nextSpi(SecretKeyFactorySpi oldSpi)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()) {
482                 Service s = serviceIterator.next();
483                 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      */
generateSecret(KeySpec keySpec)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      */
getKeySpec(SecretKey key, Class<?> keySpec)559     public final KeySpec getKeySpec(SecretKey key, Class<?> keySpec)
560             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      */
translateKey(SecretKey key)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 }
618