Frames | No Frames |
1: /* KeyFactory.java --- Key Factory Class 2: Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.security; 40: 41: import gnu.java.lang.CPStringBuilder; 42: 43: import gnu.java.security.Engine; 44: 45: import java.lang.reflect.InvocationTargetException; 46: import java.security.spec.InvalidKeySpecException; 47: import java.security.spec.KeySpec; 48: 49: /** 50: * Key factories are used to convert keys (opaque cryptographic keys of type 51: * {@link Key}) into key specifications (transparent representations of the 52: * underlying key material). 53: * 54: * <p>Key factories are bi-directional. They allow a key class to be converted 55: * into a key specification (key material) and back again. For example DSA 56: * public keys can be specified as <code>DSAPublicKeySpec</code> or 57: * <code>X509EncodedKeySpec</code>. A key factory translates these key 58: * specifications.</p> 59: * 60: * @since 1.2 61: * @see Key 62: * @see KeySpec 63: * @see java.security.spec.DSAPublicKeySpec 64: * @see java.security.spec.X509EncodedKeySpec 65: @author Mark Benvenuto 66: */ 67: public class KeyFactory 68: { 69: /** The service name for key factories. */ 70: private static final String KEY_FACTORY = "KeyFactory"; 71: 72: private KeyFactorySpi keyFacSpi; 73: private Provider provider; 74: private String algorithm; 75: 76: /** 77: * Constructs a new instance of <code>KeyFactory</code> with the specified 78: * parameters. 79: * 80: * @param keyFacSpi 81: * the key factory to use. 82: * @param provider 83: * the provider to use. 84: * @param algorithm 85: * the name of the key algorithm to use. 86: */ 87: protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider, 88: String algorithm) 89: { 90: this.keyFacSpi = keyFacSpi; 91: this.provider = provider; 92: this.algorithm = algorithm; 93: } 94: 95: /** 96: * Returns a new instance of <code>KeyFactory</code> representing the 97: * specified key factory. 98: * 99: * @param algorithm the name of algorithm to use. 100: * @return a new instance repesenting the desired algorithm. 101: * @throws NoSuchAlgorithmException if the algorithm is not implemented by any 102: * provider. 103: * @throws IllegalArgumentException if <code>algorithm</code> is 104: * <code>null</code> or is an empty string. 105: */ 106: public static KeyFactory getInstance(String algorithm) 107: throws NoSuchAlgorithmException 108: { 109: Provider[] p = Security.getProviders(); 110: NoSuchAlgorithmException lastException = null; 111: for (int i = 0; i < p.length; i++) 112: try 113: { 114: return getInstance(algorithm, p[i]); 115: } 116: catch (NoSuchAlgorithmException x) 117: { 118: lastException = x; 119: } 120: if (lastException != null) 121: throw lastException; 122: throw new NoSuchAlgorithmException(algorithm); 123: } 124: 125: /** 126: * Returns a new instance of <code>KeyFactory</code> representing the 127: * specified key factory from the specified provider. 128: * 129: * @param algorithm the name of algorithm to use. 130: * @param provider the name of the provider to use. 131: * @return a new instance repesenting the desired algorithm. 132: * @throws NoSuchAlgorithmException if the algorithm is not implemented by the 133: * named provider. 134: * @throws NoSuchProviderException if the named provider was not found. 135: * @throws IllegalArgumentException if either <code>algorithm</code> or 136: * <code>provider</code> is <code>null</code> or empty. 137: */ 138: public static KeyFactory getInstance(String algorithm, String provider) 139: throws NoSuchAlgorithmException, NoSuchProviderException 140: { 141: if (provider == null) 142: throw new IllegalArgumentException("provider MUST NOT be null"); 143: provider = provider.trim(); 144: if (provider.length() == 0) 145: throw new IllegalArgumentException("provider MUST NOT be empty"); 146: Provider p = Security.getProvider(provider); 147: if (p == null) 148: throw new NoSuchProviderException(provider); 149: return getInstance(algorithm, p); 150: } 151: 152: /** 153: * Returns a new instance of <code>KeyFactory</code> representing the 154: * specified key factory from the designated {@link Provider}. 155: * 156: * @param algorithm the name of algorithm to use. 157: * @param provider the {@link Provider} to use. 158: * @return a new instance repesenting the desired algorithm. 159: * @throws NoSuchAlgorithmException if the algorithm is not implemented by 160: * {@link Provider}. 161: * @throws IllegalArgumentException if either <code>algorithm</code> or 162: * <code>provider</code> is <code>null</code>, or if 163: * <code>algorithm</code> is an empty string. 164: * @since 1.4 165: * @see Provider 166: */ 167: public static KeyFactory getInstance(String algorithm, Provider provider) 168: throws NoSuchAlgorithmException 169: { 170: CPStringBuilder sb = new CPStringBuilder("KeyFactory for algorithm [") 171: .append(algorithm).append("] from provider[") 172: .append(provider).append("] could not be created"); 173: Throwable cause; 174: try 175: { 176: Object spi = Engine.getInstance(KEY_FACTORY, algorithm, provider); 177: return new KeyFactory((KeyFactorySpi) spi, provider, algorithm); 178: } 179: catch (InvocationTargetException x) 180: { 181: cause = x.getCause(); 182: if (cause instanceof NoSuchAlgorithmException) 183: throw (NoSuchAlgorithmException) cause; 184: if (cause == null) 185: cause = x; 186: } 187: catch (ClassCastException x) 188: { 189: cause = x; 190: } 191: NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString()); 192: x.initCause(cause); 193: throw x; 194: } 195: 196: /** 197: * Returns the {@link Provider} of this instance. 198: * 199: * @return the {@link Provider} of this instance. 200: */ 201: public final Provider getProvider() 202: { 203: return provider; 204: } 205: 206: /** 207: * Returns the name of the algorithm used. 208: * 209: * @return the name of the algorithm used. 210: */ 211: public final String getAlgorithm() 212: { 213: return algorithm; 214: } 215: 216: /** 217: * Generates a public key from the provided key specification. 218: * 219: * @param keySpec 220: * the key specification. 221: * @return the public key. 222: * @throws InvalidKeySpecException 223: * if the key specification is invalid. 224: */ 225: public final PublicKey generatePublic(KeySpec keySpec) 226: throws InvalidKeySpecException 227: { 228: return keyFacSpi.engineGeneratePublic(keySpec); 229: } 230: 231: /** 232: * Generates a private key from the provided key specification. 233: * 234: * @param keySpec 235: * the key specification. 236: * @return the private key. 237: * @throws InvalidKeySpecException 238: * if the key specification is invalid. 239: */ 240: public final PrivateKey generatePrivate(KeySpec keySpec) 241: throws InvalidKeySpecException 242: { 243: return keyFacSpi.engineGeneratePrivate(keySpec); 244: } 245: 246: /** 247: * Returns a key specification for the given key. <code>keySpec</code> 248: * identifies the specification class to return the key material in. 249: * 250: * @param key 251: * the key to use. 252: * @param keySpec 253: * the specification class to use. 254: * @return the key specification in an instance of the requested specification 255: * class. 256: * @throws InvalidKeySpecException 257: * the requested key specification is inappropriate for this key or 258: * the key is unrecognized. 259: */ 260: public final <T extends KeySpec> T getKeySpec(Key key, Class<T> keySpec) 261: throws InvalidKeySpecException 262: { 263: return keyFacSpi.engineGetKeySpec(key, keySpec); 264: } 265: 266: /** 267: * Translates the key from an unknown or untrusted provider into a key from 268: * this key factory. 269: * 270: * @param key 271: * the key to translate from. 272: * @return the translated key. 273: * @throws InvalidKeyException 274: * if the key cannot be processed by this key factory. 275: */ 276: public final Key translateKey(Key key) throws InvalidKeyException 277: { 278: return keyFacSpi.engineTranslateKey(key); 279: } 280: }