Home | History | Annotate | Download | only in crypto
      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.InvalidKeyException;
     21 import java.security.NoSuchAlgorithmException;
     22 import java.security.NoSuchProviderException;
     23 import java.security.Provider;
     24 import java.security.Security;
     25 import java.security.spec.InvalidKeySpecException;
     26 import java.security.spec.KeySpec;
     27 import org.apache.harmony.security.fortress.Engine;
     28 
     29 
     30 /**
     31  * The public API for {@code SecretKeyFactory} implementations.
     32  * <p>
     33  * Secret key factories provide the following functionality:
     34  * <ul>
     35  * <li>convert {@link SecretKey} objects to and from {@link KeySpec} objects</li>
     36  * <li>translate {@link SecretKey} objects from one provider implementation to
     37  * another</li>
     38  * </ul>
     39  * Which key specifications are supported by the {@link #generateSecret} and
     40  * {@link #getKeySpec} is provider dependent.
     41  */
     42 public class SecretKeyFactory {
     43 
     44     // Used to access common engine functionality
     45     private static final Engine ENGINE = new Engine("SecretKeyFactory");
     46 
     47     // Store used provider
     48     private final Provider provider;
     49 
     50     // Store used spi implementation
     51     private final SecretKeyFactorySpi spiImpl;
     52 
     53     // Store used algorithm name
     54     private final String algorithm;
     55 
     56     /**
     57      * Creates a new {@code SecretKeyFactory}
     58      *
     59      * @param keyFacSpi
     60      *            the SPI delegate.
     61      * @param provider
     62      *            the provider providing this key factory.
     63      * @param algorithm
     64      *            the algorithm name for the secret key.
     65      */
     66     protected SecretKeyFactory(SecretKeyFactorySpi keyFacSpi,
     67             Provider provider, String algorithm) {
     68         this.provider = provider;
     69         this.algorithm = algorithm;
     70         this.spiImpl = keyFacSpi;
     71     }
     72 
     73     /**
     74      * Returns the name of the secret key algorithm.
     75      *
     76      * @return the name of the secret key algorithm.
     77      */
     78     public final String getAlgorithm() {
     79         return algorithm;
     80     }
     81 
     82     /**
     83      * Returns the provider for this {@code SecretKeyFactory} instance.
     84      *
     85      * @return the provider for this {@code SecretKeyFactory} instance.
     86      */
     87     public final Provider getProvider() {
     88         return provider;
     89     }
     90 
     91     /**
     92      * Creates a new {@code SecretKeyFactory} instance for the specified key
     93      * algorithm.
     94      *
     95      * @param algorithm
     96      *            the name of the key algorithm.
     97      * @return a secret key factory for the specified key algorithm.
     98      * @throws NoSuchAlgorithmException
     99      *             if no installed provider can provide the requested algorithm.
    100      * @throws NullPointerException
    101      *             if the specified algorithm is {@code null}.
    102      */
    103     public static final SecretKeyFactory getInstance(String algorithm)
    104             throws NoSuchAlgorithmException {
    105         if (algorithm == null) {
    106             throw new NullPointerException("algorithm == null");
    107         }
    108         Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
    109         return new SecretKeyFactory((SecretKeyFactorySpi) sap.spi, sap.provider, algorithm);
    110     }
    111 
    112     /**
    113      * Creates a new {@code SecretKeyFactory} instance for the specified key
    114      * algorithm from the specified {@code provider}.
    115      *
    116      * @param algorithm
    117      *            the name of the key algorithm.
    118      * @param provider
    119      *            the name of the provider that provides the requested
    120      *            algorithm.
    121      * @return a secret key factory for the specified key algorithm from the
    122      *         specified provider.
    123      * @throws NoSuchAlgorithmException
    124      *             if the specified provider cannot provide the requested
    125      *             algorithm.
    126      * @throws NoSuchProviderException
    127      *             if the specified provider does not exist.
    128      * @throws IllegalArgumentException
    129      *             if the specified provider name is {@code null} or empty.
    130      */
    131     public static final SecretKeyFactory getInstance(String algorithm,
    132             String provider) throws NoSuchAlgorithmException,
    133             NoSuchProviderException {
    134         if (provider == null || provider.isEmpty()) {
    135             throw new IllegalArgumentException("Provider is null or empty");
    136         }
    137         Provider impProvider = Security.getProvider(provider);
    138         if (impProvider == null) {
    139             throw new NoSuchProviderException(provider);
    140         }
    141         return getInstance(algorithm, impProvider);
    142     }
    143 
    144     /**
    145      * Creates a new {@code SecretKeyFactory} instance for the specified key
    146      * algorithm from the specified provider. The {@code provider} supplied
    147      * does not have to be registered.
    148      *
    149      * @param algorithm
    150      *            the name of the key algorithm.
    151      * @param provider
    152      *            the provider that provides the requested algorithm.
    153      * @return a secret key factory for the specified key algorithm from the
    154      *         specified provider.
    155      * @throws NoSuchAlgorithmException
    156      *             if the specified provider cannot provider the requested
    157      *             algorithm.
    158      * @throws IllegalArgumentException
    159      *             if the specified provider is {@code null}.
    160      * @throws NullPointerException
    161      *             is the specified algorithm name is {@code null}.
    162      */
    163     public static final SecretKeyFactory getInstance(String algorithm,
    164             Provider provider) throws NoSuchAlgorithmException {
    165         if (provider == null) {
    166             throw new IllegalArgumentException("provider == null");
    167         }
    168         if (algorithm == null) {
    169             throw new NullPointerException("algorithm == null");
    170         }
    171         Object spi = ENGINE.getInstance(algorithm, provider, null);
    172         return new SecretKeyFactory((SecretKeyFactorySpi) spi, provider, algorithm);
    173     }
    174 
    175     /**
    176      * Generate a secret key from the specified key specification.
    177      *
    178      * @param keySpec
    179      *            the key specification.
    180      * @return a secret key.
    181      * @throws InvalidKeySpecException
    182      *             if the specified key specification cannot be used to generate
    183      *             a secret key.
    184      */
    185     public final SecretKey generateSecret(KeySpec keySpec)
    186             throws InvalidKeySpecException {
    187         return spiImpl.engineGenerateSecret(keySpec);
    188     }
    189 
    190     /**
    191      * Returns the key specification of the specified secret key.
    192      *
    193      * @param key
    194      *            the secret key to get the specification from.
    195      * @param keySpec
    196      *            the target key specification class.
    197      * @return an instance of the specified key specification class.
    198      * @throws InvalidKeySpecException
    199      *             if the specified secret key cannot be transformed into the
    200      *             requested key specification.
    201      */
    202     @SuppressWarnings("unchecked")
    203     public final KeySpec getKeySpec(SecretKey key, Class keySpec)
    204             throws InvalidKeySpecException {
    205         return spiImpl.engineGetKeySpec(key, keySpec);
    206     }
    207 
    208     /**
    209      * Translates the specified secret key into an instance of the corresponding
    210      * key from the provider of this key factory.
    211      *
    212      * @param key
    213      *            the secret key to translate.
    214      * @return the corresponding translated key.
    215      * @throws InvalidKeyException
    216      *             if the specified key cannot be translated using this key
    217      *             factory.
    218      */
    219     public final SecretKey translateKey(SecretKey key)
    220             throws InvalidKeyException {
    221         return spiImpl.engineTranslateKey(key);
    222 
    223     }
    224 }
    225