javasocketsssltcpsslsocketfactory

Java: How to abstract between "regular" TCP Socket and SSLSocket


Edit: Removed startHandshake(); as it's irrelevant to the question and rarely needed (for example, not in my case)

I have a rather specific and rare client-server protocol (over TCP).
I've implemented it using SSLSocket.
Now, I foresee that I might need to use the same protocol over an un-encrypted connection.

My problem is that the class implementing the protocol has a field: public SSLSocket currentSocket;
(and then the methods in my client class do all sorts of .read(), .write(), flush()...)

I thought about changing the field type, like so: public Socket currentSocket;
However, then, the problem is that my connection procedure is incompatible:

public static void connect () {
currentSocket = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
...

I don't want to re-implement my whole client just for this difference...

Is there a way to make my currentSocket field more abstract, so that I can define it in the same client, then instruct a slightly different client code path depending on a known variable (something like needSSLsocket=true) for the instantiation and connection?


Solution

  • SSLSocket extends Socket, so you can assign an SSLSocket object to a Socket variable. You are right to change your currentSocket field to a Socket. Simply use another variable to handle the SSLSocket when needed, eg:

    public static void connect () {
        if (needSSLsocket) {
            SSLSocket ssl = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
            ssl.startHandshake();
            ...
            currentSocket = ssl;
    
            /* or:
            currentSocket = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
            ((SSLSocket) currentSocket).startHandshake();
            ...
            */
        } else {
            currentSocket = new Socket(host, port);
        }
        ...
    }