diff --git a/README.md b/README.md index 1adb3b83..9facb71a 100644 --- a/README.md +++ b/README.md @@ -531,6 +531,12 @@ are enabled in different ways depending on the JDK implementation. For Oracle/OpenJDK and variants, this System property enables session tickets and was added in Java 13. Should be set to "true" to enable. +**wolfjsse.autoSNI (boolean)** - Controls automatic Server Name Indication (SNI) +extension setting based on hostname or peer address. When set to "true", enables +legacy behavior where SNI is automatically configured from hostname/peer information +even without explicit SSLParameters configuration. Default value is "false", where +SNI is only set when explicitly configured through SSLParameters. + If there are other System properties you would like to use with wolfJSSE, please contact support@wolfssl.com. diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index 0a0f2307..187ca23a 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -876,7 +876,6 @@ private static boolean checkBooleanProperty(String prop, * what String. */ private void setLocalServerNames() { - /* Do not add SNI if system property has been set to false */ boolean enableSNI = checkBooleanProperty("jsse.enableSNIExtension", true); @@ -886,6 +885,13 @@ private void setLocalServerNames() { boolean trustNameService = checkBooleanProperty("jdk.tls.trustNameService", false); + /* + * Check if automatic SNI setting is enabled via Security property. + * This allows users to enable legacy hostname-based SNI behavior + * through java.security configuration rather than JVM arguments. */ + boolean autoSNI = "true".equalsIgnoreCase( + Security.getProperty("wolfjsse.autoSNI")); + if (!enableSNI) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "jsse.enableSNIExtension property set to false, " + @@ -904,8 +910,7 @@ else if (this.clientMode) { if (sni != null) { this.ssl.useSNI((byte)sni.getType(), sni.getEncoded()); } - - } else { + } else if (autoSNI) { if (this.peerAddr != null && trustNameService) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "setting SNI extension with " + @@ -914,8 +919,7 @@ else if (this.clientMode) { this.ssl.useSNI((byte)0, this.peerAddr.getHostName().getBytes()); - } - else if (this.hostname != null) { + } else if (this.hostname != null) { if (peerAddr != null) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "jdk.tls.trustNameService not set to true, " + @@ -930,12 +934,13 @@ else if (this.hostname != null) { "hostname: " + this.hostname); } this.ssl.useSNI((byte)0, this.hostname.getBytes()); - - } - else { + } else { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "hostname and peerAddr are null, not setting SNI"); } + } else { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "No SNI configured through SSLParameters, not setting SNI"); } } } diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java index 9405ea19..313c52fc 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java @@ -3287,6 +3287,102 @@ public Void call() throws Exception { System.out.println("\t... passed"); } + @Test + public void testAutoSNIProperty() throws Exception { + System.out.print("\tTesting autoSNI property"); + + /* Save original Security property value */ + String originalProp = Security.getProperty("wolfjsse.autoSNI"); + + try { + /* Test with autoSNI enabled */ + Security.setProperty("wolfjsse.autoSNI", "true"); + + /* Create new CTX */ + this.ctx = tf.createSSLContext("TLS", ctxProvider); + + /* Create SSLServerSocket first to get ephemeral port */ + SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory() + .createServerSocket(0); + + /* Set up test arguments without explicit SNI configuration. + * With autoSNI=true, SNI should be automatically set based on hostname */ + TestArgs sArgs = new TestArgs(null, + null, true, + true, + true, + null); + TestArgs cArgs = new TestArgs(null, + null, + false, + false, + true, + null); + + CountDownLatch sDoneLatch = new CountDownLatch(1); + CountDownLatch cDoneLatch = new CountDownLatch(1); + + TestServer server = new TestServer(this.ctx, ss, sArgs, 1, sDoneLatch); + server.start(); + + TestClient client = new TestClient(this.ctx, ss.getLocalPort(), cArgs, + cDoneLatch); + client.start(); + + cDoneLatch.await(); + sDoneLatch.await(); + + Exception srvException = server.getException(); + if (srvException != null) { + throw srvException; + } + + Exception cliException = client.getException(); + if (cliException != null) { + throw cliException; + } + + /* Test with autoSNI disabled */ + Security.setProperty("wolfjsse.autoSNI", "false"); + + ss = (SSLServerSocket)ctx.getServerSocketFactory() + .createServerSocket(0); + + sDoneLatch = new CountDownLatch(1); + cDoneLatch = new CountDownLatch(1); + + server = new TestServer(this.ctx, ss, sArgs, + 1, sDoneLatch); + server.start(); + + client = new TestClient(this.ctx, ss.getLocalPort(), cArgs, + cDoneLatch); + client.start(); + + cDoneLatch.await(); + sDoneLatch.await(); + + srvException = server.getException(); + if (srvException != null) { + throw srvException; + } + + cliException = client.getException(); + if (cliException != null) { + throw cliException; + } + + System.out.println("\t\t... passed"); + + } finally { + /* Restore original property value */ + if (originalProp != null) { + Security.setProperty("wolfjsse.autoSNI", originalProp); + } else { + Security.setProperty("wolfjsse.autoSNI", "true"); + } + } + } /** * Inner class used to hold configuration options for