Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/windows-vs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
ant_version:
description: 'Apache Ant version to use'
required: false
default: '1.10.15'
default: '1.10.16'
type: string
platform_toolset:
description: 'Visual Studio platform toolset (auto-detect if not specified)'
Expand Down
21 changes: 0 additions & 21 deletions src/java/com/wolfssl/provider/jsse/WolfSSLAuthStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -411,27 +411,6 @@ else if (!sessionCipherSuiteAvailable(

ses.isFromTable = true;

/* Check if the session has stored SNI server names */
List<SNIServerName> sniNames = ses.getSNIServerNames();
if (sniNames != null && !sniNames.isEmpty()) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "Found SNI server names in cached session");

/* Apply SNI settings to the SSL connection */
for (SNIServerName name : sniNames) {
if (name instanceof SNIHostName) {
String hostName = ((SNIHostName)name).getAsciiName();
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "Applying SNI hostname for resumption: " +
hostName);

/* Set the SNI directly on the SSL object */
ssl.useSNI((byte)WolfSSL.WOLFSSL_SNI_HOST_NAME,
hostName.getBytes(StandardCharsets.UTF_8));
}
}
}

if (ses.resume(ssl) != WolfSSL.SSL_SUCCESS) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "native wolfSSL_set_session() failed, " +
Expand Down
27 changes: 22 additions & 5 deletions src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -1122,25 +1122,38 @@ else if (this.clientMode) {

/* Explicitly set if user has set through SSLParameters. Check
* wolfSSL-specific server names first, then fall back to standard
* SSLParameters server names (set via parent setServerNames()). */
* SSLParameters server names (set via parent setServerNames()).
* If neither have been set and session is being resumed, check
* cached SNI */
boolean sniSet = false;
List<WolfSSLSNIServerName> names =
this.params.getWolfSSLServerNames();
List<SNIServerName> parentNames =
this.params.getServerNames();
List<SNIServerName> sniServerNames =
(this.session == null) ? null :
this.session.getSNIServerNames();
if (names != null && !names.isEmpty()) {
WolfSSLSNIServerName sni = names.get(0);
if (sni != null) {
this.ssl.useSNI((byte)sni.getType(), sni.getEncoded());
sniSet = true;
}
} else if (parentNames != null && !parentNames.isEmpty()) {
SNIServerName sni = parentNames.get(0);
if (sni != null) {
this.ssl.useSNI((byte)sni.getType(), sni.getEncoded());
sniSet = true;
}
} else if (sniServerNames != null && !sniServerNames.isEmpty()) {
SNIServerName sni = sniServerNames.get(0);
if (sni != null) {
this.ssl.useSNI((byte)sni.getType(), sni.getEncoded());
sniSet = true;
}
}

if ((names == null || names.isEmpty()) &&
(parentNames == null || parentNames.isEmpty()) && autoSNI) {
if (!sniSet && autoSNI) {
if (this.peerAddr != null && this.jdkTlsTrustNameService) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "setting SNI extension with " +
Expand Down Expand Up @@ -1173,10 +1186,14 @@ else if (this.clientMode) {
() -> "hostname and peerAddr are null, " +
"not setting SNI");
}
} else if (sniSet) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "SNI configured through SSLParameters " +
"or session resumption");
} else {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "No SNI configured through SSLParameters, " +
"not setting SNI");
() -> "No SNI configured through SSLParameters " +
"or session resumption, not setting SNI");
}
}
}
Expand Down
120 changes: 120 additions & 0 deletions src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIMatcher;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.SSLEngineResult;
Expand Down Expand Up @@ -1212,6 +1215,123 @@ public void testReuseSession()
}
}

