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