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