001/* SSLServerSocketFactory.java -- factory for SSL server sockets.
002   Copyright (C) 2004 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package javax.net.ssl;
040
041import java.io.IOException;
042import java.net.InetAddress;
043import java.net.ServerSocket;
044import java.security.KeyStore;
045import java.security.Security;
046
047import javax.net.ServerSocketFactory;
048
049/**
050 * A server socket factory for <i>Secure Socket Layer</i> (<b>SSL</b>)
051 * server sockets.
052 */
053public abstract class SSLServerSocketFactory extends ServerSocketFactory
054{
055  // Field.
056  // -------------------------------------------------------------------------
057
058  private static SSLContext context;
059
060  // Constructor.
061  // -------------------------------------------------------------------------
062
063  protected SSLServerSocketFactory()
064  {
065    super();
066  }
067
068  // Class methods.
069  // -------------------------------------------------------------------------
070
071  /**
072   * Returns a default implementation of a SSL server socket factory.
073   *
074   * <p>To control the class that gets returned by this method, set the
075   * security property "ssl.ServerSocketFactory.provider" to the class
076   * name of a concrete implementation of this class. If not set, a
077   * system-dependent implementation will be used.</p>
078   *
079   * <p>The implementation returned is created by the first implementation
080   * of the {@link SSLContext} class found, which is initialized with
081   * default parameters. To control the key and trust manager factory
082   * algorithms used as defaults, set the security properties
083   * "ssl.keyManagerFactory.algorithm" and "ssl.trustManagerFactory.algorithm"
084   * to the appropriate names.</p>
085   *
086   * <p>Using this method is not recommended. Instead, use the methods of
087   * {@link SSLContext}, which provide much better control over the
088   * creation of server socket factories.</p>
089   *
090   * @return The default server socket factory.
091   * @throws RuntimeException If no default can be created.
092   */
093  public static synchronized ServerSocketFactory getDefault()
094  {
095    try
096      {
097        String s = Security.getProperty("ssl.ServerSocketFactory.provider");
098        ClassLoader cl = ClassLoader.getSystemClassLoader();
099        if (s != null && cl != null)
100          {
101            return (ServerSocketFactory) cl.loadClass(s).newInstance();
102          }
103      }
104    catch (Exception e)
105      {
106      }
107    if (context == null)
108      {
109        KeyManager[] km = null;
110        TrustManager[] tm = null;
111
112        // 1. Determine which algorithms to use for the key and trust
113        // manager factories.
114        String kmAlg = KeyManagerFactory.getDefaultAlgorithm();
115        String tmAlg = TrustManagerFactory.getDefaultAlgorithm();
116        // 2. Try to initialize the factories with default parameters.
117        try
118          {
119            KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmAlg);
120            kmf.init(null, null);
121            km = kmf.getKeyManagers();
122          }
123        catch (Exception ex)
124          {
125          }
126        try
127          {
128            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlg);
129            tmf.init((KeyStore) null);
130            tm = tmf.getTrustManagers();
131          }
132        catch (Exception ex)
133          {
134          }
135
136        // 3. Create and initialize a context.
137        try
138          {
139            context = SSLContext.getInstance("SSLv3");
140            context.init(km, tm, null);
141          }
142        catch (Exception ex)
143          {
144            return new ErrorServerSocketFactory(new RuntimeException(
145                "error instantiating default server socket factory: "
146                                       + ex.toString(), ex));
147          }
148      }
149    try
150      {
151        return context.getServerSocketFactory();
152      }
153    catch (Exception e)
154      {
155      }
156    return new ErrorServerSocketFactory(new RuntimeException(
157        "no SSLSocketFactory implementation available"));
158  }
159
160  private static final class ErrorServerSocketFactory
161    extends SSLServerSocketFactory
162  {
163    private RuntimeException x;
164
165    ErrorServerSocketFactory(RuntimeException x)
166    {
167      this.x = x;
168    }
169
170    public ServerSocket createServerSocket() throws IOException
171    {
172      throw (IOException) new IOException().initCause(x);
173    }
174
175    public ServerSocket createServerSocket(int port) throws IOException
176    {
177      throw (IOException) new IOException().initCause(x);
178    }
179
180    public ServerSocket createServerSocket(int port, int backlog)
181      throws IOException
182    {
183      throw (IOException) new IOException().initCause(x);
184    }
185
186    public ServerSocket createServerSocket(int port, int backlog,
187                                           InetAddress ifAddress)
188      throws IOException
189    {
190      throw (IOException) new IOException().initCause(x);
191    }
192
193    public String[] getDefaultCipherSuites()
194    {
195      throw new RuntimeException(x);
196    }
197
198    public String[] getSupportedCipherSuites()
199    {
200      throw new RuntimeException(x);
201    }
202  }
203
204  // Abstract methods.
205  // -------------------------------------------------------------------------
206
207  /**
208   * Returns the list of cipher suites that will be enabled in server sockets
209   * created by this factory.
210   *
211   * @return The default cipher suites.
212   */
213  public abstract String[] getDefaultCipherSuites();
214
215  /**
216   * Returns the list of all cipher suites supported by this factory.
217   *
218   * @return The list of supported cipher suites.
219   */
220  public abstract String[] getSupportedCipherSuites();
221}