Skip to content

Commit 5be8623

Browse files
committed
add regression test for SNI names
1 parent c3165b6 commit 5be8623

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
import javax.net.ssl.SSLSocket;
5353
import javax.net.ssl.SSLServerSocket;
5454
import javax.net.ssl.TrustManager;
55+
import javax.net.ssl.SNIHostName;
56+
import javax.net.ssl.SNIMatcher;
57+
import javax.net.ssl.SSLParameters;
5558
import javax.net.ssl.X509TrustManager;
5659
import javax.net.ssl.X509ExtendedTrustManager;
5760
import javax.net.ssl.SSLEngineResult;
@@ -1212,6 +1215,123 @@ public void testReuseSession()
12121215
}
12131216
}
12141217

1218+
/**
1219+
* Test that SNI is correctly preserved across TLS session resumption
1220+
* when using SSLEngine. Regression test for the bug where
1221+
* setLocalServerNames() would overwrite session-cached SNI with the
1222+
* autoSNI hostname on resumption.
1223+
*/
1224+
@Test
1225+
public void testEngineSessionResumptionSNI()
1226+
throws NoSuchProviderException, NoSuchAlgorithmException,
1227+
KeyManagementException, KeyStoreException, IOException,
1228+
CertificateException, UnrecoverableKeyException {
1229+
1230+
System.out.print("\tEngine session resumption SNI");
1231+
1232+
/* Requires WOLFSSL_ALWAYS_KEEP_SNI, enabled by default with
1233+
* --enable-jni in wolfSSL 5.7.6+ (PR 8283) */
1234+
if (WolfSSL.getLibVersionHex() < 0x05007006L) {
1235+
System.out.println("\t... skipped");
1236+
return;
1237+
}
1238+
1239+
if (!enabledProtocols.contains("TLSv1.3")) {
1240+
System.out.println("\t... skipped");
1241+
return;
1242+
}
1243+
1244+
/* wolfjsse.clientSessionCache.disabled could be set in users
1245+
* java.security file which would cause this test to not work
1246+
* properly. Save their setting here, and re-enable session
1247+
* cache for this test */
1248+
String originalProp = Security.getProperty(
1249+
"wolfjsse.clientSessionCache.disabled");
1250+
Security.setProperty("wolfjsse.clientSessionCache.disabled", "false");
1251+
1252+
/* SNI hostname intentionally differs from peer hostname.
1253+
* autoSNI would send "localhost"; the fix sends "www.example.com"
1254+
* from the session cache instead. The server SNI matcher only
1255+
* accepts "www.example.com", so the outcome distinguishes the two. */
1256+
final String sniHostname = "www.example.com";
1257+
final String peerHostname = "localhost";
1258+
final SNIMatcher matcher =
1259+
SNIHostName.createSNIMatcher("www\\.example\\.com");
1260+
1261+
try {
1262+
int ret;
1263+
SSLEngine client1 = null, client2 = null;
1264+
SSLEngine server1 = null, server2 = null;
1265+
SSLContext ctx13 = tf.createSSLContext("TLSv1.3", engineProvider);
1266+
1267+
/* --- Connection #1: explicit SNI, caches it in the session --- */
1268+
try {
1269+
client1 = ctx13.createSSLEngine(peerHostname, 8443);
1270+
client1.setUseClientMode(true);
1271+
SSLParameters cliParams1 = client1.getSSLParameters();
1272+
cliParams1.setServerNames(
1273+
Arrays.asList(new SNIHostName(sniHostname)));
1274+
client1.setSSLParameters(cliParams1);
1275+
1276+
server1 = ctx13.createSSLEngine();
1277+
server1.setUseClientMode(false);
1278+
SSLParameters srvParams1 = server1.getSSLParameters();
1279+
srvParams1.setSNIMatchers(Arrays.asList(matcher));
1280+
server1.setSSLParameters(srvParams1);
1281+
1282+
ret = tf.testConnection(server1, client1, null, null, "Hello");
1283+
if (ret != 0) {
1284+
error("\t... failed");
1285+
fail("Initial connection with explicit SNI failed");
1286+
}
1287+
} finally {
1288+
if (server1 != null && client1 != null) {
1289+
tf.CloseConnection(server1, client1, false);
1290+
}
1291+
}
1292+
1293+
/* Connection #2: SNI must come from session cache */
1294+
try {
1295+
client2 = ctx13.createSSLEngine(peerHostname, 8443);
1296+
client2.setUseClientMode(true);
1297+
/* Intentionally no setSSLParameters() with server names.
1298+
* peerHostname ("localhost") makes
1299+
* isEngineConnectionWithHost=true and autoSNI=true. Without
1300+
* the fix, autoSNI would send "localhost" and the server
1301+
* would reject it. With the fix, the session-cached
1302+
* "www.example.com" is used instead. */
1303+
1304+
server2 = ctx13.createSSLEngine();
1305+
server2.setUseClientMode(false);
1306+
SSLParameters srvParams2 = server2.getSSLParameters();
1307+
srvParams2.setSNIMatchers(Arrays.asList(matcher));
1308+
server2.setSSLParameters(srvParams2);
1309+
1310+
ret = tf.testConnection(server2, client2, null, null, "Hello");
1311+
} finally {
1312+
if (server2 != null && client2 != null) {
1313+
tf.CloseConnection(server2, client2, false);
1314+
}
1315+
}
1316+
if (ret != 0) {
1317+
error("\t... failed");
1318+
fail("Resumed connection did not carry session-cached SNI");
1319+
}
1320+
1321+
pass("\t... passed");
1322+
1323+
} catch (Exception e) {
1324+
error("\t... failed");
1325+
e.printStackTrace();
1326+
fail("testEngineSessionResumptionSNI failed with exception: " + e);
1327+
} finally {
1328+
if (originalProp != null && !originalProp.isEmpty()) {
1329+
Security.setProperty(
1330+
"wolfjsse.clientSessionCache.disabled", originalProp);
1331+
}
1332+
}
1333+
}
1334+
12151335
/**
12161336
* More extended threading test of SSLEngine class.
12171337
* Launches a simple multi-threaded SSLSocket-based server, which

0 commit comments

Comments
 (0)