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