Skip to content

Commit 315faa5

Browse files
committed
getPeerCertificateChain returns null fix
1 parent 0e9a858 commit 315faa5

3 files changed

Lines changed: 96 additions & 4 deletions

File tree

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,11 @@ private void initHandshakeInternal(SSLSocket socket, SSLEngine engine)
13491349
else {
13501350
this.session.setSessionContext(authStore.getServerContext());
13511351
this.session.setSide(WolfSSL.WOLFSSL_SERVER_END);
1352+
/* Track client auth state for getPeerCertificates() */
1353+
boolean clientAuthRequested =
1354+
this.params.getNeedClientAuth() ||
1355+
this.params.getWantClientAuth();
1356+
this.session.setClientAuthRequested(clientAuthRequested);
13521357
}
13531358

13541359
if (this.sessionCreation == false && !this.session.isFromTable) {

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

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession {
7373
byte[] pseudoSessionID = null; /* used with TLS 1.3*/
7474
private int side = 0;
7575

76+
/* Track if client auth was requested, for getPeerCertificates() behavior */
77+
private volatile boolean clientAuthRequested = false;
78+
7679
/* Cache peer certificates after received. Applications assume that
7780
* SSLSocket.getSession().getPeerCertificates() will return the peer
7881
* certificate even on a resumed connection where the cert has not been
@@ -260,6 +263,7 @@ public WolfSSLImplementSSLSession (WolfSSLImplementSSLSession orig) {
260263
this.pseudoSessionID = orig.pseudoSessionID.clone();
261264
}
262265
this.side = orig.side;
266+
this.clientAuthRequested = orig.clientAuthRequested;
263267
if (orig.peerCerts != null) {
264268
this.peerCerts = orig.peerCerts.clone();
265269
}
@@ -519,6 +523,15 @@ public synchronized Certificate[] getPeerCertificates()
519523
"SSLSocket/Engine closed");
520524
}
521525

526+
/* Throw if server side with no client auth requested */
527+
if (this.side == WolfSSL.WOLFSSL_SERVER_END &&
528+
!this.clientAuthRequested) {
529+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
530+
() -> "Server side, no client auth, throwing exception");
531+
throw new SSLPeerUnverifiedException(
532+
"peer not authenticated (no client auth requested)");
533+
}
534+
522535
try {
523536
x509 = this.ssl.getPeerCertificate();
524537
} catch (IllegalStateException | WolfSSLJNIException ex) {
@@ -605,8 +618,8 @@ public Certificate[] getLocalCertificates() {
605618
}
606619

607620
@Override
608-
public synchronized javax.security.cert.X509Certificate[] getPeerCertificateChain()
609-
throws SSLPeerUnverifiedException {
621+
public synchronized javax.security.cert.X509Certificate[]
622+
getPeerCertificateChain() throws SSLPeerUnverifiedException {
610623

611624
long peerX509 = 0;
612625
WolfSSLX509X x509;
@@ -615,10 +628,17 @@ public synchronized javax.security.cert.X509Certificate[] getPeerCertificateChai
615628
throw new SSLPeerUnverifiedException("handshake not done");
616629
}
617630

631+
/* Throw if server side with no client auth requested */
632+
if (this.side == WolfSSL.WOLFSSL_SERVER_END &&
633+
!this.clientAuthRequested) {
634+
throw new SSLPeerUnverifiedException(
635+
"peer not authenticated (no client auth requested)");
636+
}
637+
618638
try {
619639
peerX509 = this.ssl.getPeerCertificate();
620640
if (peerX509 == 0) {
621-
return null;
641+
throw new SSLPeerUnverifiedException("No peer certificate");
622642
}
623643

624644
/* wolfSSL starting with 5.3.0 returns a new WOLFSSL_X509
@@ -657,10 +677,17 @@ public synchronized Principal getPeerPrincipal()
657677
throw new SSLPeerUnverifiedException("handshake not done");
658678
}
659679

680+
/* Throw if server side with no client auth requested */
681+
if (this.side == WolfSSL.WOLFSSL_SERVER_END &&
682+
!this.clientAuthRequested) {
683+
throw new SSLPeerUnverifiedException(
684+
"peer not authenticated (no client auth requested)");
685+
}
686+
660687
try {
661688
peerX509 = this.ssl.getPeerCertificate();
662689
if (peerX509 == 0) {
663-
return null;
690+
throw new SSLPeerUnverifiedException("No peer certificate");
664691
}
665692

666693
/* wolfSSL starting with 5.3.0 returns a new WOLFSSL_X509
@@ -1039,6 +1066,16 @@ protected int getSide() {
10391066
return this.side;
10401067
}
10411068

1069+
/**
1070+
* Set whether client auth was requested.
1071+
* Used for getPeerCertificates() behavior.
1072+
*
1073+
* @param requested true if client auth was requested, false otherwise
1074+
*/
1075+
protected void setClientAuthRequested(boolean requested) {
1076+
this.clientAuthRequested = requested;
1077+
}
1078+
10421079
/**
10431080
* Return the side session is on (server/client) as a String
10441081
* @return "client" or "server" representing the side of this session

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import javax.net.ssl.SSLEngineResult;
5555
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
5656
import javax.net.ssl.SSLException;
57+
import javax.net.ssl.SSLPeerUnverifiedException;
5758
import java.util.concurrent.TimeUnit;
5859
import java.util.concurrent.Executors;
5960
import java.util.concurrent.ExecutorService;
@@ -2494,5 +2495,54 @@ private ByteBuffer enlargeBuffer(ByteBuffer buffer, int size) {
24942495
bb.put(buffer);
24952496
return bb;
24962497
}
2498+
2499+
/**
2500+
* Verify getPeerCertificateChain() throws SSLPeerUnverifiedException
2501+
* when no client auth requested, matching SunJSSE/Netty expectations.
2502+
*/
2503+
@Test
2504+
public void testGetPeerCertificateChainNoClientAuth() throws Exception {
2505+
2506+
System.out.print("\tgetPeerCertChain no client auth");
2507+
2508+
String protocol = null;
2509+
for (String p : enabledProtocols) {
2510+
if (!p.equals("TLS") && !p.contains("DTLS")) {
2511+
protocol = p;
2512+
break;
2513+
}
2514+
}
2515+
2516+
if (protocol == null) {
2517+
pass("\t... skipped");
2518+
return;
2519+
}
2520+
2521+
SSLContext ctx = tf.createSSLContext(protocol, engineProvider);
2522+
2523+
SSLEngine server = ctx.createSSLEngine();
2524+
SSLEngine client = ctx.createSSLEngine("localhost", 11111);
2525+
2526+
server.setUseClientMode(false);
2527+
server.setNeedClientAuth(false);
2528+
server.setWantClientAuth(false);
2529+
client.setUseClientMode(true);
2530+
2531+
tf.testConnection(server, client, null, null, "No client auth test");
2532+
2533+
SSLSession serverSession = server.getSession();
2534+
2535+
try {
2536+
javax.security.cert.X509Certificate[] certs =
2537+
serverSession.getPeerCertificateChain();
2538+
error("\t... failed");
2539+
fail("Expected SSLPeerUnverifiedException, got " +
2540+
(certs == null ? "null" : "certs"));
2541+
} catch (SSLPeerUnverifiedException e) {
2542+
/* Expected */
2543+
}
2544+
2545+
pass("\t... passed");
2546+
}
24972547
}
24982548

0 commit comments

Comments
 (0)