/**
* Test that SNI is correctly preserved across TLS session resumption
* when using SSLEngine. Regression test for the bug where
* setLocalServerNames() would overwrite session-cached SNI with the
* autoSNI hostname on resumption.
*/
@Test
public void testEngineSessionResumptionSNI()
throws NoSuchProviderException, NoSuchAlgorithmException,
KeyManagementException, KeyStoreException, IOException,
CertificateException, UnrecoverableKeyException {

System.out.print("\tEngine session resumption SNI");

/* Requires WOLFSSL_ALWAYS_KEEP_SNI, enabled by default with
* --enable-jni in wolfSSL 5.7.6+ (PR 8283) */
if (WolfSSL.getLibVersionHex() < 0x05007006L) {
System.out.println("\t... skipped");
return;
}

if (!enabledProtocols.contains("TLSv1.3")) {
System.out.println("\t... skipped");
return;
}
Comment thread
rlm2002 marked this conversation as resolved.

/* wolfjsse.clientSessionCache.disabled could be set in users
* java.security file which would cause this test to not work
* properly. Save their setting here, and re-enable session
* cache for this test */
String originalProp = Security.getProperty(
"wolfjsse.clientSessionCache.disabled");
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");

/* SNI hostname intentionally differs from peer hostname.
* autoSNI would send "localhost"; the fix sends "www.example.com"
* from the session cache instead. The server SNI matcher only
* accepts "www.example.com", so the outcome distinguishes the two. */
final String sniHostname = "www.example.com";
final String peerHostname = "localhost";
final SNIMatcher matcher =
SNIHostName.createSNIMatcher("www\\.example\\.com");

try {
int ret;
SSLEngine client1 = null, client2 = null;
SSLEngine server1 = null, server2 = null;
SSLContext ctx13 = tf.createSSLContext("TLSv1.3", engineProvider);

/* --- Connection #1: explicit SNI, caches it in the session --- */
try {
client1 = ctx13.createSSLEngine(peerHostname, 8443);
client1.setUseClientMode(true);
SSLParameters cliParams1 = client1.getSSLParameters();
cliParams1.setServerNames(
Arrays.asList(new SNIHostName(sniHostname)));
client1.setSSLParameters(cliParams1);

server1 = ctx13.createSSLEngine();
server1.setUseClientMode(false);
SSLParameters srvParams1 = server1.getSSLParameters();
srvParams1.setSNIMatchers(Arrays.asList(matcher));
server1.setSSLParameters(srvParams1);

ret = tf.testConnection(server1, client1, null, null, "Hello");
if (ret != 0) {
error("\t... failed");
fail("Initial connection with explicit SNI failed");
}
} finally {
if (server1 != null && client1 != null) {
tf.CloseConnection(server1, client1, false);
}
}

/* Connection #2: SNI must come from session cache */
try {
client2 = ctx13.createSSLEngine(peerHostname, 8443);
client2.setUseClientMode(true);
/* Intentionally no setSSLParameters() with server names.
* peerHostname ("localhost") makes
* isEngineConnectionWithHost=true and autoSNI=true. Without
* the fix, autoSNI would send "localhost" and the server
* would reject it. With the fix, the session-cached
* "www.example.com" is used instead. */

server2 = ctx13.createSSLEngine();
server2.setUseClientMode(false);
SSLParameters srvParams2 = server2.getSSLParameters();
srvParams2.setSNIMatchers(Arrays.asList(matcher));
server2.setSSLParameters(srvParams2);

ret = tf.testConnection(server2, client2, null, null, "Hello");
} finally {
if (server2 != null && client2 != null) {
tf.CloseConnection(server2, client2, false);
}
}
if (ret != 0) {
error("\t... failed");
fail("Resumed connection did not carry session-cached SNI");
Comment thread
rlm2002 marked this conversation as resolved.
}

pass("\t... passed");

} catch (Exception e) {
error("\t... failed");
e.printStackTrace();
fail("testEngineSessionResumptionSNI failed with exception: " + e);
} finally {
if (originalProp != null && !originalProp.isEmpty()) {
Security.setProperty(
"wolfjsse.clientSessionCache.disabled", originalProp);
}
}
}

/**
* More extended threading test of SSLEngine class.
* Launches a simple multi-threaded SSLSocket-based server, which
Expand Down
Loading