1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package javax.net.ssl;
19
20import java.security.InvalidAlgorithmParameterException;
21import java.security.KeyStore;
22import java.security.KeyStoreException;
23import java.security.NoSuchAlgorithmException;
24import java.security.NoSuchProviderException;
25import java.security.Provider;
26import java.security.Security;
27import org.apache.harmony.security.fortress.Engine;
28
29/**
30 * The factory for {@code TrustManager}s based on {@code KeyStore} or provider
31 * specific implementation.
32 */
33public class TrustManagerFactory {
34    // Store TrustManager service name
35    private static final String SERVICE = "TrustManagerFactory";
36
37    // Used to access common engine functionality
38    private static final Engine ENGINE = new Engine(SERVICE);
39
40    // Store default property name
41    private static final String PROPERTY_NAME = "ssl.TrustManagerFactory.algorithm";
42
43    // Default value of TrustManagerFactory type.
44    private static final String DEFAULT_PROPERTY = "PKIX";
45
46    /**
47     * Returns the default algorithm name for the {@code TrustManagerFactory}. The
48     * default algorithm name is specified by the security property
49     * {@code 'ssl.TrustManagerFactory.algorithm'}.
50     *
51     * @return the default algorithm name.
52     */
53    public static final String getDefaultAlgorithm() {
54        String algorithm = Security.getProperty(PROPERTY_NAME);
55        return (algorithm != null ? algorithm : DEFAULT_PROPERTY);
56    }
57
58    /**
59     * Creates a new {@code TrustManagerFactory} instance for the specified
60     * trust management algorithm.
61     *
62     * @param algorithm
63     *            the name of the requested trust management algorithm.
64     * @return a trust manager factory for the requested algorithm.
65     * @throws NoSuchAlgorithmException
66     *             if no installed provider can provide the requested algorithm.
67     * @throws NullPointerException
68     *             if {@code algorithm} is {@code null} (instead of
69     *             NoSuchAlgorithmException as in 1.4 release)
70     */
71    public static final TrustManagerFactory getInstance(String algorithm)
72            throws NoSuchAlgorithmException {
73        if (algorithm == null) {
74            throw new NullPointerException("algorithm == null");
75        }
76        Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
77        return new TrustManagerFactory((TrustManagerFactorySpi) sap.spi, sap.provider, algorithm);
78    }
79
80    /**
81     * Creates a new {@code TrustManagerFactory} instance for the specified
82     * trust management algorithm from the specified provider.
83     *
84     * @param algorithm
85     *            the name of the requested trust management algorithm name.
86     * @param provider
87     *            the name of the provider that provides the requested
88     *            algorithm.
89     * @return a trust manager factory for the requested algorithm.
90     * @throws NoSuchAlgorithmException
91     *             if the specified provider cannot provide the requested
92     *             algorithm.
93     * @throws NoSuchProviderException
94     *             if the specified provider does not exist.
95     * @throws NullPointerException
96     *             if {@code algorithm} is {@code null} (instead of
97     *             NoSuchAlgorithmException as in 1.4 release)
98     */
99    public static final TrustManagerFactory getInstance(String algorithm, String provider)
100            throws NoSuchAlgorithmException, NoSuchProviderException {
101        if ((provider == null) || (provider.length() == 0)) {
102            throw new IllegalArgumentException("Provider is null or empty");
103        }
104        Provider impProvider = Security.getProvider(provider);
105        if (impProvider == null) {
106            throw new NoSuchProviderException(provider);
107        }
108        return getInstance(algorithm, impProvider);
109    }
110
111    /**
112     * Creates a new {@code TrustManagerFactory} instance for the specified
113     * trust management algorithm from the specified provider.
114     *
115     * @param algorithm
116     *            the name of the requested key management algorithm name.
117     * @param provider
118     *            the provider that provides the requested algorithm.
119     * @return a key manager factory for the requested algorithm.
120     * @throws NoSuchAlgorithmException
121     *             if the specified provider cannot provide the requested
122     *             algorithm.
123     * @throws NullPointerException
124     *             if {@code algorithm} is {@code null} (instead of
125     *             NoSuchAlgorithmException as in 1.4 release)
126     */
127    public static final TrustManagerFactory getInstance(String algorithm, Provider provider)
128            throws NoSuchAlgorithmException {
129        if (provider == null) {
130            throw new IllegalArgumentException("Provider is null");
131        }
132        if (algorithm == null) {
133            throw new NullPointerException("algorithm == null");
134        }
135        Object spi = ENGINE.getInstance(algorithm, provider, null);
136        return new TrustManagerFactory((TrustManagerFactorySpi) spi, provider, algorithm);
137    }
138
139    // Store used provider
140    private final Provider provider;
141
142    // Store used TrustManagerFactorySpi implementation
143    private final TrustManagerFactorySpi spiImpl;
144
145    // Store used algorithm
146    private final String algorithm;
147
148    /**
149     * Creates a new {@code TrustManagerFactory} instance.
150     *
151     * @param factorySpi
152     *            the implementation delegate.
153     * @param provider
154     *            the provider
155     * @param algorithm
156     *            the algorithm name.
157     */
158    protected TrustManagerFactory(TrustManagerFactorySpi factorySpi, Provider provider,
159            String algorithm) {
160        this.provider = provider;
161        this.algorithm = algorithm;
162        this.spiImpl = factorySpi;
163    }
164
165    /**
166     * Returns the name of this {@code TrustManagerFactory} algorithm
167     * implementation.
168     *
169     * @return the name of this {@code TrustManagerFactory} algorithm
170     *         implementation.
171     */
172    public final String getAlgorithm() {
173        return algorithm;
174    }
175
176    /**
177     * Returns the provider for this {@code TrustManagerFactory} instance.
178     *
179     * @return the provider for this {@code TrustManagerFactory} instance.
180     */
181    public final Provider getProvider() {
182        return provider;
183    }
184
185    /**
186     * Initializes this factory instance with the specified keystore as source
187     * of certificate authorities and trust material.
188     *
189     * @param ks
190     *            the keystore or {@code null}.
191     * @throws KeyStoreException
192     *             if the initialization fails.
193     */
194    public final void init(KeyStore ks) throws KeyStoreException {
195        spiImpl.engineInit(ks);
196    }
197
198    /**
199     * Initializes this factory instance with the specified provider-specific
200     * parameters for a source of trust material.
201     *
202     * @param spec
203     *            the provider-specific parameters.
204     * @throws InvalidAlgorithmParameterException
205     *             if the initialization fails.
206     */
207    public final void init(ManagerFactoryParameters spec)
208            throws InvalidAlgorithmParameterException {
209        spiImpl.engineInit(spec);
210    }
211
212    /**
213     * Returns the list of {@code TrustManager}s with one entry for each type
214     * of trust material.
215     *
216     * @return the list of {@code TrustManager}s
217     */
218    public final TrustManager[] getTrustManagers() {
219        return spiImpl.engineGetTrustManagers();
220    }
221
222}
223