From 9973c43fac0a3d1059cae2c6c3efebb448eaae60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alen=20Vre=C4=8Dko?= <332217+avrecko@users.noreply.github.com> Date: Sat, 21 Dec 2024 21:40:33 +0100 Subject: [PATCH] Support for setting SNI extension on ssl socket handshake. Need this to support virtual host ssl servers. --- src/one/nio/net/NativeSslSocket.java | 2 +- src/one/nio/net/Socket.java | 2 +- src/one/nio/net/native/ssl.c | 20 +++++++++++++++++++- src/one/nio/pool/SocketPool.java | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/one/nio/net/NativeSslSocket.java b/src/one/nio/net/NativeSslSocket.java index c460e01..049d5be 100755 --- a/src/one/nio/net/NativeSslSocket.java +++ b/src/one/nio/net/NativeSslSocket.java @@ -92,7 +92,7 @@ public Object getSslOption(SslOption option) { return null; } @Override - public synchronized native void handshake() throws IOException; + public synchronized native void handshake(String sniHostName) throws IOException; @Override public synchronized native int writeRaw(long buf, int count, int flags) throws IOException; diff --git a/src/one/nio/net/Socket.java b/src/one/nio/net/Socket.java index 30621cf..f0b0833 100755 --- a/src/one/nio/net/Socket.java +++ b/src/one/nio/net/Socket.java @@ -174,7 +174,7 @@ public int send(ByteBuffer data, int flags, String host, int port) throws IOExce return send(data, flags, InetAddress.getByName(host), port); } - public void handshake() throws IOException { + public void handshake(String sniHostname) throws IOException { // Only for SSL sockets } diff --git a/src/one/nio/net/native/ssl.c b/src/one/nio/net/native/ssl.c index c047cca..9d8b0c9 100755 --- a/src/one/nio/net/native/ssl.c +++ b/src/one/nio/net/native/ssl.c @@ -1109,12 +1109,30 @@ Java_one_nio_net_NativeSslSocket_sslFree(JNIEnv* env, jclass cls, jlong sslptr) SSL_free(ssl); } +static void set_tlsext_host_name(JNIEnv* env, SSL* ssl, jstring hostName) { + if (hostName != NULL) { + // set sni if hostname set to not ipv4/ipv6 + struct in_addr ipv4; + struct in6_addr ipv6; + const char *value = (*env) -> GetStringUTFChars(env, hostName, NULL); + bool isIp = inet_pton(AF_INET, value, &ipv4) != 1 && inet_pton(AF_INET6, value, &ipv6) != 1; + (*env)->ReleaseStringUTFChars(env, hostName, value); + if (!isIp) { + int result = SSL_set_tlsext_host_name(ssl, value); + if (result <= 0) { + check_ssl_error(env, ssl, result); + } + } + } +} + JNIEXPORT void JNICALL -Java_one_nio_net_NativeSslSocket_handshake(JNIEnv* env, jobject self) { +Java_one_nio_net_NativeSslSocket_handshake(JNIEnv* env, jobject self, jstring hostName) { SSL* ssl = (SSL*)(intptr_t) (*env)->GetLongField(env, self, f_ssl); if (ssl == NULL) { throw_socket_closed(env); } else { + set_tlsext_host_name(env, ssl, hostName); int result = SSL_do_handshake(ssl); if (result <= 0) { check_ssl_error(env, ssl, result); diff --git a/src/one/nio/pool/SocketPool.java b/src/one/nio/pool/SocketPool.java index bc23db5..4a7378b 100755 --- a/src/one/nio/pool/SocketPool.java +++ b/src/one/nio/pool/SocketPool.java @@ -177,7 +177,7 @@ public Socket createObject() throws PoolException { if (sslContext != null) { socket = socket.sslWrap(sslContext); - socket.handshake(); + socket.handshake(host); } return socket;