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}openjdk-redirect.html?v=8&path=/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}openjdk-redirect.html?v=8&path=/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}openjdk-redirect.html?v=8&path=/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