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