1 /*
2  * Copyright (c) 1999, 2019, 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 import java.util.Objects;
31 
32 import sun.security.jca.GetInstance;
33 
34 /**
35  * This class acts as a factory for trust managers based on a
36  * source of trust material. Each trust manager manages a specific
37  * type of trust material for use by secure sockets. The trust
38  * material is based on a KeyStore and/or provider-specific sources.
39  *
40  * <p> Every implementation of the Java platform is required to support the
41  * following standard {@code TrustManagerFactory} algorithm:
42  * <ul>
43  * <li>{@code PKIX}</li>
44  * </ul>
45  * This algorithm is described in the <a href=
46  * "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
47  * TrustManagerFactory section</a> of the
48  * Java Security Standard Algorithm Names Specification.
49  * Consult the release documentation for your implementation to see if any
50  * other algorithms are supported.
51  *
52  * @since 1.4
53  * @see TrustManager
54  */
55 public class TrustManagerFactory {
56     // The provider
57     private Provider provider;
58 
59     // The provider implementation (delegate)
60     private TrustManagerFactorySpi factorySpi;
61 
62     // The name of the trust management algorithm.
63     private String algorithm;
64 
65     /**
66      * Obtains the default TrustManagerFactory algorithm name.
67      *
68      * <p>The default TrustManager can be changed at runtime by setting
69      * the value of the {@code ssl.TrustManagerFactory.algorithm}
70      * security property to the desired algorithm name.
71      *
72      * @see java.security.Security security properties
73      * @return the default algorithm name as specified by the
74      * {@code ssl.TrustManagerFactory.algorithm} security property, or an
75      * implementation-specific default if no such property exists.
76      */
getDefaultAlgorithm()77     public static final String getDefaultAlgorithm() {
78         String type;
79         type = AccessController.doPrivileged(new PrivilegedAction<>() {
80             @Override
81             public String run() {
82                 return Security.getProperty(
83                     "ssl.TrustManagerFactory.algorithm");
84             }
85         });
86         if (type == null) {
87             type = "SunX509";
88         }
89         return type;
90     }
91 
92     /**
93      * Creates a TrustManagerFactory object.
94      *
95      * @param factorySpi the delegate
96      * @param provider the provider
97      * @param algorithm the algorithm
98      */
TrustManagerFactory(TrustManagerFactorySpi factorySpi, Provider provider, String algorithm)99     protected TrustManagerFactory(TrustManagerFactorySpi factorySpi,
100             Provider provider, String algorithm) {
101         this.factorySpi = factorySpi;
102         this.provider = provider;
103         this.algorithm = algorithm;
104     }
105 
106     /**
107      * Returns the algorithm name of this <code>TrustManagerFactory</code>
108      * object.
109      *
110      * <p>This is the same name that was specified in one of the
111      * <code>getInstance</code> calls that created this
112      * <code>TrustManagerFactory</code> object.
113      *
114      * @return the algorithm name of this <code>TrustManagerFactory</code>
115      *          object
116      */
getAlgorithm()117     public final String getAlgorithm() {
118         return this.algorithm;
119     }
120 
121     /**
122      * Returns a <code>TrustManagerFactory</code> object that acts as a
123      * factory for trust managers.
124      *
125      * <p> This method traverses the list of registered security Providers,
126      * starting with the most preferred Provider.
127      * A new TrustManagerFactory object encapsulating the
128      * TrustManagerFactorySpi implementation from the first
129      * Provider that supports the specified algorithm is returned.
130      *
131      * <p> Note that the list of registered providers may be retrieved via
132      * the {@link Security#getProviders() Security.getProviders()} method.
133      *
134      * @implNote
135      * The JDK Reference Implementation additionally uses the
136      * {@code jdk.security.provider.preferred}
137      * {@link Security#getProperty(String) Security} property to determine
138      * the preferred provider order for the specified algorithm. This
139      * may be different than the order of providers returned by
140      * {@link Security#getProviders() Security.getProviders()}.
141      *
142      * @param algorithm the standard name of the requested trust management
143      *          algorithm.  See the <a href=
144      *          "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
145      *          TrustManagerFactory section</a> in the Java Security Standard
146      *          Algorithm Names Specification for information about standard
147      *          algorithm names.
148      *
149      * @return the new {@code TrustManagerFactory} object
150      *
151      * @throws NoSuchAlgorithmException if no {@code Provider} supports a
152      *         {@code TrustManagerFactorySpi} implementation for the
153      *         specified algorithm
154      *
155      * @throws NullPointerException if {@code algorithm} is {@code null}
156      *
157      * @see java.security.Provider
158      */
getInstance(String algorithm)159     public static final TrustManagerFactory getInstance(String algorithm)
160             throws NoSuchAlgorithmException {
161         Objects.requireNonNull(algorithm, "null algorithm name");
162         GetInstance.Instance instance = GetInstance.getInstance
163                 ("TrustManagerFactory", TrustManagerFactorySpi.class,
164                 algorithm);
165         return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
166                 instance.provider, algorithm);
167     }
168 
169     /**
170      * Returns a <code>TrustManagerFactory</code> object that acts as a
171      * factory for trust managers.
172      *
173      * <p> A new KeyManagerFactory object encapsulating the
174      * KeyManagerFactorySpi implementation from the specified provider
175      * is returned.  The specified provider must be registered
176      * in the security provider list.
177      *
178      * <p> Note that the list of registered providers may be retrieved via
179      * the {@link Security#getProviders() Security.getProviders()} method.
180      *
181      * @param algorithm the standard name of the requested trust management
182      *          algorithm.  See the <a href=
183      *          "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
184      *          TrustManagerFactory section</a> in the Java Security Standard
185      *          Algorithm Names Specification for information about standard
186      *          algorithm names.
187      *
188      * @param provider the name of the provider.
189      *
190      * @return the new {@code TrustManagerFactory} object
191      *
192      * @throws IllegalArgumentException if the provider name is
193      *         {@code null} or empty
194      *
195      * @throws NoSuchAlgorithmException if a {@code TrustManagerFactorySpi}
196      *         implementation for the specified algorithm is not
197      *         available from the specified provider
198      *
199      * @throws NoSuchProviderException if the specified provider is not
200      *         registered in the security provider list
201      *
202      * @throws NullPointerException if {@code algorithm} is {@code null}
203      *
204      * @see java.security.Provider
205      */
getInstance(String algorithm, String provider)206     public static final TrustManagerFactory getInstance(String algorithm,
207             String provider) throws NoSuchAlgorithmException,
208             NoSuchProviderException {
209         Objects.requireNonNull(algorithm, "null algorithm name");
210         GetInstance.Instance instance = GetInstance.getInstance
211                 ("TrustManagerFactory", TrustManagerFactorySpi.class,
212                 algorithm, provider);
213         return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
214                 instance.provider, algorithm);
215     }
216 
217     /**
218      * Returns a <code>TrustManagerFactory</code> object that acts as a
219      * factory for trust managers.
220      *
221      * <p> A new TrustManagerFactory object encapsulating the
222      * TrustManagerFactorySpi implementation from the specified Provider
223      * object is returned.  Note that the specified Provider object
224      * does not have to be registered in the provider list.
225      *
226      * @param algorithm the standard name of the requested trust management
227      *          algorithm.  See the <a href=
228      *          "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
229      *          TrustManagerFactory section</a> in the Java Security Standard
230      *          Algorithm Names Specification for information about standard
231      *          algorithm names.
232      *
233      * @param provider an instance of the provider.
234      *
235      * @return the new {@code TrustManagerFactory} object
236      *
237      * @throws IllegalArgumentException if the provider is {@code null}
238      *
239      * @throws NoSuchAlgorithmException if a {@code TrustManagerFactorySpi}
240      *         implementation for the specified algorithm is not available
241      *         from the specified {@code Provider} object
242      *
243      * @throws NullPointerException if {@code algorithm} is {@code null}
244      *
245      * @see java.security.Provider
246      */
getInstance(String algorithm, Provider provider)247     public static final TrustManagerFactory getInstance(String algorithm,
248             Provider provider) throws NoSuchAlgorithmException {
249         Objects.requireNonNull(algorithm, "null algorithm name");
250         GetInstance.Instance instance = GetInstance.getInstance
251                 ("TrustManagerFactory", TrustManagerFactorySpi.class,
252                 algorithm, provider);
253         return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
254                 instance.provider, algorithm);
255     }
256 
257     /**
258      * Returns the provider of this <code>TrustManagerFactory</code> object.
259      *
260      * @return the provider of this <code>TrustManagerFactory</code> object
261      */
getProvider()262     public final Provider getProvider() {
263         return this.provider;
264     }
265 
266 
267     /**
268      * Initializes this factory with a source of certificate
269      * authorities and related trust material.
270      * <P>
271      * The provider typically uses a KeyStore as a basis for making
272      * trust decisions.
273      * <P>
274      * For more flexible initialization, please see
275      * {@link #init(ManagerFactoryParameters)}.
276      *
277      * @param ks the key store, or null
278      * @throws KeyStoreException if this operation fails
279      */
init(KeyStore ks)280     public final void init(KeyStore ks) throws KeyStoreException {
281         factorySpi.engineInit(ks);
282     }
283 
284 
285     /**
286      * Initializes this factory with a source of provider-specific
287      * trust material.
288      * <P>
289      * In some cases, initialization parameters other than a keystore
290      * may be needed by a provider.  Users of that particular provider
291      * are expected to pass an implementation of the appropriate
292      * <CODE>ManagerFactoryParameters</CODE> as defined by the
293      * provider.  The provider can then call the specified methods in
294      * the <CODE>ManagerFactoryParameters</CODE> implementation to obtain the
295      * needed information.
296      *
297      * @param spec an implementation of a provider-specific parameter
298      *          specification
299      * @throws InvalidAlgorithmParameterException if an error is
300      *          encountered
301      */
init(ManagerFactoryParameters spec)302     public final void init(ManagerFactoryParameters spec) throws
303             InvalidAlgorithmParameterException {
304         factorySpi.engineInit(spec);
305     }
306 
307 
308     /**
309      * Returns one trust manager for each type of trust material.
310      *
311      * @throws IllegalStateException if the factory is not initialized.
312      *
313      * @return the trust managers
314      */
getTrustManagers()315     public final TrustManager[] getTrustManagers() {
316         return factorySpi.engineGetTrustManagers();
317     }
318 }
319