2

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);
...
  • java.net.Socket 's default constructor obviously doesn't accept keystore stuff

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

  • One thought I have is, when I need a plaintext Socket, to create an SSLSocket with no encryption.
    I don't know if that's a professional way of doing it or if it will even work (the server will expect a plaintext client socket in the new use case)

  • My other idea is to define two fields, one for plaintext socket, one for SSL socket and then use logic to link the in/out streams to the correct field, as needed. However, that will result in a "hanging" field. If you use SSL, there will be a redundant field Socket plaintextSocket and vice-versa...

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?

4
  • 1
    (1) You can write your own factory that creates the socket required, and (2) you don't need to call startHandshake(). You should be able to write your entire application in terms of Socket, other than what happens in the factory method, unless you are doing fancy stuff like session invalidation or re-handshaking. Commented Jan 28, 2020 at 4:37
  • @user207421 I thought about my own factory but it looks like more fuss than it's worth. I got pretty well contained use cases. As for startHandShake - I am afraid I am a prisoner of ignorance here. I don't know how to connect an SSL socket without it. Anyway, thanks for your valuable input! Commented Jan 28, 2020 at 12:52
  • 1
    startHandshake() is called automatically on the first I/O to/from the socket. You don't have t call it yourself. You only need to call it when you want to rekey the session. Commented Jan 28, 2020 at 21:34
  • @user207421 YES! I simply commented out that handshake and things work as usual :) To be honest, when developing my client, I had to deal with so much, I didn't question every piece of guidance I was able to find. One less action means a lot in my style of developing - thank you <3 Commented Jan 29, 2020 at 17:24

1 Answer 1

3

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);
    }
    ...
}
Sign up to request clarification or add additional context in comments.

4 Comments

Tested and adopted. Thank you! I will just add a comment about startHandshake();
OK that edit was rejected but for future readers: startHandshake(); , as shown in my question and irrelevant to it, may not be an essential part of an SSL socket connection procedure, except in rare cases.
@DraxDomax "startHandshake(); , as shown in my question and irrelevant to it" - then you should have left it out of the question altogether to begin with.
to be honest I thought I could leave it there. As, from an objective point of view, another coder might actually need to call that method and it shows things you cannot perform on a Socket object, adding to the impetus to bridge the types. But I'll be damned to argue with 400k :) I will edit. Thanks again for your help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.