Skip to content

Commit ca4bfe1

Browse files
authored
Merge pull request #287 from rlm2002/SSLContextImpl_PropnParams
add get/setUseCipherSuitesOrder to ParametersHelper
2 parents be1ec83 + 57f1dfe commit ca4bfe1

6 files changed

Lines changed: 191 additions & 19 deletions

File tree

native/com_wolfssl_WolfSSLSession.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5874,6 +5874,17 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_hasTicket
58745874
#endif
58755875
}
58765876

5877+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useClientSuites
5878+
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
5879+
{
5880+
(void)jcl;
5881+
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
5882+
if (jenv == NULL || ssl == NULL) {
5883+
return WOLFSSL_FAILURE;
5884+
}
5885+
return (jint)wolfSSL_UseClientSuites(ssl);
5886+
}
5887+
58775888
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_interruptBlockedIO
58785889
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
58795890
{

native/com_wolfssl_WolfSSLSession.h

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/java/com/wolfssl/WolfSSLSession.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ private native int setTlsHmacInner(long ssl, byte[] inner, long sz,
693693
private native int useSupportedCurve(long ssl, int name);
694694
private native int disableExtendedMasterSecret(long ssl);
695695
private native int hasTicket(long session);
696+
private native int useClientSuites(long ssl);
696697
private native int interruptBlockedIO(long ssl);
697698
private native int getThreadsBlockedInPoll(long ssl);
698699
private native int setMTU(long ssl, int mtu);
@@ -2476,6 +2477,26 @@ public long getTimeout() throws IllegalStateException {
24762477
}
24772478
}
24782479

2480+
/**
2481+
* Set SSL session to use Client cipher suite order preference.
2482+
* @return <code>SSL_SUCCESS</code> upon success. <code>
2483+
* SSL_FAILURE</code> upon failure.
2484+
* @throws IllegalStateException WolfSSLSession has been freed
2485+
*
2486+
*/
2487+
public int useClientSuites() throws IllegalStateException {
2488+
2489+
confirmObjectIsActive();
2490+
2491+
synchronized (sslLock) {
2492+
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
2493+
WolfSSLDebug.INFO, this.sslPtr,
2494+
() -> "entered useClientSuites()");
2495+
2496+
return useClientSuites(this.sslPtr);
2497+
}
2498+
}
2499+
24792500
/**
24802501
* Sets the cipher suite list for a given SSL session.
24812502
* The ciphers in the list should be sorted in order of preference from

src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,11 @@ private void setLocalCiphers(String[] suites)
759759
}
760760
}
761761

762+
if (this.ssl.getSide() == WolfSSL.WOLFSSL_SERVER_END &&
763+
!this.params.getUseCipherSuitesOrder()) {
764+
this.ssl.useClientSuites();
765+
}
766+
762767
} catch (IllegalStateException e) {
763768
throw new IllegalArgumentException(e);
764769
}

src/java/com/wolfssl/provider/jsse/WolfSSLParametersHelper.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class WolfSSLParametersHelper
4343
private static Method setSNIMatchers = null;
4444
private static Method getMaximumPacketSize = null;
4545
private static Method setMaximumPacketSize = null;
46+
private static Method setUseCipherSuitesOrder = null;
47+
private static Method getUseCipherSuitesOrder = null;
4648

4749
/** Default WolfSSLParametersHelper constructor */
4850
public WolfSSLParametersHelper() { }
@@ -91,6 +93,12 @@ public Object run() {
9193
case "setMaximumPacketSize":
9294
setMaximumPacketSize = m;
9395
continue;
96+
case "setUseCipherSuitesOrder":
97+
setUseCipherSuitesOrder = m;
98+
continue;
99+
case "getUseCipherSuitesOrder":
100+
getUseCipherSuitesOrder = m;
101+
continue;
94102
default:
95103
continue;
96104
}
@@ -134,7 +142,8 @@ protected static SSLParameters decoupleParams(WolfSSLParameters in) {
134142
* do not existing in older JDKs. Since older JDKs will not have them,
135143
* use Java reflection to detect availability in helper class. */
136144
if (setServerNames != null || setApplicationProtocols != null ||
137-
setEndpointIdentificationAlgorithm != null || setSNIMatchers != null) {
145+
setEndpointIdentificationAlgorithm != null ||
146+
setSNIMatchers != null || setUseCipherSuitesOrder != null) {
138147

139148
try {
140149
/* load WolfSSLJDK8Helper at runtime, not compiled
@@ -167,6 +176,11 @@ protected static SSLParameters decoupleParams(WolfSSLParameters in) {
167176
mth = cls.getDeclaredMethod("setSNIMatchers", paramList);
168177
mth.invoke(obj, ret, setSNIMatchers, in);
169178
}
179+
if (setUseCipherSuitesOrder != null) {
180+
mth = cls.getDeclaredMethod("setUseCipherSuitesOrder",
181+
paramList);
182+
mth.invoke(obj, ret, setUseCipherSuitesOrder, in);
183+
}
170184

171185
} catch (Exception e) {
172186
/* ignore, class not found */
@@ -193,15 +207,20 @@ protected static SSLParameters decoupleParams(WolfSSLParameters in) {
193207
/* Not available, just ignore and continue */
194208
}
195209

210+
try {
211+
if (setUseCipherSuitesOrder != null) {
212+
ret.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder());
213+
}
214+
} catch (Exception e) {
215+
/* Not available, just ignore and continue */
216+
}
217+
196218
/* The following SSLParameters features are not yet supported
197219
* by wolfJSSE (see Android API 23 note above). They are supported
198220
* with newer versions of SSLParameters, but will need to be added
199221
* conditionally to wolfJSSE when supported. */
200222
/*ret.setAlgorithmConstraints(in.getAlgorithmConstraints());
201223
ret.setEnableRetransmissions(in.getEnableRetransmissions());
202-
ret.setMaximumPacketSize(in.getMaximumPacketSize());
203-
ret.setSNIMatchers(in.getSNIMatchers());
204-
ret.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder());
205224
*/
206225

207226
return ret;
@@ -242,7 +261,8 @@ protected static void importParams(SSLParameters in,
242261
* do not existing in older JDKs. Since older JDKs will not have them,
243262
* use Java reflection to detect availability in helper class. */
244263
if (getServerNames != null || getApplicationProtocols != null ||
245-
getEndpointIdentificationAlgorithm != null || getSNIMatchers != null) {
264+
getEndpointIdentificationAlgorithm != null ||
265+
getSNIMatchers != null || getUseCipherSuitesOrder != null) {
246266
try {
247267
/* load WolfSSLJDK8Helper at runtime, not compiled on older JDKs */
248268
Class<?> cls = Class.forName(
@@ -267,10 +287,15 @@ protected static void importParams(SSLParameters in,
267287
"getEndpointIdentificationAlgorithm", paramList);
268288
mth.invoke(obj, in, out);
269289
}
270-
if (getSNIMatchers != null){
290+
if (getSNIMatchers != null) {
271291
mth = cls.getDeclaredMethod("getSNIMatchers", paramList);
272292
mth.invoke(obj, in, out);
273293
}
294+
if (getUseCipherSuitesOrder != null) {
295+
mth = cls.getDeclaredMethod("getUseCipherSuitesOrder",
296+
paramList);
297+
mth.invoke(obj, in, out);
298+
}
274299

275300
} catch (Exception e) {
276301
/* ignore, class not found */
@@ -296,12 +321,21 @@ protected static void importParams(SSLParameters in,
296321
* conditionally to wolfJSSE when supported. */
297322
/*out.setAlgorithmConstraints(in.getAlgorithmConstraints());
298323
out.setEnableRetransmissions(in.getEnableRetransmissions());
299-
out.setMaximumPacketSize(in.getMaximumPacketSize());
300-
out.setSNIMatchers(in.getSNIMatchers());
301-
out.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder());
302324
*/
303325

304-
out.setSNIMatchers(in.getSNIMatchers());
326+
try {
327+
out.setSNIMatchers(in.getSNIMatchers());
328+
} catch (Exception e) {
329+
/* Not available, just ignore and continue */
330+
}
331+
332+
try {
333+
if (getUseCipherSuitesOrder != null) {
334+
out.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder());
335+
}
336+
} catch (Exception e) {
337+
/* Not available, just ignore and continue */
338+
}
305339

306340
}
307341
}

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

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public static void testSetupSocketFactory() throws NoSuchProviderException,
179179
try {
180180
tf = new WolfSSLTestFactory();
181181
} catch (WolfSSLException e) {
182-
// TODO Auto-generated catch block
182+
/* TODO Auto-generated catch block */
183183
e.printStackTrace();
184184
}
185185

@@ -321,6 +321,99 @@ public void testGetSetEnabledCipherSuites()
321321
System.out.println("\t... passed");
322322
}
323323

324+
@Test
325+
public void testServerUsesClientCipherSuitePreference() throws Exception {
326+
327+
System.out.print("\tTesting client suite preference");
328+
329+
this.ctx = tf.createSSLContext("TLS", "wolfJSSE");
330+
331+
String[] serverSuites = {
332+
"TLS_AES_256_GCM_SHA384",
333+
"TLS_AES_128_GCM_SHA256"
334+
};
335+
336+
String[] clientSuites = {
337+
"TLS_AES_128_GCM_SHA256",
338+
"TLS_AES_256_GCM_SHA384"
339+
};
340+
341+
/* --- Case 1: default (server order) --- */
342+
SSLServerSocket ss1 = (SSLServerSocket)ctx.getServerSocketFactory()
343+
.createServerSocket(0);
344+
ss1.setEnabledCipherSuites(serverSuites);
345+
346+
SSLSocket cs1 = (SSLSocket)ctx.getSocketFactory().createSocket();
347+
cs1.setEnabledCipherSuites(clientSuites);
348+
cs1.connect(new InetSocketAddress(ss1.getLocalPort()));
349+
350+
final SSLSocket server1 = (SSLSocket)ss1.accept();
351+
352+
ExecutorService es = Executors.newSingleThreadExecutor();
353+
Future<Void> f1 = es.submit(() -> {
354+
server1.startHandshake();
355+
return null;
356+
});
357+
358+
cs1.startHandshake();
359+
f1.get();
360+
361+
String chosen1 = cs1.getSession().getCipherSuite();
362+
/* Note: WolfSSL may report TLS 1.3 ciphers in IANA standard or wolfSSL
363+
* alias depending on wolfSSL configuration. */
364+
if (!"TLS_AES_256_GCM_SHA384".equals(chosen1) &&
365+
!"TLS13-AES256-GCM-SHA384".equals(chosen1)) {
366+
System.out.println("\t... failed");
367+
fail("Expected server preference cipher (AES_256), got "
368+
+ chosen1);
369+
}
370+
371+
cs1.close();
372+
server1.close();
373+
ss1.close();
374+
375+
/* --- Case 2: server honors client order --- */
376+
SSLServerSocket ss2 = (SSLServerSocket)ctx.getServerSocketFactory()
377+
.createServerSocket(0);
378+
ss2.setEnabledCipherSuites(serverSuites);
379+
380+
/* Do not honor local cipher suites preference */
381+
SSLParameters ss2Params = ss2.getSSLParameters();
382+
ss2Params.setUseCipherSuitesOrder(false);
383+
ss2.setSSLParameters(ss2Params);
384+
385+
SSLSocket cs2 = (SSLSocket)ctx.getSocketFactory().createSocket();
386+
cs2.setEnabledCipherSuites(clientSuites);
387+
cs2.connect(new InetSocketAddress(ss2.getLocalPort()));
388+
389+
final SSLSocket server2 = (SSLSocket)ss2.accept();
390+
391+
Future<Void> f2 = es.submit(() -> {
392+
server2.startHandshake();
393+
return null;
394+
});
395+
396+
cs2.startHandshake();
397+
f2.get();
398+
399+
String chosen2 = cs2.getSession().getCipherSuite();
400+
/* Note: WolfSSL may report TLS 1.3 ciphers in IANA standard or wolfSSL
401+
* alias depending on wolfSSL configuration. */
402+
if (!"TLS_AES_128_GCM_SHA256".equals(chosen2) &&
403+
!"TLS13-AES128-GCM-SHA256".equals(chosen2)) {
404+
System.out.println("\t... failed");
405+
fail("Expected client preference cipher (AES_128), got "
406+
+ chosen2);
407+
}
408+
409+
cs2.close();
410+
server2.close();
411+
ss2.close();
412+
es.shutdown();
413+
414+
System.out.println("\t... passed");
415+
}
416+
324417
@Test
325418
public void testGetSupportedProtocols()
326419
throws NoSuchProviderException, NoSuchAlgorithmException {
@@ -659,7 +752,7 @@ public void testEnabledSupportedCurvesProperty() throws Exception {
659752

660753
try {
661754
client.join(1000);
662-
//server.join(1000);
755+
/* server.join(1000); */
663756

664757
} catch (InterruptedException e) {
665758
System.out.println("interrupt happened");
@@ -3402,14 +3495,14 @@ public void testAutoSNIProperty() throws Exception {
34023495
public void testSNIMatchers() throws Exception {
34033496

34043497
System.out.print("\tTesting SNI Matchers");
3405-
3498+
34063499
/* create new CTX */
34073500
this.ctx = tf.createSSLContext("TLS", ctxProvider);
3408-
3501+
34093502
/* create SSLServerSocket first to get ephemeral port */
34103503
final SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory()
34113504
.createServerSocket(0);
3412-
3505+
34133506
/* Configure SNI matcher for server*/
34143507
SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.com");
34153508
Collection<SNIMatcher> matchers = new ArrayList<>();
@@ -3436,7 +3529,7 @@ public void testSNIMatchers() throws Exception {
34363529
cs.setSSLParameters(cp);
34373530

34383531
final SSLSocket serverMatched = (SSLSocket)ss.accept();
3439-
3532+
34403533
ExecutorService es = Executors.newSingleThreadExecutor();
34413534
Future<Void> serverFuture = es.submit(new Callable<Void>() {
34423535
@Override
@@ -3451,10 +3544,10 @@ public Void call() throws Exception {
34513544
return null;
34523545
}
34533546
});
3454-
3547+
34553548
cs.startHandshake();
34563549
cs.close();
3457-
3550+
34583551
es.shutdown();
34593552
serverFuture.get();
34603553

@@ -3473,7 +3566,7 @@ public Void call() throws Exception {
34733566
cs.setSSLParameters(cp);
34743567

34753568
final SSLSocket serverUnmatched = (SSLSocket)ss.accept();
3476-
3569+
34773570
es = Executors.newSingleThreadExecutor();
34783571
serverFuture = es.submit(() -> {
34793572
try {

0 commit comments

Comments
 (0)