1 /*
   2  * Copyright (c) 1997, 2012, 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.io.InputStream;
  33 import java.security.*;
  34 import java.util.Locale;
  35 
  36 import sun.security.action.GetPropertyAction;
  37 
  38 /**
  39  * <code>SSLSocketFactory</code>s create <code>SSLSocket</code>s.
  40  *
  41  * @since 1.4
  42  * @see SSLSocket
  43  * @author David Brownell
  44  */
  45 public abstract class SSLSocketFactory extends SocketFactory
  46 {
  47     private static SSLSocketFactory theFactory;
  48 
  49     private static boolean propertyChecked;
  50 
  51     static final boolean DEBUG;
  52 
  53     static {
  54         String s = GetPropertyAction.getProperty("javax.net.debug", "")
  55                 .toLowerCase(Locale.ENGLISH);
  56 
  57         DEBUG = s.contains("all") || s.contains("ssl");
  58     }
  59 
  60     private static void log(String msg) {
  61         if (DEBUG) {
  62             System.out.println(msg);
  63         }
  64     }
  65 
  66     /**
  67      * Constructor is used only by subclasses.
  68      */
  69     public SSLSocketFactory() {
  70     }
  71 
  72     /**
  73      * Returns the default SSL socket factory.
  74      *
  75      * <p>The first time this method is called, the security property
  76      * "ssl.SocketFactory.provider" is examined. If it is non-null, a class by
  77      * that name is loaded and instantiated. If that is successful and the
  78      * object is an instance of SSLSocketFactory, it is made the default SSL
  79      * socket factory.
  80      *
  81      * <p>Otherwise, this method returns
  82      * <code>SSLContext.getDefault().getSocketFactory()</code>. If that
  83      * call fails, an inoperative factory is returned.
  84      *
  85      * @return the default <code>SocketFactory</code>
  86      * @see SSLContext#getDefault
  87      */
  88     public static synchronized SocketFactory getDefault() {
  89         if (theFactory != null) {
  90             return theFactory;
  91         }
  92 
  93         if (propertyChecked == false) {
  94             propertyChecked = true;
  95             String clsName = getSecurityProperty("ssl.SocketFactory.provider");
  96             if (clsName != null) {
  97                 log("setting up default SSLSocketFactory");
  98                 try {
  99                     Class<?> cls = null;
 100                     try {
 101                         cls = Class.forName(clsName);
 102                     } catch (ClassNotFoundException e) {
 103                         ClassLoader cl = ClassLoader.getSystemClassLoader();
 104                         if (cl != null) {
 105                             cls = cl.loadClass(clsName);
 106                         }
 107                     }
 108                     log("class " + clsName + " is loaded");
 109                     @SuppressWarnings("deprecation")
 110                     SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance();
 111                     log("instantiated an instance of class " + clsName);
 112                     theFactory = fac;
 113                     return fac;
 114                 } catch (Exception e) {
 115                     log("SSLSocketFactory instantiation failed: " + e.toString());
 116                     theFactory = new DefaultSSLSocketFactory(e);
 117                     return theFactory;
 118                 }
 119             }
 120         }
 121 
 122         try {
 123             return SSLContext.getDefault().getSocketFactory();
 124         } catch (NoSuchAlgorithmException e) {
 125             return new DefaultSSLSocketFactory(e);
 126         }
 127     }
 128 
 129     static String getSecurityProperty(final String name) {
 130         return AccessController.doPrivileged(new PrivilegedAction<>() {
 131             @Override
 132             public String run() {
 133                 String s = java.security.Security.getProperty(name);
 134                 if (s != null) {
 135                     s = s.trim();
 136                     if (s.length() == 0) {
 137                         s = null;
 138                     }
 139                 }
 140                 return s;
 141             }
 142         });
 143     }
 144 
 145     /**
 146      * Returns the list of cipher suites which are enabled by default.
 147      * Unless a different list is enabled, handshaking on an SSL connection
 148      * will use one of these cipher suites.  The minimum quality of service
 149      * for these defaults requires confidentiality protection and server
 150      * authentication (that is, no anonymous cipher suites).
 151      *
 152      * @see #getSupportedCipherSuites()
 153      * @return array of the cipher suites enabled by default
 154      */
 155     public abstract String [] getDefaultCipherSuites();
 156 
 157     /**
 158      * Returns the names of the cipher suites which could be enabled for use
 159      * on an SSL connection.  Normally, only a subset of these will actually
 160      * be enabled by default, since this list may include cipher suites which
 161      * do not meet quality of service requirements for those defaults.  Such
 162      * cipher suites are useful in specialized applications.
 163      *
 164      * @see #getDefaultCipherSuites()
 165      * @return an array of cipher suite names
 166      */
 167     public abstract String [] getSupportedCipherSuites();
 168 
 169     /**
 170      * Returns a socket layered over an existing socket connected to the named
 171      * host, at the given port.  This constructor can be used when tunneling SSL
 172      * through a proxy or when negotiating the use of SSL over an existing
 173      * socket. The host and port refer to the logical peer destination.
 174      * This socket is configured using the socket options established for
 175      * this factory.
 176      *
 177      * @param s the existing socket
 178      * @param host the server host
 179      * @param port the server port
 180      * @param autoClose close the underlying socket when this socket is closed
 181      * @return a socket connected to the specified host and port
 182      * @throws IOException if an I/O error occurs when creating the socket
 183      * @throws NullPointerException if the parameter s is null
 184      */
 185     public abstract Socket createSocket(Socket s, String host,
 186             int port, boolean autoClose) throws IOException;
 187 
 188     /**
 189      * Creates a server mode {@link Socket} layered over an
 190      * existing connected socket, and is able to read data which has
 191      * already been consumed/removed from the {@link Socket}'s
 192      * underlying {@link InputStream}.
 193      * <p>
 194      * This method can be used by a server application that needs to
 195      * observe the inbound data but still create valid SSL/TLS
 196      * connections: for example, inspection of Server Name Indication
 197      * (SNI) extensions (See section 3 of <A
 198      * HREF="http://www.ietf.org/rfc/rfc6066.txt">TLS Extensions
 199      * (RFC6066)</A>).  Data that has been already removed from the
 200      * underlying {@link InputStream} should be loaded into the
 201      * {@code consumed} stream before this method is called, perhaps
 202      * using a {@link java.io.ByteArrayInputStream}.  When this
 203      * {@link Socket} begins handshaking, it will read all of the data in
 204      * {@code consumed} until it reaches {@code EOF}, then all further
 205      * data is read from the underlying {@link InputStream} as
 206      * usual.
 207      * <p>
 208      * The returned socket is configured using the socket options
 209      * established for this factory, and is set to use server mode when
 210      * handshaking (see {@link SSLSocket#setUseClientMode(boolean)}).
 211      *
 212      * @param  s
 213      *         the existing socket
 214      * @param  consumed
 215      *         the consumed inbound network data that has already been
 216      *         removed from the existing {@link Socket}
 217      *         {@link InputStream}.  This parameter may be
 218      *         {@code null} if no data has been removed.
 219      * @param  autoClose close the underlying socket when this socket is closed.
 220      *
 221      * @return the {@link Socket} compliant with the socket options
 222      *         established for this factory
 223      *
 224      * @throws IOException if an I/O error occurs when creating the socket
 225      * @throws UnsupportedOperationException if the underlying provider
 226      *         does not implement the operation
 227      * @throws NullPointerException if {@code s} is {@code null}
 228      *
 229      * @since 1.8
 230      */
 231     public Socket createSocket(Socket s, InputStream consumed,
 232             boolean autoClose) throws IOException {
 233         throw new UnsupportedOperationException();
 234     }
 235 }
 236 
 237 
 238 // file private
 239 class DefaultSSLSocketFactory extends SSLSocketFactory
 240 {
 241     private Exception reason;
 242 
 243     DefaultSSLSocketFactory(Exception reason) {
 244         this.reason = reason;
 245     }
 246 
 247     private Socket throwException() throws SocketException {
 248         throw (SocketException)
 249             new SocketException(reason.toString()).initCause(reason);
 250     }
 251 
 252     @Override
 253     public Socket createSocket()
 254     throws IOException
 255     {
 256         return throwException();
 257     }
 258 
 259     @Override
 260     public Socket createSocket(String host, int port)
 261     throws IOException
 262     {
 263         return throwException();
 264     }
 265 
 266     @Override
 267     public Socket createSocket(Socket s, String host,
 268                                 int port, boolean autoClose)
 269     throws IOException
 270     {
 271         return throwException();
 272     }
 273 
 274     @Override
 275     public Socket createSocket(InetAddress address, int port)
 276     throws IOException
 277     {
 278         return throwException();
 279     }
 280 
 281     @Override
 282     public Socket createSocket(String host, int port,
 283         InetAddress clientAddress, int clientPort)
 284     throws IOException
 285     {
 286         return throwException();
 287     }
 288 
 289     @Override
 290     public Socket createSocket(InetAddress address, int port,
 291         InetAddress clientAddress, int clientPort)
 292     throws IOException
 293     {
 294         return throwException();
 295     }
 296 
 297     @Override
 298     public String [] getDefaultCipherSuites() {
 299         return new String[0];
 300     }
 301 
 302     @Override
 303     public String [] getSupportedCipherSuites() {
 304         return new String[0];
 305     }
 306 }