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 trust managers based on a
35  * source of trust material. Each trust manager manages a specific
36  * type of trust material for use by secure sockets. The trust
37  * material is based on a KeyStore and/or provider specific sources.
38  *
39  * <p> Android provides the following <code>TrustManagerFactory</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 TrustManager
57  */
58 public class TrustManagerFactory {
59     // The provider
60     private Provider provider;
61 
62     // The provider implementation (delegate)
63     private TrustManagerFactorySpi factorySpi;
64 
65     // The name of the trust management algorithm.
66     private String algorithm;
67 
68     /**
69      * Obtains the default TrustManagerFactory algorithm name.
70      *
71      * <p>The default TrustManager can be changed at runtime by setting
72      * the value of the {@code ssl.TrustManagerFactory.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.TrustManagerFactory.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.TrustManagerFactory.algorithm");
87             }
88         });
89         if (type == null) {
90             type = "SunX509";
91         }
92         return type;
93     }
94 
95     /**
96      * Creates a TrustManagerFactory object.
97      *
98      * @param factorySpi the delegate
99      * @param provider the provider
100      * @param algorithm the algorithm
101      */
TrustManagerFactory(TrustManagerFactorySpi factorySpi, Provider provider, String algorithm)102     protected TrustManagerFactory(TrustManagerFactorySpi 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>TrustManagerFactory</code>
111      * object.
112      *
113      * <p>This is the same name that was specified in one of the
114      * <code>getInstance</code> calls that created this
115      * <code>TrustManagerFactory</code> object.
116      *
117      * @return the algorithm name of this <code>TrustManagerFactory</code>
118      *          object
119      */
getAlgorithm()120     public final String getAlgorithm() {
121         return this.algorithm;
122     }
123 
124     /**
125      * Returns a <code>TrustManagerFactory</code> object that acts as a
126      * factory for trust managers.
127      *
128      * <p> This method traverses the list of registered security Providers,
129      * starting with the most preferred Provider.
130      * A new TrustManagerFactory object encapsulating the
131      * TrustManagerFactorySpi implementation from the first
132      * Provider that supports the specified algorithm is returned.
133      *
134      * <p> Note that the list of registered providers may be retrieved via
135      * the {@link Security#getProviders() Security.getProviders()} method.
136      *
137      * @param algorithm the standard name of the requested trust management
138      *          algorithm.  See the <a href=
139      *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
140      *          Java Secure Socket Extension Reference Guide </a>
141      *          for information about standard algorithm names.
142      *
143      * @return the new <code>TrustManagerFactory</code> object.
144      *
145      * @exception NoSuchAlgorithmException if no Provider supports a
146      *          TrustManagerFactorySpi implementation for the
147      *          specified algorithm.
148      * @exception NullPointerException if algorithm is null.
149      *
150      * @see java.security.Provider
151      */
getInstance(String algorithm)152     public static final TrustManagerFactory getInstance(String algorithm)
153             throws NoSuchAlgorithmException {
154         GetInstance.Instance instance = GetInstance.getInstance
155                 ("TrustManagerFactory", TrustManagerFactorySpi.class,
156                 algorithm);
157         return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
158                 instance.provider, algorithm);
159     }
160 
161     /**
162      * Returns a <code>TrustManagerFactory</code> object that acts as a
163      * factory for trust managers.
164      *
165      * <p> A new KeyManagerFactory object encapsulating the
166      * KeyManagerFactorySpi implementation from the specified provider
167      * is returned.  The specified provider must be registered
168      * in the security provider list.
169      *
170      * <p> Note that the list of registered providers may be retrieved via
171      * the {@link Security#getProviders() Security.getProviders()} method.
172      *
173      * @param algorithm the standard name of the requested trust management
174      *          algorithm.  See the <a href=
175      *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
176      *          Java Secure Socket Extension Reference Guide </a>
177      *          for information about standard algorithm names.
178      *
179      * @param provider the name of the provider.
180      *
181      * @return the new <code>TrustManagerFactory</code> object
182      *
183      * @throws NoSuchAlgorithmException if a TrustManagerFactorySpi
184      *          implementation for the specified algorithm is not
185      *          available from the specified provider.
186      *
187      * @throws NoSuchProviderException if the specified provider is not
188      *          registered in the security provider list.
189      *
190      * @throws IllegalArgumentException if the provider name is null or empty.
191      * @throws NullPointerException if algorithm is null.
192      *
193      * @see java.security.Provider
194      */
getInstance(String algorithm, String provider)195     public static final TrustManagerFactory getInstance(String algorithm,
196             String provider) throws NoSuchAlgorithmException,
197             NoSuchProviderException {
198         GetInstance.Instance instance = GetInstance.getInstance
199                 ("TrustManagerFactory", TrustManagerFactorySpi.class,
200                 algorithm, provider);
201         return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
202                 instance.provider, algorithm);
203     }
204 
205     /**
206      * Returns a <code>TrustManagerFactory</code> object that acts as a
207      * factory for trust managers.
208      *
209      * <p> A new TrustManagerFactory object encapsulating the
210      * TrustManagerFactorySpi implementation from the specified Provider
211      * object is returned.  Note that the specified Provider object
212      * does not have to be registered in the provider list.
213      *
214      * @param algorithm the standard name of the requested trust management
215      *          algorithm.  See the <a href=
216      *  "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/jsse/JSSERefGuide.html">
217      *          Java Secure Socket Extension Reference Guide </a>
218      *          for information about standard algorithm names.
219      *
220      * @param provider an instance of the provider.
221      *
222      * @return the new <code>TrustManagerFactory</code> object.
223      *
224      * @throws NoSuchAlgorithmException if a TrustManagerFactorySpi
225      *          implementation for the specified algorithm is not available
226      *          from the specified Provider object.
227      *
228      * @throws IllegalArgumentException if the provider is null.
229      * @throws NullPointerException if algorithm is null.
230      *
231      * @see java.security.Provider
232      */
getInstance(String algorithm, Provider provider)233     public static final TrustManagerFactory getInstance(String algorithm,
234             Provider provider) throws NoSuchAlgorithmException {
235         GetInstance.Instance instance = GetInstance.getInstance
236                 ("TrustManagerFactory", TrustManagerFactorySpi.class,
237                 algorithm, provider);
238         return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
239                 instance.provider, algorithm);
240     }
241 
242     /**
243      * Returns the provider of this <code>TrustManagerFactory</code> object.
244      *
245      * @return the provider of this <code>TrustManagerFactory</code> object
246      */
getProvider()247     public final Provider getProvider() {
248         return this.provider;
249     }
250 
251 
252     /**
253      * Initializes this factory with a source of certificate
254      * authorities and related trust material.
255      * <P>
256      * The provider typically uses a KeyStore as a basis for making
257      * trust decisions.
258      * <P>
259      * For more flexible initialization, please see
260      * {@link #init(ManagerFactoryParameters)}.
261      *
262      * @param ks the key store, or null
263      * @throws KeyStoreException if this operation fails
264      */
init(KeyStore ks)265     public final void init(KeyStore ks) throws KeyStoreException {
266         factorySpi.engineInit(ks);
267     }
268 
269 
270     /**
271      * Initializes this factory with a source of provider-specific
272      * trust material.
273      * <P>
274      * In some cases, initialization parameters other than a keystore
275      * may be needed by a provider.  Users of that particular provider
276      * are expected to pass an implementation of the appropriate
277      * <CODE>ManagerFactoryParameters</CODE> as defined by the
278      * provider.  The provider can then call the specified methods in
279      * the <CODE>ManagerFactoryParameters</CODE> implementation to obtain the
280      * needed information.
281      *
282      * @param spec an implementation of a provider-specific parameter
283      *          specification
284      * @throws InvalidAlgorithmParameterException if an error is
285      *          encountered
286      */
init(ManagerFactoryParameters spec)287     public final void init(ManagerFactoryParameters spec) throws
288             InvalidAlgorithmParameterException {
289         factorySpi.engineInit(spec);
290     }
291 
292 
293     /**
294      * Returns one trust manager for each type of trust material.
295      *
296      * @throws IllegalStateException if the factory is not initialized.
297      *
298      * @return the trust managers
299      */
getTrustManagers()300     public final TrustManager[] getTrustManagers() {
301         return factorySpi.engineGetTrustManagers();
302     }
303 }
304