jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java
author xdono
Wed, 02 Jul 2008 12:55:45 -0700
changeset 715 f16baef3a20e
parent 51 6fe31bc95bbc
child 5506 202f599c92aa
permissions -rw-r--r--
6719955: Update copyright year Summary: Update copyright year for files that have been modified in 2008 Reviewed-by: ohair, tbell
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 51
diff changeset
     2
 * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.rmi.ssl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.net.Socket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.rmi.server.RMIClientSocketFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.StringTokenizer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.net.SocketFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.net.ssl.SSLSocket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.net.ssl.SSLSocketFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * <p>An <code>SslRMIClientSocketFactory</code> instance is used by the RMI
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * runtime in order to obtain client sockets for RMI calls via SSL.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * <p>This class implements <code>RMIClientSocketFactory</code> over
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * the Secure Sockets Layer (SSL) or Transport Layer Security (TLS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * protocols.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * <p>This class creates SSL sockets using the default
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * <code>SSLSocketFactory</code> (see {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * SSLSocketFactory#getDefault}).  All instances of this class are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * functionally equivalent.  In particular, they all share the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * truststore, and the same keystore when client authentication is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * required by the server.  This behavior can be modified in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * subclasses by overriding the {@link #createSocket(String,int)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * method; in that case, {@link #equals(Object) equals} and {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * #hashCode() hashCode} may also need to be overridden.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <p>If the system property
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * <code>javax.rmi.ssl.client.enabledCipherSuites</code> is specified,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * the {@link #createSocket(String,int)} method will call {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * SSLSocket#setEnabledCipherSuites(String[])} before returning the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * socket.  The value of this system property is a string that is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * comma-separated list of SSL/TLS cipher suites to enable.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * <p>If the system property
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * <code>javax.rmi.ssl.client.enabledProtocols</code> is specified,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * the {@link #createSocket(String,int)} method will call {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * SSLSocket#setEnabledProtocols(String[])} before returning the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * socket.  The value of this system property is a string that is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * comma-separated list of SSL/TLS protocol versions to enable.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * @see javax.net.ssl.SSLSocketFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * @see javax.rmi.ssl.SslRMIServerSocketFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
public class SslRMIClientSocketFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    implements RMIClientSocketFactory, Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     * <p>Creates a new <code>SslRMIClientSocketFactory</code>.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    public SslRMIClientSocketFactory() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        // We don't force the initialization of the default SSLSocketFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        // at construction time - because the RMI client socket factory is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        // created on the server side, where that initialization is a priori
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        // meaningless, unless both server and client run in the same JVM.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        // We could possibly override readObject() to force this initialization,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        // but it might not be a good idea to actually mix this with possible
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        // deserialization problems.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        // So contrarily to what we do for the server side, the initialization
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        // of the SSLSocketFactory will be delayed until the first time
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        // createSocket() is called - note that the default SSLSocketFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        // might already have been initialized anyway if someone in the JVM
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        // already called SSLSocketFactory.getDefault().
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * <p>Creates an SSL socket.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * <p>If the system property
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * <code>javax.rmi.ssl.client.enabledCipherSuites</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * specified, this method will call {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * SSLSocket#setEnabledCipherSuites(String[])} before returning
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * the socket. The value of this system property is a string that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * is a comma-separated list of SSL/TLS cipher suites to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * enable.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * <p>If the system property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * <code>javax.rmi.ssl.client.enabledProtocols</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * specified, this method will call {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * SSLSocket#setEnabledProtocols(String[])} before returning the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * socket. The value of this system property is a string that is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * comma-separated list of SSL/TLS protocol versions to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * enable.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    public Socket createSocket(String host, int port) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        // Retrieve the SSLSocketFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        final SocketFactory sslSocketFactory = getDefaultClientSocketFactory();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        // Create the SSLSocket
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        final SSLSocket sslSocket = (SSLSocket)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            sslSocketFactory.createSocket(host, port);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        // Set the SSLSocket Enabled Cipher Suites
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        //
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   124
        final String enabledCipherSuites =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            System.getProperty("javax.rmi.ssl.client.enabledCipherSuites");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        if (enabledCipherSuites != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            int tokens = st.countTokens();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            String enabledCipherSuitesList[] = new String[tokens];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            for (int i = 0 ; i < tokens; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                enabledCipherSuitesList[i] = st.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                sslSocket.setEnabledCipherSuites(enabledCipherSuitesList);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            } catch (IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                throw (IOException)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                    new IOException(e.getMessage()).initCause(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        // Set the SSLSocket Enabled Protocols
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        //
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   142
        final String enabledProtocols =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            System.getProperty("javax.rmi.ssl.client.enabledProtocols");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        if (enabledProtocols != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            int tokens = st.countTokens();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            String enabledProtocolsList[] = new String[tokens];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            for (int i = 0 ; i < tokens; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                enabledProtocolsList[i] = st.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                sslSocket.setEnabledProtocols(enabledProtocolsList);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            } catch (IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                throw (IOException)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                    new IOException(e.getMessage()).initCause(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        // Return the preconfigured SSLSocket
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        return sslSocket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * <p>Indicates whether some other object is "equal to" this one.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * <p>Because all instances of this class are functionally equivalent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * (they all use the default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * <code>SSLSocketFactory</code>), this method simply returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * <code>this.getClass().equals(obj.getClass())</code>.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * <p>A subclass should override this method (as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * as {@link #hashCode()}) if its instances are not all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * functionally equivalent.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    public boolean equals(Object obj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        if (obj == null) return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        if (obj == this) return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        return this.getClass().equals(obj.getClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * <p>Returns a hash code value for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * <code>SslRMIClientSocketFactory</code>.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * @return a hash code value for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * <code>SslRMIClientSocketFactory</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        return this.getClass().hashCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    // We use a static field because:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    //    SSLSocketFactory.getDefault() always returns the same object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    //    (at least on Sun's implementation), and we want to make sure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    //    that the Javadoc & the implementation stay in sync.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    // If someone needs to have different SslRMIClientSocketFactory factories
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    // with different underlying SSLSocketFactory objects using different key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    // and trust stores, he can always do so by subclassing this class and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    // overriding createSocket(String host, int port).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    private static SocketFactory defaultSocketFactory = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    private static synchronized SocketFactory getDefaultClientSocketFactory() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        if (defaultSocketFactory == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            defaultSocketFactory = SSLSocketFactory.getDefault();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        return defaultSocketFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    private static final long serialVersionUID = -8310631444933958385L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
}