Skip to content

Commit

Permalink
Enable Server Name Indication Support - Initial / Reference commit
Browse files Browse the repository at this point in the history
This is on a different branch than the [Python/Ruby SNI mods][1] just to make
testing easier for myself. I.e. I had code that worked with the 2.3.3
driver where as the recent [Jackson changes][2] broke that. However, the
underlying SNI changes will work with the Next branch.

This includes some commented out printlns that ultimately need removing,
but they were for my debugging and I don't want to forget that.

Enabling SNI itself is easy, the tricky bit for me was modifying a test
app to work with it. You have to use the SSLContext option similar to
[here][3]. For testing I've just used a null sslContext:

	private static final String DEFAULT_SSL_PROTOCOL = "TLSv1.2";

	...

	Connection conn = null;
	Connection.Builder builder = r.connection().
	    hostname(host).
	    port(port).
	    authKey(authKey);

	final SSLContext sslContext = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL);
	sslContext.init(null, null, null);
	conn = builder.sslContext(sslContext).connect();

[1]: https://github.com/atomicules/rethinkdb/commits/sni
[2]: rethinkdb#6157
[3]: https://github.com/pires/rethinkdb-ssl-test/blob/master/src/main/java/com/github/pires/App.java#L70
  • Loading branch information
atomicules committed Dec 19, 2016
1 parent 9c21e9b commit 771f34d
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions drivers/java/src/main/java/com/rethinkdb/net/SocketWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import com.rethinkdb.gen.exc.ReqlDriverError;

import javax.net.SocketFactory;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.DataInputStream;
Expand All @@ -14,7 +17,9 @@
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Optional;
import java.util.List;

public class SocketWrapper {
// networking stuff
Expand Down Expand Up @@ -56,13 +61,23 @@ void connect(Handshake handshake) {

// should we secure the connection?
if (sslContext.isPresent()) {
// System.out.println("sslContext");
socketFactory = sslContext.get().getSocketFactory();
SSLSocketFactory sslSf = (SSLSocketFactory) socketFactory;
sslSocket = (SSLSocket) sslSf.createSocket(socket,
socket.getInetAddress().getHostAddress(),
socket.getPort(),
true);

// SNI support, Java 8 only
SNIHostName serverName = new SNIHostName(hostname);
List<SNIServerName> serverNames = new ArrayList<>(1);
serverNames.add(serverName);

SSLParameters params = sslSocket.getSSLParameters();
params.setServerNames(serverNames);
sslSocket.setSSLParameters(params);

// replace input/output streams
readStream = new DataInputStream(sslSocket.getInputStream());
writeStream = sslSocket.getOutputStream();
Expand All @@ -88,6 +103,7 @@ void connect(Handshake handshake) {
toWrite = handshake.nextMessage(serverMsg);
}
} catch (IOException e) {
// System.out.println(e);
throw new ReqlDriverError("Connection timed out.", e);
}
}
Expand Down

2 comments on commit 771f34d

@atomicules
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to decide if sslContext.init(null, null, null); is valid or not.

I can see that specifying a trust manager might be useful, but as far as I can tell specifying a trust manager always references a key store, I.e: Here and here.

Also, as per the init description here:

Initializes this context. Either of the first two parameters may be null in which case the installed security providers will be searched for the highest priority implementation of the appropriate factory. Likewise, the secure random parameter may be null in which case the default implementation will be used.

it implies it picks up the system defaults if null. Well, at least I think that is what it is saying.

@atomicules
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually verified this with -Djavax.net.debug=SSL,trustmanager (had to fight gradle) and it is using the default trust manager and everything is hunkydory here. Yay!

Please sign in to comment.