1 /* 2 * Copyright (c) 1999, 2007, 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.net.ssl; 27 28 import java.security.Security; 29 import java.security.*; 30 31 import sun.security.jca.GetInstance; 32 33 /** 34 * This class acts as a factory for key managers based on a 35 * source of key material. Each key manager manages a specific 36 * type of key material for use by secure sockets. The key 37 * material is based on a KeyStore and/or provider specific sources. 38 * 39 * @since 1.4 40 * @see KeyManager 41 */ 42 public class KeyManagerFactory { 43 // The provider 44 private Provider provider; 45 46 // The provider implementation (delegate) 47 private KeyManagerFactorySpi factorySpi; 48 49 // The name of the key management algorithm. 50 private String algorithm; 51 52 /** 53 * Obtains the default KeyManagerFactory algorithm name. 54 * 55 * <p>The default algorithm can be changed at runtime by setting 56 * the value of the "ssl.KeyManagerFactory.algorithm" security 57 * property (set in the Java security properties file or by calling 58 * {@link java.security.Security#setProperty(java.lang.String, 59 * java.lang.String)}) 60 * to the desired algorithm name. 61 * 62 * @see java.security.Security#setProperty(java.lang.String, 63 * java.lang.String) 64 * @return the default algorithm name as specified in the 65 * Java security properties, or an implementation-specific 66 * default if no such property exists. 67 */ 68 public final static String getDefaultAlgorithm() { 69 String type; 70 type = AccessController.doPrivileged(new PrivilegedAction<String>() { 71 public String run() { 72 return Security.getProperty( 73 "ssl.KeyManagerFactory.algorithm"); 74 } 75 }); 76 if (type == null) { 77 type = "SunX509"; 78 } 79 return type; 80 } 81 82 /** 83 * Creates a KeyManagerFactory object. 84 * 85 * @param factorySpi the delegate 86 * @param provider the provider 87 * @param algorithm the algorithm 88 */ 89 protected KeyManagerFactory(KeyManagerFactorySpi factorySpi, 90 Provider provider, String algorithm) { 91 this.factorySpi = factorySpi; 92 this.provider = provider; 93 this.algorithm = algorithm; 94 } 95 96 /** 97 * Returns the algorithm name of this <code>KeyManagerFactory</code> object. 98 * 99 * <p>This is the same name that was specified in one of the 100 * <code>getInstance</code> calls that created this 101 * <code>KeyManagerFactory</code> object. 102 * 103 * @return the algorithm name of this <code>KeyManagerFactory</code> object. 104 */ 105 public final String getAlgorithm() { 106 return this.algorithm; 107 } 108 109 /** 110 * Returns a <code>KeyManagerFactory</code> object that acts as a 111 * factory for key managers. 112 * 113 * <p> This method traverses the list of registered security Providers, 114 * starting with the most preferred Provider. 115 * A new KeyManagerFactory object encapsulating the 116 * KeyManagerFactorySpi implementation from the first 117 * Provider that supports the specified algorithm is returned. 118 * 119 * <p> Note that the list of registered providers may be retrieved via 120 * the {@link Security#getProviders() Security.getProviders()} method. 121 * 122 * @param algorithm the standard name of the requested algorithm. 123 * See the <a href= 124 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html"> 125 * Java Secure Socket Extension Reference Guide </a> 126 * for information about standard algorithm names. 127 * 128 * @return the new <code>KeyManagerFactory</code> object. 129 * 130 * @exception NoSuchAlgorithmException if no Provider supports a 131 * KeyManagerFactorySpi implementation for the 132 * specified algorithm. 133 * @exception NullPointerException if <code>algorithm</code> is null. 134 * 135 * @see java.security.Provider 136 */ 137 public static final KeyManagerFactory getInstance(String algorithm) 138 throws NoSuchAlgorithmException { 139 GetInstance.Instance instance = GetInstance.getInstance 140 ("KeyManagerFactory", KeyManagerFactorySpi.class, 141 algorithm); 142 return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl, 143 instance.provider, algorithm); 144 } 145 146 /** 147 * Returns a <code>KeyManagerFactory</code> object that acts as a 148 * factory for key managers. 149 * 150 * <p> A new KeyManagerFactory object encapsulating the 151 * KeyManagerFactorySpi implementation from the specified provider 152 * is returned. The specified provider must be registered 153 * in the security provider list. 154 * 155 * <p> Note that the list of registered providers may be retrieved via 156 * the {@link Security#getProviders() Security.getProviders()} method. 157 158 * @param algorithm the standard name of the requested algorithm. 159 * See the <a href= 160 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html"> 161 * Java Secure Socket Extension Reference Guide </a> 162 * for information about standard algorithm names. 163 * 164 * @param provider the name of the provider. 165 * 166 * @return the new <code>KeyManagerFactory</code> object. 167 * 168 * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi 169 * implementation for the specified algorithm is not 170 * available from the specified provider. 171 * 172 * @throws NoSuchProviderException if the specified provider is not 173 * registered in the security provider list. 174 * 175 * @throws IllegalArgumentException if the provider name is null or empty. 176 * @throws NullPointerException if <code>algorithm</code> is null. 177 * 178 * @see java.security.Provider 179 */ 180 public static final KeyManagerFactory getInstance(String algorithm, 181 String provider) throws NoSuchAlgorithmException, 182 NoSuchProviderException { 183 GetInstance.Instance instance = GetInstance.getInstance 184 ("KeyManagerFactory", KeyManagerFactorySpi.class, 185 algorithm, provider); 186 return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl, 187 instance.provider, algorithm); 188 } 189 190 /** 191 * Returns a <code>KeyManagerFactory</code> object that acts as a 192 * factory for key managers. 193 * 194 * <p> A new KeyManagerFactory object encapsulating the 195 * KeyManagerFactorySpi implementation from the specified Provider 196 * object is returned. Note that the specified Provider object 197 * does not have to be registered in the provider list. 198 * 199 * @param algorithm the standard name of the requested algorithm. 200 * See the <a href= 201 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html"> 202 * Java Secure Socket Extension Reference Guide </a> 203 * for information about standard algorithm names. 204 * 205 * @param provider an instance of the provider. 206 * 207 * @return the new <code>KeyManagerFactory</code> object. 208 * 209 * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi 210 * implementation for the specified algorithm is not available 211 * from the specified Provider object. 212 * 213 * @throws IllegalArgumentException if provider is null. 214 * @throws NullPointerException if <code>algorithm</code> is null. 215 * 216 * @see java.security.Provider 217 */ 218 public static final KeyManagerFactory getInstance(String algorithm, 219 Provider provider) throws NoSuchAlgorithmException { 220 GetInstance.Instance instance = GetInstance.getInstance 221 ("KeyManagerFactory", KeyManagerFactorySpi.class, 222 algorithm, provider); 223 return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl, 224 instance.provider, algorithm); 225 } 226 227 /** 228 * Returns the provider of this <code>KeyManagerFactory</code> object. 229 * 230 * @return the provider of this <code>KeyManagerFactory</code> object 231 */ 232 public final Provider getProvider() { 233 return this.provider; 234 } 235 236 237 /** 238 * Initializes this factory with a source of key material. 239 * <P> 240 * The provider typically uses a KeyStore for obtaining 241 * key material for use during secure socket negotiations. 242 * The KeyStore is generally password-protected. 243 * <P> 244 * For more flexible initialization, please see 245 * {@link #init(ManagerFactoryParameters)}. 246 * <P> 247 * 248 * @param ks the key store or null 249 * @param password the password for recovering keys in the KeyStore 250 * @throws KeyStoreException if this operation fails 251 * @throws NoSuchAlgorithmException if the specified algorithm is not 252 * available from the specified provider. 253 * @throws UnrecoverableKeyException if the key cannot be recovered 254 * (e.g. the given password is wrong). 255 */ 256 public final void init(KeyStore ks, char[] password) throws 257 KeyStoreException, NoSuchAlgorithmException, 258 UnrecoverableKeyException { 259 factorySpi.engineInit(ks, password); 260 } 261 262 263 /** 264 * Initializes this factory with a source of provider-specific 265 * key material. 266 * <P> 267 * In some cases, initialization parameters other than a keystore 268 * and password may be needed by a provider. Users of that 269 * particular provider are expected to pass an implementation of 270 * the appropriate <CODE>ManagerFactoryParameters</CODE> as 271 * defined by the provider. The provider can then call the 272 * specified methods in the <CODE>ManagerFactoryParameters</CODE> 273 * implementation to obtain the needed information. 274 * 275 * @param spec an implementation of a provider-specific parameter 276 * specification 277 * @throws InvalidAlgorithmParameterException if an error is encountered 278 */ 279 public final void init(ManagerFactoryParameters spec) throws 280 InvalidAlgorithmParameterException { 281 factorySpi.engineInit(spec); 282 } 283 284 285 /** 286 * Returns one key manager for each type of key material. 287 * 288 * @return the key managers 289 * @throws IllegalStateException if the KeyManagerFactory is not initialized 290 */ 291 public final KeyManager[] getKeyManagers() { 292 return factorySpi.engineGetKeyManagers(); 293 } 294 } 295