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