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