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 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} 122 * {@link Security#getProperty(String) Security} property to determine 123 * the preferred provider order for the specified algorithm. This 124 * may be different than the order of providers returned by 125 * {@link Security#getProviders() Security.getProviders()}. 126 * 127 * @param algorithm the standard name of the requested algorithm. 128 * See the <a href= 129 * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html"> 130 * Java Secure Socket Extension Reference Guide </a> 131 * for information about standard algorithm names. 132 * 133 * @return the new <code>KeyManagerFactory</code> object. 134 * 135 * @exception NoSuchAlgorithmException if no Provider supports a 136 * KeyManagerFactorySpi implementation for the 137 * specified algorithm. 138 * @exception NullPointerException if <code>algorithm</code> is null. 139 * 140 * @see java.security.Provider 141 */ 142 public static final KeyManagerFactory getInstance(String algorithm) 143 throws NoSuchAlgorithmException { 144 GetInstance.Instance instance = GetInstance.getInstance 145 ("KeyManagerFactory", KeyManagerFactorySpi.class, 146 algorithm); 147 return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl, 148 instance.provider, algorithm); 149 } 150 151 /** 152 * Returns a <code>KeyManagerFactory</code> object that acts as a 153 * factory for key managers. 154 * 155 * <p> A new KeyManagerFactory object encapsulating the 156 * KeyManagerFactorySpi implementation from the specified provider 157 * is returned. The specified provider must be registered 158 * in the security provider list. 159 * 160 * <p> Note that the list of registered providers may be retrieved via 161 * the {@link Security#getProviders() Security.getProviders()} method. 162 163 * @param algorithm the standard name of the requested algorithm. 164 * See the <a href= 165 * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html"> 166 * Java Secure Socket Extension Reference Guide </a> 167 * for information about standard algorithm names. 168 * 169 * @param provider the name of the provider. 170 * 171 * @return the new <code>KeyManagerFactory</code> object. 172 * 173 * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi 174 * implementation for the specified algorithm is not 175 * available from the specified provider. 176 * 177 * @throws NoSuchProviderException if the specified provider is not 178 * registered in the security provider list. 179 * 180 * @throws IllegalArgumentException if the provider name is null or empty. 181 * @throws NullPointerException if <code>algorithm</code> is null. 182 * 183 * @see java.security.Provider 184 */ 185 public static final KeyManagerFactory getInstance(String algorithm, 186 String provider) throws NoSuchAlgorithmException, 187 NoSuchProviderException { 188 GetInstance.Instance instance = GetInstance.getInstance 189 ("KeyManagerFactory", KeyManagerFactorySpi.class, 190 algorithm, provider); 191 return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl, 192 instance.provider, algorithm); 193 } 194 195 /** 196 * Returns a <code>KeyManagerFactory</code> object that acts as a 197 * factory for key managers. 198 * 199 * <p> A new KeyManagerFactory object encapsulating the 200 * KeyManagerFactorySpi implementation from the specified Provider 201 * object is returned. Note that the specified Provider object 202 * does not have to be registered in the provider list. 203 * 204 * @param algorithm the standard name of the requested algorithm. 205 * See the <a href= 206 * "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html"> 207 * Java Secure Socket Extension Reference Guide </a> 208 * for information about standard algorithm names. 209 * 210 * @param provider an instance of the provider. 211 * 212 * @return the new <code>KeyManagerFactory</code> object. 213 * 214 * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi 215 * implementation for the specified algorithm is not available 216 * from the specified Provider object. 217 * 218 * @throws IllegalArgumentException if provider is null. 219 * @throws NullPointerException if <code>algorithm</code> is null. 220 * 221 * @see java.security.Provider 222 */ 223 public static final KeyManagerFactory getInstance(String algorithm, 224 Provider provider) throws NoSuchAlgorithmException { 225 GetInstance.Instance instance = GetInstance.getInstance 226 ("KeyManagerFactory", KeyManagerFactorySpi.class, 227 algorithm, provider); 228 return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl, 229 instance.provider, algorithm); 230 } 231 232 /** 233 * Returns the provider of this <code>KeyManagerFactory</code> object. 234 * 235 * @return the provider of this <code>KeyManagerFactory</code> object 236 */ 237 public final Provider getProvider() { 238 return this.provider; 239 } 240 241 242 /** 243 * Initializes this factory with a source of key material. 244 * <P> 245 * The provider typically uses a KeyStore for obtaining 246 * key material for use during secure socket negotiations. 247 * The KeyStore is generally password-protected. 248 * <P> 249 * For more flexible initialization, please see 250 * {@link #init(ManagerFactoryParameters)}. 251 * 252 * @param ks the key store or null 253 * @param password the password for recovering keys in the KeyStore 254 * @throws KeyStoreException if this operation fails 255 * @throws NoSuchAlgorithmException if the specified algorithm is not 256 * available from the specified provider. 257 * @throws UnrecoverableKeyException if the key cannot be recovered 258 * (e.g. the given password is wrong). 259 */ 260 public final void init(KeyStore ks, char[] password) throws 261 KeyStoreException, NoSuchAlgorithmException, 262 UnrecoverableKeyException { 263 factorySpi.engineInit(ks, password); 264 } 265 266 267 /** 268 * Initializes this factory with a source of provider-specific 269 * key material. 270 * <P> 271 * In some cases, initialization parameters other than a keystore 272 * and password may be needed by a provider. Users of that 273 * particular provider are expected to pass an implementation of 274 * the appropriate <CODE>ManagerFactoryParameters</CODE> as 275 * defined by the provider. The provider can then call the 276 * specified methods in the <CODE>ManagerFactoryParameters</CODE> 277 * implementation to obtain the needed information. 278 * 279 * @param spec an implementation of a provider-specific parameter 280 * specification 281 * @throws InvalidAlgorithmParameterException if an error is encountered 282 */ 283 public final void init(ManagerFactoryParameters spec) throws 284 InvalidAlgorithmParameterException { 285 factorySpi.engineInit(spec); 286 } 287 288 289 /** 290 * Returns one key manager for each type of key material. 291 * 292 * @return the key managers 293 * @throws IllegalStateException if the KeyManagerFactory is not initialized 294 */ 295 public final KeyManager[] getKeyManagers() { 296 return factorySpi.engineGetKeyManagers(); 297 } 298 }