Frames | No Frames |
1: /* SSLSocketFactory.java -- factory for SSL client sockets. 2: Copyright (C) 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.net.ssl; 40: 41: import java.io.IOException; 42: import java.net.InetAddress; 43: import java.net.Socket; 44: import java.security.KeyStore; 45: import java.security.Security; 46: 47: import javax.net.SocketFactory; 48: 49: /** 50: * A socket factory for creating <i>Secure Socket Layer</i> (<b>SSL</b>) 51: * sockets. 52: */ 53: public abstract class SSLSocketFactory extends SocketFactory 54: { 55: // Constants. 56: // ------------------------------------------------------------------------- 57: 58: private static SSLContext context; 59: 60: // Constructor. 61: // ------------------------------------------------------------------------- 62: 63: public SSLSocketFactory() 64: { 65: super(); 66: } 67: 68: // Class methods. 69: // ------------------------------------------------------------------------- 70: 71: /** 72: * Returns a default implementation of a SSL socket factory. 73: * 74: * <p>To control the class that gets returned by this method, set the 75: * security property "ssl.SocketFactory.provider" to the class 76: * name of a concrete implementation of this class. If not set, a 77: * system-dependent implementation will be used.</p> 78: * 79: * <p>The implementation returned is created by the first implementation 80: * of the {@link SSLContext} class found, which is initialized with 81: * default parameters. To control the key and trust manager factory 82: * algorithms used as defaults, set the security properties 83: * "ssl.keyManagerFactory.algorithm" and "ssl.trustManagerFactory.algorithm" 84: * to the appropriate names.</p> 85: * 86: * <p>Using this method is not recommended. Instead, use the methods of 87: * {@link SSLContext}, which provide much better control over the 88: * creation of socket factories.</p> 89: * 90: * @return The default socket factory. 91: * @throws RuntimeException If no default can be created. 92: */ 93: public static synchronized SocketFactory getDefault() 94: { 95: try 96: { 97: String s = Security.getProperty("ssl.SocketFactory.provider"); 98: ClassLoader cl = ClassLoader.getSystemClassLoader(); 99: if (s != null && cl != null) 100: { 101: return (SocketFactory) 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: 117: // 2. Try to initialize the factories with default parameters. 118: try 119: { 120: KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmAlg); 121: kmf.init(null, null); 122: km = kmf.getKeyManagers(); 123: } 124: catch (Exception ex) 125: { 126: } 127: try 128: { 129: TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlg); 130: tmf.init((KeyStore) null); 131: tm = tmf.getTrustManagers(); 132: } 133: catch (Exception ex) 134: { 135: } 136: 137: // 3. Create and initialize a context. 138: try 139: { 140: context = SSLContext.getInstance("SSLv3"); 141: context.init(km, tm, null); 142: } 143: catch (Exception ex) 144: { 145: return new ErrorSocketFactory(new RuntimeException( 146: "error instantiating default socket factory: " + ex.toString(), 147: ex)); 148: } 149: } 150: try 151: { 152: return context.getSocketFactory(); 153: } 154: catch (Exception e) 155: { 156: } 157: return new ErrorSocketFactory(new RuntimeException( 158: "no SSLSocketFactory implementation available")); 159: } 160: 161: private static final class ErrorSocketFactory extends SSLSocketFactory 162: { 163: private RuntimeException x; 164: 165: ErrorSocketFactory(RuntimeException x) 166: { 167: this.x = x; 168: } 169: 170: public Socket createSocket() throws IOException 171: { 172: throw (IOException) new IOException().initCause(x); 173: } 174: 175: public Socket createSocket(String host, int port) 176: throws IOException 177: { 178: throw (IOException) new IOException().initCause(x); 179: } 180: 181: public Socket createSocket(String host, int port, InetAddress localHost, 182: int localPort) 183: throws IOException 184: { 185: throw (IOException) new IOException().initCause(x); 186: } 187: 188: public Socket createSocket(InetAddress host, int port) throws IOException 189: { 190: throw (IOException) new IOException().initCause(x); 191: } 192: 193: public Socket createSocket(InetAddress hast, int port, InetAddress localHost, 194: int localPort) 195: throws IOException 196: { 197: throw (IOException) new IOException().initCause(x); 198: } 199: 200: public String[] getDefaultCipherSuites() 201: { 202: throw new RuntimeException(x); 203: } 204: 205: public String[] getSupportedCipherSuites() 206: { 207: throw new RuntimeException(x); 208: } 209: 210: public Socket createSocket(Socket s, String host, int port, 211: boolean autoClose) 212: throws IOException 213: { 214: throw new RuntimeException(x); 215: } 216: } 217: 218: // Abstract methods. 219: // ------------------------------------------------------------------------- 220: 221: /** 222: * Creates a SSL socket wrapped around an existing socket. 223: * 224: * @param socket The socket to wrap. 225: * @param host The host the socket is connected to. 226: * @param port The port the socket is connected to. 227: * @param autoClose Whether or not the wrapped socket should be closed 228: * automatically. 229: * @return The new SSL socket. 230: * @throws IOException If the socket could not be created. 231: */ 232: public abstract Socket createSocket(Socket socket, String host, 233: int port, boolean autoClose) 234: throws IOException; 235: 236: /** 237: * Returns the list of cipher suites that will be enabled in sockets 238: * created by this factory. 239: * 240: * @return The default cipher suites. 241: */ 242: public abstract String[] getDefaultCipherSuites(); 243: 244: /** 245: * Returns the list of all cipher suites supported by this factory. 246: * 247: * @return The list of supported cipher suites. 248: */ 249: public abstract String[] getSupportedCipherSuites(); 250: }