1 /* 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package javax.net.ssl; 28 29 import java.net; 30 import javax.net.SocketFactory; 31 import java.io.IOException; 32 import java.security; 33 import java.util.Locale; 34 35 import sun.security.action.GetPropertyAction; 36 37 /** 38 * <code>SSLSocketFactory</code>s create <code>SSLSocket</code>s. 39 * 40 * @since 1.4 41 * @see SSLSocket 42 * @author David Brownell 43 */ 44 public abstract class SSLSocketFactory extends SocketFactory 45 { 46 private static SSLSocketFactory theFactory; 47 48 private static boolean propertyChecked; 49 50 static final boolean DEBUG; 51 52 static { 53 String s = java.security.AccessController.doPrivileged( 54 new GetPropertyAction("javax.net.debug", "")).toLowerCase( 55 Locale.ENGLISH); 56 DEBUG = s.contains("all") || s.contains("ssl"); 57 } 58 59 private static void log(String msg) { 60 if (DEBUG) { 61 System.out.println(msg); 62 } 63 } 64 65 /** 66 * Constructor is used only by subclasses. 67 */ 68 public SSLSocketFactory() { 69 } 70 71 /** 72 * Returns the default SSL socket factory. 73 * 74 * <p>The first time this method is called, the security property 75 * "ssl.SocketFactory.provider" is examined. If it is non-null, a class by 76 * that name is loaded and instantiated. If that is successful and the 77 * object is an instance of SSLSocketFactory, it is made the default SSL 78 * socket factory. 79 * 80 * <p>Otherwise, this method returns 81 * <code>SSLContext.getDefault().getSocketFactory()</code>. If that 82 * call fails, an inoperative factory is returned. 83 * 84 * @return the default <code>SocketFactory</code> 85 * @see SSLContext#getDefault 86 */ 87 public static synchronized SocketFactory getDefault() { 88 if (theFactory != null) { 89 return theFactory; 90 } 91 92 if (propertyChecked == false) { 93 propertyChecked = true; 94 String clsName = getSecurityProperty("ssl.SocketFactory.provider"); 95 if (clsName != null) { 96 log("setting up default SSLSocketFactory"); 97 try { 98 Class cls = null; 99 try { 100 cls = Class.forName(clsName); 101 } catch (ClassNotFoundException e) { 102 ClassLoader cl = ClassLoader.getSystemClassLoader(); 103 if (cl != null) { 104 cls = cl.loadClass(clsName); 105 } 106 } 107 log("class " + clsName + " is loaded"); 108 SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance(); 109 log("instantiated an instance of class " + clsName); 110 theFactory = fac; 111 return fac; 112 } catch (Exception e) { 113 log("SSLSocketFactory instantiation failed: " + e.toString()); 114 theFactory = new DefaultSSLSocketFactory(e); 115 return theFactory; 116 } 117 } 118 } 119 120 try { 121 return SSLContext.getDefault().getSocketFactory(); 122 } catch (NoSuchAlgorithmException e) { 123 return new DefaultSSLSocketFactory(e); 124 } 125 } 126 127 static String getSecurityProperty(final String name) { 128 return AccessController.doPrivileged(new PrivilegedAction<String>() { 129 public String run() { 130 String s = java.security.Security.getProperty(name); 131 if (s != null) { 132 s = s.trim(); 133 if (s.length() == 0) { 134 s = null; 135 } 136 } 137 return s; 138 } 139 }); 140 } 141 142 /** 143 * Returns the list of cipher suites which are enabled by default. 144 * Unless a different list is enabled, handshaking on an SSL connection 145 * will use one of these cipher suites. The minimum quality of service 146 * for these defaults requires confidentiality protection and server 147 * authentication (that is, no anonymous cipher suites). 148 * 149 * @see #getSupportedCipherSuites() 150 * @return array of the cipher suites enabled by default 151 */ 152 public abstract String [] getDefaultCipherSuites(); 153 154 /** 155 * Returns the names of the cipher suites which could be enabled for use 156 * on an SSL connection. Normally, only a subset of these will actually 157 * be enabled by default, since this list may include cipher suites which 158 * do not meet quality of service requirements for those defaults. Such 159 * cipher suites are useful in specialized applications. 160 * 161 * @see #getDefaultCipherSuites() 162 * @return an array of cipher suite names 163 */ 164 public abstract String [] getSupportedCipherSuites(); 165 166 /** 167 * Returns a socket layered over an existing socket connected to the named 168 * host, at the given port. This constructor can be used when tunneling SSL 169 * through a proxy or when negotiating the use of SSL over an existing 170 * socket. The host and port refer to the logical peer destination. 171 * This socket is configured using the socket options established for 172 * this factory. 173 * 174 * @param s the existing socket 175 * @param host the server host 176 * @param port the server port 177 * @param autoClose close the underlying socket when this socket is closed 178 * @return a socket connected to the specified host and port 179 * @throws IOException if an I/O error occurs when creating the socket 180 * @throws NullPointerException if the parameter s is null 181 */ 182 public abstract Socket createSocket(Socket s, String host, 183 int port, boolean autoClose) 184 throws IOException; 185 } 186 187 188 // file private 189 class DefaultSSLSocketFactory extends SSLSocketFactory 190 { 191 private Exception reason; 192 193 DefaultSSLSocketFactory(Exception reason) { 194 this.reason = reason; 195 } 196 197 private Socket throwException() throws SocketException { 198 throw (SocketException) 199 new SocketException(reason.toString()).initCause(reason); 200 } 201 202 public Socket createSocket() 203 throws IOException 204 { 205 return throwException(); 206 } 207 208 public Socket createSocket(String host, int port) 209 throws IOException 210 { 211 return throwException(); 212 } 213 214 public Socket createSocket(Socket s, String host, 215 int port, boolean autoClose) 216 throws IOException 217 { 218 return throwException(); 219 } 220 221 public Socket createSocket(InetAddress address, int port) 222 throws IOException 223 { 224 return throwException(); 225 } 226 227 public Socket createSocket(String host, int port, 228 InetAddress clientAddress, int clientPort) 229 throws IOException 230 { 231 return throwException(); 232 } 233 234 public Socket createSocket(InetAddress address, int port, 235 InetAddress clientAddress, int clientPort) 236 throws IOException 237 { 238 return throwException(); 239 } 240 241 public String [] getDefaultCipherSuites() { 242 return new String[0]; 243 } 244 245 public String [] getSupportedCipherSuites() { 246 return new String[0]; 247 } 248 }