Save This Page
Home » openjdk-7 » javax » rmi » ssl » [javadoc | source]
    1   /*
    2    * Copyright 2003-2004 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.rmi.ssl;
   27   
   28   import java.io.IOException;
   29   import java.io.Serializable;
   30   import java.net.Socket;
   31   import java.rmi.server.RMIClientSocketFactory;
   32   import java.util.StringTokenizer;
   33   import javax.net.SocketFactory;
   34   import javax.net.ssl.SSLSocket;
   35   import javax.net.ssl.SSLSocketFactory;
   36   
   37   /**
   38    * <p>An <code>SslRMIClientSocketFactory</code> instance is used by the RMI
   39    * runtime in order to obtain client sockets for RMI calls via SSL.</p>
   40    *
   41    * <p>This class implements <code>RMIClientSocketFactory</code> over
   42    * the Secure Sockets Layer (SSL) or Transport Layer Security (TLS)
   43    * protocols.</p>
   44    *
   45    * <p>This class creates SSL sockets using the default
   46    * <code>SSLSocketFactory</code> (see {@link
   47    * SSLSocketFactory#getDefault}).  All instances of this class are
   48    * functionally equivalent.  In particular, they all share the same
   49    * truststore, and the same keystore when client authentication is
   50    * required by the server.  This behavior can be modified in
   51    * subclasses by overriding the {@link #createSocket(String,int)}
   52    * method; in that case, {@link #equals(Object) equals} and {@link
   53    * #hashCode() hashCode} may also need to be overridden.</p>
   54    *
   55    * <p>If the system property
   56    * <code>javax.rmi.ssl.client.enabledCipherSuites</code> is specified,
   57    * the {@link #createSocket(String,int)} method will call {@link
   58    * SSLSocket#setEnabledCipherSuites(String[])} before returning the
   59    * socket.  The value of this system property is a string that is a
   60    * comma-separated list of SSL/TLS cipher suites to enable.</p>
   61    *
   62    * <p>If the system property
   63    * <code>javax.rmi.ssl.client.enabledProtocols</code> is specified,
   64    * the {@link #createSocket(String,int)} method will call {@link
   65    * SSLSocket#setEnabledProtocols(String[])} before returning the
   66    * socket.  The value of this system property is a string that is a
   67    * comma-separated list of SSL/TLS protocol versions to enable.</p>
   68    *
   69    * @see javax.net.ssl.SSLSocketFactory
   70    * @see javax.rmi.ssl.SslRMIServerSocketFactory
   71    * @since 1.5
   72    */
   73   public class SslRMIClientSocketFactory
   74       implements RMIClientSocketFactory, Serializable {
   75   
   76       /**
   77        * <p>Creates a new <code>SslRMIClientSocketFactory</code>.</p>
   78        */
   79       public SslRMIClientSocketFactory() {
   80           // We don't force the initialization of the default SSLSocketFactory
   81           // at construction time - because the RMI client socket factory is
   82           // created on the server side, where that initialization is a priori
   83           // meaningless, unless both server and client run in the same JVM.
   84           // We could possibly override readObject() to force this initialization,
   85           // but it might not be a good idea to actually mix this with possible
   86           // deserialization problems.
   87           // So contrarily to what we do for the server side, the initialization
   88           // of the SSLSocketFactory will be delayed until the first time
   89           // createSocket() is called - note that the default SSLSocketFactory
   90           // might already have been initialized anyway if someone in the JVM
   91           // already called SSLSocketFactory.getDefault().
   92           //
   93       }
   94   
   95       /**
   96        * <p>Creates an SSL socket.</p>
   97        *
   98        * <p>If the system property
   99        * <code>javax.rmi.ssl.client.enabledCipherSuites</code> is
  100        * specified, this method will call {@link
  101        * SSLSocket#setEnabledCipherSuites(String[])} before returning
  102        * the socket. The value of this system property is a string that
  103        * is a comma-separated list of SSL/TLS cipher suites to
  104        * enable.</p>
  105        *
  106        * <p>If the system property
  107        * <code>javax.rmi.ssl.client.enabledProtocols</code> is
  108        * specified, this method will call {@link
  109        * SSLSocket#setEnabledProtocols(String[])} before returning the
  110        * socket. The value of this system property is a string that is a
  111        * comma-separated list of SSL/TLS protocol versions to
  112        * enable.</p>
  113        */
  114       public Socket createSocket(String host, int port) throws IOException {
  115           // Retrieve the SSLSocketFactory
  116           //
  117           final SocketFactory sslSocketFactory = getDefaultClientSocketFactory();
  118           // Create the SSLSocket
  119           //
  120           final SSLSocket sslSocket = (SSLSocket)
  121               sslSocketFactory.createSocket(host, port);
  122           // Set the SSLSocket Enabled Cipher Suites
  123           //
  124           final String enabledCipherSuites =
  125               System.getProperty("javax.rmi.ssl.client.enabledCipherSuites");
  126           if (enabledCipherSuites != null) {
  127               StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
  128               int tokens = st.countTokens();
  129               String enabledCipherSuitesList[] = new String[tokens];
  130               for (int i = 0 ; i < tokens; i++) {
  131                   enabledCipherSuitesList[i] = st.nextToken();
  132               }
  133               try {
  134                   sslSocket.setEnabledCipherSuites(enabledCipherSuitesList);
  135               } catch (IllegalArgumentException e) {
  136                   throw (IOException)
  137                       new IOException(e.getMessage()).initCause(e);
  138               }
  139           }
  140           // Set the SSLSocket Enabled Protocols
  141           //
  142           final String enabledProtocols =
  143               System.getProperty("javax.rmi.ssl.client.enabledProtocols");
  144           if (enabledProtocols != null) {
  145               StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
  146               int tokens = st.countTokens();
  147               String enabledProtocolsList[] = new String[tokens];
  148               for (int i = 0 ; i < tokens; i++) {
  149                   enabledProtocolsList[i] = st.nextToken();
  150               }
  151               try {
  152                   sslSocket.setEnabledProtocols(enabledProtocolsList);
  153               } catch (IllegalArgumentException e) {
  154                   throw (IOException)
  155                       new IOException(e.getMessage()).initCause(e);
  156               }
  157           }
  158           // Return the preconfigured SSLSocket
  159           //
  160           return sslSocket;
  161       }
  162   
  163       /**
  164        * <p>Indicates whether some other object is "equal to" this one.</p>
  165        *
  166        * <p>Because all instances of this class are functionally equivalent
  167        * (they all use the default
  168        * <code>SSLSocketFactory</code>), this method simply returns
  169        * <code>this.getClass().equals(obj.getClass())</code>.</p>
  170        *
  171        * <p>A subclass should override this method (as well
  172        * as {@link #hashCode()}) if its instances are not all
  173        * functionally equivalent.</p>
  174        */
  175       public boolean equals(Object obj) {
  176           if (obj == null) return false;
  177           if (obj == this) return true;
  178           return this.getClass().equals(obj.getClass());
  179       }
  180   
  181       /**
  182        * <p>Returns a hash code value for this
  183        * <code>SslRMIClientSocketFactory</code>.</p>
  184        *
  185        * @return a hash code value for this
  186        * <code>SslRMIClientSocketFactory</code>.
  187        */
  188       public int hashCode() {
  189           return this.getClass().hashCode();
  190       }
  191   
  192       // We use a static field because:
  193       //
  194       //    SSLSocketFactory.getDefault() always returns the same object
  195       //    (at least on Sun's implementation), and we want to make sure
  196       //    that the Javadoc & the implementation stay in sync.
  197       //
  198       // If someone needs to have different SslRMIClientSocketFactory factories
  199       // with different underlying SSLSocketFactory objects using different key
  200       // and trust stores, he can always do so by subclassing this class and
  201       // overriding createSocket(String host, int port).
  202       //
  203       private static SocketFactory defaultSocketFactory = null;
  204   
  205       private static synchronized SocketFactory getDefaultClientSocketFactory() {
  206           if (defaultSocketFactory == null)
  207               defaultSocketFactory = SSLSocketFactory.getDefault();
  208           return defaultSocketFactory;
  209       }
  210   
  211       private static final long serialVersionUID = -8310631444933958385L;
  212   }

Save This Page
Home » openjdk-7 » javax » rmi » ssl » [javadoc | source]