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
26package javax.net.ssl;
27
28import java.security.Security;
29import java.security.*;
30
31import 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 */
58public 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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
300    public final TrustManager[] getTrustManagers() {
301        return factorySpi.engineGetTrustManagers();
302    }
303}
304