Skip to content

Commit 5876be8

Browse files
committed
Netty FIPS fixes for cross-signed certs, empty protocol array, SNI caching
1 parent 249a622 commit 5876be8

7 files changed

Lines changed: 77 additions & 18 deletions

File tree

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ public class WolfSSLEngine extends SSLEngine {
101101
private int lastSSLConnectRet = WolfSSL.SSL_FAILURE;
102102
private int lastSSLAcceptRet = WolfSSL.SSL_FAILURE;
103103

104+
/* SNI mismatch detected during handshake */
105+
private boolean sniMismatch = false;
106+
104107
/* closeNotify status when shutting down */
105108
private boolean closeNotifySent = false;
106109
private boolean closeNotifyReceived = false;
@@ -1036,6 +1039,11 @@ else if (produced == 0) {
10361039
() -> "==================================================");
10371040
}
10381041

1042+
if (this.sniMismatch) {
1043+
throw new SSLHandshakeException(
1044+
"Unrecognized Server Name");
1045+
}
1046+
10391047
return new SSLEngineResult(status, hs, consumed, produced);
10401048

10411049
} finally {
@@ -1333,6 +1341,13 @@ public synchronized SSLEngineResult unwrap(ByteBuffer in, ByteBuffer[] out,
13331341
inRemaining = in.remaining();
13341342
}
13351343

1344+
/* Cache SNI from ClientHello before native handshake consumes
1345+
* the data. The read callback advances netData position, so
1346+
* SNI must be parsed here while the buffer is still intact. */
1347+
if (!this.handshakeFinished) {
1348+
cacheRequestedServerNamesFromNetData();
1349+
}
1350+
13361351
if (extraDebugEnabled) {
13371352
final SSLEngineResult.Status tmpStatus = status;
13381353
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
@@ -1816,6 +1831,11 @@ else if (!this.handshakeFinished && (ret == 0) &&
18161831
() -> "==================================================");
18171832
}
18181833

1834+
if (this.sniMismatch) {
1835+
throw new SSLHandshakeException(
1836+
"Unrecognized Server Name");
1837+
}
1838+
18191839
return new SSLEngineResult(status, hs, consumed, produced);
18201840

18211841
} catch (SSLException | RuntimeException e) {
@@ -1918,6 +1938,10 @@ else if (this.closeNotifyReceived == true &&
19181938
(this.nativeWantsToWrite == 0) &&
19191939
(this.nativeWantsToRead == 0)) {
19201940

1941+
if (!this.getUseClientMode() &&
1942+
!this.engineHelper.matchSNI()) {
1943+
this.sniMismatch = true;
1944+
}
19211945
this.handshakeFinished = true;
19221946
hs = SSLEngineResult.HandshakeStatus.FINISHED;
19231947
this.engineHelper.getSession().updateStoredSessionValues();

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,8 @@ protected synchronized void setCiphers(String[] suites)
564564
*
565565
* @param p String array of SSL/TLS protocols to be enabled
566566
*
567-
* @throws IllegalArgumentException if input array is null,
568-
* has length zero, or contains invalid/unsupported protocols
567+
* @throws IllegalArgumentException if input array is null or
568+
* contains invalid/unsupported protocols
569569
*/
570570
protected synchronized void setProtocols(String[] p)
571571
throws IllegalArgumentException {
@@ -575,7 +575,9 @@ protected synchronized void setProtocols(String[] p)
575575
}
576576

577577
if (p.length == 0) {
578-
throw new IllegalArgumentException("input array has length zero");
578+
/* Empty array is valid, store empty set */
579+
this.params.setProtocols(new String[0]);
580+
return;
579581
}
580582

581583
/* sanitize protocol array for unsupported strings */

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,10 @@ public String[] getLocalSupportedSignatureAlgorithms() {
11181118

11191119
@Override
11201120
public String[] getPeerSupportedSignatureAlgorithms() {
1121-
/* TODO */
1122-
return null;
1121+
/* TODO: Wire to native wolfSSL_get_peer_sigalgs() once
1122+
* available. Returns String[0] not null because JSSE
1123+
* callers iterate the result directly. Null causes NPE. */
1124+
return new String[0];
11231125
}
11241126

11251127
/**

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ synchronized public void setEnabledProtocols(String[] protocols)
235235
}
236236

237237
if (protocols.length == 0) {
238-
throw new IllegalArgumentException("input array has length zero");
238+
/* Empty array is valid, store empty set */
239+
params.setProtocols(new String[0]);
240+
return;
239241
}
240242

241243
/* sanitize protocol array for unsupported strings */

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,10 +573,33 @@ private List<X509Certificate> certManagerVerify(
573573
ret = cm.CertManagerVerifyBuffer(peer, peer.length,
574574
WolfSSL.SSL_FILETYPE_ASN1);
575575
if (ret != WolfSSL.SSL_SUCCESS) {
576-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
577-
() -> "Failed to verify peer certificate");
578-
cm.free();
579-
throw new CertificateException("Failed to verify peer certificate");
576+
/* Native CA lookup by subject hash may return wrong issuer
577+
* for cross-signed certs. Find correct one by signature,
578+
* reload it, and retry. */
579+
X509Certificate issuer = findIssuerBySignature(
580+
sortedCerts[0], this.store);
581+
if (issuer != null) {
582+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
583+
() -> "Found issuer by signature for peer: " +
584+
sortedCerts[0].getSubjectX500Principal().getName());
585+
try {
586+
cm.CertManagerUnloadCAs();
587+
byte[] issuerEnc = issuer.getEncoded();
588+
cm.CertManagerLoadCABuffer(issuerEnc,
589+
issuerEnc.length, WolfSSL.SSL_FILETYPE_ASN1);
590+
} catch (Exception e) {
591+
/* Fall through to failure below */
592+
}
593+
ret = cm.CertManagerVerifyBuffer(peer, peer.length,
594+
WolfSSL.SSL_FILETYPE_ASN1);
595+
}
596+
if (ret != WolfSSL.SSL_SUCCESS) {
597+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
598+
() -> "Failed to verify peer certificate");
599+
cm.free();
600+
throw new CertificateException(
601+
"Failed to verify peer certificate");
602+
}
580603
}
581604

