001    /* TrustManagerFactory.java -- factory for trust managers.
002       Copyright (C) 2004 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.net.ssl;
040    
041    import gnu.java.security.Engine;
042    
043    import java.lang.reflect.InvocationTargetException;
044    import java.security.AccessController;
045    import java.security.InvalidAlgorithmParameterException;
046    import java.security.KeyStore;
047    import java.security.KeyStoreException;
048    import java.security.NoSuchAlgorithmException;
049    import java.security.NoSuchProviderException;
050    import java.security.PrivilegedAction;
051    import java.security.Provider;
052    import java.security.Security;
053    
054    /**
055     * A factory for creating trust manager objects.
056     */
057    public class TrustManagerFactory
058    {
059    
060      // Constants and fields.
061      // -------------------------------------------------------------------------
062    
063      /** The service name for trust manager factories. */
064      private static final String TRUST_MANAGER_FACTORY = "TrustManagerFactory";
065    
066      /** The system default trust manager algorithm. */
067      private static final String DEFAULT_ALGORITHM = "JessieX509";
068    
069      /** The underlying engine class. */
070      private final TrustManagerFactorySpi tmfSpi;
071    
072      /** The provider of the engine class. */
073      private final Provider provider;
074    
075      /** The name of this trust manager algorithm. */
076      private final String algorithm;
077    
078      // Constructor.
079      // -------------------------------------------------------------------------
080    
081      /**
082       * Creates a new trust manager factory.
083       *
084       * @param tmfSpi The underlying engine class.
085       * @param provider The provider of the engine class.
086       * @param algorithm The trust manager algorithm name.
087       */
088      protected TrustManagerFactory(TrustManagerFactorySpi tmfSpi,
089                                    Provider provider, String algorithm)
090      {
091        this.tmfSpi = tmfSpi;
092        this.provider = provider;
093        this.algorithm = algorithm;
094      }
095    
096      /**
097       * Returns an instance of a trust manager factory for the given algorithm from
098       * the first provider that implements it.
099       *
100       * @param algorithm The name of the algorithm to get.
101       * @return The instance of the trust manager factory.
102       * @throws NoSuchAlgorithmException If no provider implements the given
103       *           algorithm.
104       * @throws IllegalArgumentException if <code>algorithm</code> is
105       *           <code>null</code> or is an empty string.
106       */
107      public static final TrustManagerFactory getInstance(String algorithm)
108          throws NoSuchAlgorithmException
109      {
110        Provider[] p = Security.getProviders();
111        NoSuchAlgorithmException lastException = null;
112        for (int i = 0; i < p.length; i++)
113          try
114            {
115              return getInstance(algorithm, p[i]);
116            }
117          catch (NoSuchAlgorithmException x)
118            {
119              lastException = x;
120            }
121        if (lastException != null)
122          throw lastException;
123        throw new NoSuchAlgorithmException(algorithm);
124      }
125    
126      /**
127       * Returns an instance of a trust manager factory for the given algorithm from
128       * the named provider.
129       *
130       * @param algorithm The name of the algorithm to get.
131       * @param provider The name of the provider to get the instance from.
132       * @return The instance of the trust manager factory.
133       * @throws NoSuchAlgorithmException If the provider does not implement the
134       *           given algorithm.
135       * @throws NoSuchProviderException If there is no such named provider.
136       * @throws IllegalArgumentException if either <code>algorithm</code> or
137       *           <code>provider</code> is <code>null</code>, or if
138       *           <code>algorithm</code> is an empty string.
139       */
140      public static final TrustManagerFactory getInstance(String algorithm,
141                                                          String provider)
142        throws NoSuchAlgorithmException, NoSuchProviderException
143      {
144        if (provider == null)
145          throw new IllegalArgumentException("provider MUST NOT be null");
146        Provider p = Security.getProvider(provider);
147        if (p == null)
148          throw new NoSuchProviderException(provider);
149        return getInstance(algorithm, p);
150      }
151    
152      /**
153       * Returns an instance of a trust manager factory for the given algorithm from
154       * the specified provider.
155       *
156       * @param algorithm The name of the algorithm to get.
157       * @param provider The provider to get the instance from.
158       * @return The instance of the trust manager factory.
159       * @throws NoSuchAlgorithmException If the provider does not implement the
160       *           given algorithm.
161       * @throws IllegalArgumentException if either <code>algorithm</code> or
162       *           <code>provider</code> is <code>null</code>, or if
163       *           <code>algorithm</code> is an empty string.
164       */
165      public static final TrustManagerFactory getInstance(String algorithm,
166                                                          Provider provider)
167          throws NoSuchAlgorithmException
168      {
169        StringBuilder sb = new StringBuilder("TrustManagerFactory algorithm [")
170            .append(algorithm).append("] from provider[")
171            .append(provider).append("] could not be created");
172        Throwable cause;
173        try
174          {
175            Object spi = Engine.getInstance(TRUST_MANAGER_FACTORY, algorithm, provider);
176            return new TrustManagerFactory((TrustManagerFactorySpi) spi,
177                                           provider,
178                                           algorithm);
179          }
180        catch (InvocationTargetException x)
181          {
182            cause = x.getCause();
183            if (cause instanceof NoSuchAlgorithmException)
184              throw (NoSuchAlgorithmException) cause;
185            if (cause == null)
186              cause = x;
187          }
188        catch (ClassCastException x)
189          {
190            cause = x;
191          }
192        NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
193        x.initCause(cause);
194        throw x;
195      }
196    
197      /**
198       * Returns the default algorithm for trust manager factories. The value
199       * returned is either the value of the security property
200       * "ssl.TrustManagerFactory.algorithm" if it is set, or the value "JessieX509"
201       * if not.
202       *
203       * @return The default algorithm name.
204       * @see Security.getProperty(java.lang.String)
205       */
206      public static final String getDefaultAlgorithm()
207      {
208        String alg = null;
209        try
210          {
211            alg = (String) AccessController.doPrivileged(
212              new PrivilegedAction()
213              {
214                public Object run()
215                {
216                  return Security.getProperty("ssl.TrustManagerFactory.algorithm");
217                }
218              }
219            );
220          }
221        catch (SecurityException se)
222          {
223          }
224        if (alg == null)
225          alg = DEFAULT_ALGORITHM;
226        return alg;
227      }
228    
229      // Instance methods.
230      // -------------------------------------------------------------------------
231    
232      /**
233       * Returns the name of this trust manager algorithm.
234       *
235       * @return The algorithm name.
236       */
237      public final String getAlgorithm()
238      {
239        return algorithm;
240      }
241    
242      /**
243       * Returns the provider of the underlying implementation.
244       *
245       * @return The provider.
246       */
247      public final Provider getProvider()
248      {
249        return provider;
250      }
251    
252      /**
253       * Returns the trust managers created by this factory.
254       *
255       * @return The trust managers.
256       */
257      public final TrustManager[] getTrustManagers()
258      {
259        return tmfSpi.engineGetTrustManagers();
260      }
261    
262      /**
263       * Initialize this instance with some algorithm-specific parameters.
264       *
265       * @param params The parameters.
266       * @throws InvalidAlgorithmParameterException If the supplied parameters
267       *   are inappropriate for this instance.
268       */
269      public final void init(ManagerFactoryParameters params)
270        throws InvalidAlgorithmParameterException
271      {
272        tmfSpi.engineInit(params);
273      }
274    
275      /**
276       * Initialize this instance with a key store. The key store may be null,
277       * in which case a default will be used.
278       *
279       * @param store The key store.
280       * @throws KeyStoreException If there is a problem reading from the
281       *   key store.
282       */
283      public final void init(KeyStore store) throws KeyStoreException
284      {
285        tmfSpi.engineInit(store);
286      }
287    }