001 /* SSLServerSocketFactory.java -- factory for SSL server sockets.
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 java.io.IOException;
042 import java.net.InetAddress;
043 import java.net.ServerSocket;
044 import java.security.KeyStore;
045 import java.security.Security;
046
047 import javax.net.ServerSocketFactory;
048
049 /**
050 * A server socket factory for <i>Secure Socket Layer</i> (<b>SSL</b>)
051 * server sockets.
052 */
053 public 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 }