582605
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,16 +413,19 @@ public void testGetSetEnabledProtocols()
413413
/* expected */
414414
}
415415

416-
/* test failure, empty string */
416+
String[] savedProtos = s.getEnabledProtocols();
417+
418+
/* test empty array accepted */
417419
try {
418420
String[] empty = {};
419421
s.setEnabledProtocols(empty);
420-
System.out.println("\t... failed");
421-
fail("setEnabledProtocols() failed");
422422
} catch (IllegalArgumentException e) {
423-
/* expected */
423+
System.out.println("\t... failed");
424+
fail("setEnabledProtocols() should accept empty");
424425
}
425426

427+
s.setEnabledProtocols(savedProtos);
428+
426429
/* test failure, bad value */
427430
try {
428431
String[] badvalue = { "badvalue" };

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,16 +474,19 @@ public void testGetSetEnabledProtocols()
474474
/* expected */
475475
}
476476

477-
/* test failure, empty string */
477+
String[] savedProtos = s.getEnabledProtocols();
478+
479+
/* test empty array accepted */
478480
try {
479481
String[] empty = {};
480482
s.setEnabledProtocols(empty);
481-
System.out.println("\t\t... failed");
482-
fail("SSLSocket.setEnabledProtocols() failed");
483483
} catch (IllegalArgumentException e) {
484-
/* expected */
484+
System.out.println("\t\t... failed");
485+
fail("SSLSocket.setEnabledProtocols() should accept empty");
485486
}
486487

488+
s.setEnabledProtocols(savedProtos);
489+
487490
/* test failure, bad value */
488491
try {
489492
String[] badvalue = { "badvalue" };

0 commit comments

Comments
 (0)