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 18package javax.crypto; 19 20import java.security.InvalidKeyException; 21import java.security.NoSuchAlgorithmException; 22import java.security.NoSuchProviderException; 23import java.security.Provider; 24import java.security.Security; 25import java.security.spec.InvalidKeySpecException; 26import java.security.spec.KeySpec; 27import 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 */ 42public 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. 147 * 148 * @param algorithm 149 * the name of the key algorithm. 150 * @param provider 151 * the provider that provides the requested algorithm. 152 * @return a secret key factory for the specified key algorithm from the 153 * specified provider. 154 * @throws NoSuchAlgorithmException 155 * if the specified provider cannot provider the requested 156 * algorithm. 157 * @throws IllegalArgumentException 158 * if the specified provider is {@code null}. 159 * @throws NullPointerException 160 * is the specified algorithm name is {@code null}. 161 */ 162 public static final SecretKeyFactory getInstance(String algorithm, 163 Provider provider) throws NoSuchAlgorithmException { 164 if (provider == null) { 165 throw new IllegalArgumentException("provider == null"); 166 } 167 if (algorithm == null) { 168 throw new NullPointerException("algorithm == null"); 169 } 170 Object spi = ENGINE.getInstance(algorithm, provider, null); 171 return new SecretKeyFactory((SecretKeyFactorySpi) spi, provider, algorithm); 172 } 173 174 /** 175 * Generate a secret key from the specified key specification. 176 * 177 * @param keySpec 178 * the key specification. 179 * @return a secret key. 180 * @throws InvalidKeySpecException 181 * if the specified key specification cannot be used to generate 182 * a secret key. 183 */ 184 public final SecretKey generateSecret(KeySpec keySpec) 185 throws InvalidKeySpecException { 186 return spiImpl.engineGenerateSecret(keySpec); 187 } 188 189 /** 190 * Returns the key specification of the specified secret key. 191 * 192 * @param key 193 * the secret key to get the specification from. 194 * @param keySpec 195 * the target key specification class. 196 * @return an instance of the specified key specification class. 197 * @throws InvalidKeySpecException 198 * if the specified secret key cannot be transformed into the 199 * requested key specification. 200 */ 201 @SuppressWarnings("unchecked") 202 public final KeySpec getKeySpec(SecretKey key, Class keySpec) 203 throws InvalidKeySpecException { 204 return spiImpl.engineGetKeySpec(key, keySpec); 205 } 206 207 /** 208 * Translates the specified secret key into an instance of the corresponding 209 * key from the provider of this key factory. 210 * 211 * @param key 212 * the secret key to translate. 213 * @return the corresponding translated key. 214 * @throws InvalidKeyException 215 * if the specified key cannot be translated using this key 216 * factory. 217 */ 218 public final SecretKey translateKey(SecretKey key) 219 throws InvalidKeyException { 220 return spiImpl.engineTranslateKey(key); 221 222 } 223} 224