Skip to content

Commit

Permalink
JSSE: add SSLSocket.getSession() tests throughout different times of …
Browse files Browse the repository at this point in the history
…connection establishment
  • Loading branch information
cconlon committed Nov 25, 2024
1 parent ed3db7a commit eeaa1c4
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 17 deletions.
10 changes: 7 additions & 3 deletions src/java/com/wolfssl/provider/jsse/WolfSSLAuthStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ protected synchronized WolfSSLImplementSSLSession getSession(

/* Return new session if in server mode, or if host is null */
if (!clientMode || host == null) {
return this.getSession(ssl, clientMode);
return this.getSession(ssl, clientMode, host, port);
}

WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
Expand Down Expand Up @@ -527,18 +527,22 @@ private void printSessionStoreStatus() {
}

/** Returns a new session, does not check/save for resumption
*
* @param ssl WOLFSSL class to reference with new session
* @param clientMode true if on client side, false if server
* @param host hostname of peer, or null if not available
* @param port port of peer
*
* @return a new SSLSession on success
*/
protected synchronized WolfSSLImplementSSLSession getSession(
WolfSSLSession ssl, boolean clientMode) {
WolfSSLSession ssl, boolean clientMode, String host, int port) {

WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"creating new session");

WolfSSLImplementSSLSession ses =
new WolfSSLImplementSSLSession(ssl, this);
new WolfSSLImplementSSLSession(ssl, this, host, port);

ses.setValid(true);
ses.isFromTable = false;
Expand Down
9 changes: 8 additions & 1 deletion src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ protected synchronized int doHandshake(int isSSLEngine, int timeout)
int ret, err;
byte[] serverId = null;
String hostAddress = null;
String sessCacheHostname = this.hostname;

if (!modeSet) {
throw new SSLException("setUseClientMode has not been called");
Expand Down Expand Up @@ -1293,7 +1294,13 @@ protected synchronized int doHandshake(int isSSLEngine, int timeout)

return WolfSSL.SSL_HANDSHAKE_FAILURE;
}
this.session = this.authStore.getSession(ssl, this.clientMode);

if (sessCacheHostname == null && this.peerAddr != null) {
sessCacheHostname = this.peerAddr.getHostAddress();
}

this.session = this.authStore.getSession(ssl, this.clientMode,
sessCacheHostname, this.port);
}

if (this.clientMode) {
Expand Down
23 changes: 19 additions & 4 deletions src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,13 @@ public WolfSSLImplementSSLSession (WolfSSLSession in, int port, String host,
*
* @param in WolfSSLSession to be used with this object
* @param params WolfSSLAuthStore for this session
* @param host hostname of peer, or null if not available
* @param port port of peer
*/
public WolfSSLImplementSSLSession (WolfSSLSession in,
WolfSSLAuthStore params) {
WolfSSLAuthStore params,
String host, int port) {
this.ssl = in;
this.port = -1;
this.host = null;
this.authStore = params;
this.valid = false; /* flag if joining or resuming session is allowed */
this.peerCerts = null;
Expand All @@ -163,6 +164,18 @@ public WolfSSLImplementSSLSession (WolfSSLSession in,
creation = new Date();
accessed = new Date();

if (host != null) {
this.host = host;
} else {
this.host = null;
}

if (port > 0) {
this.port = port;
} else {
this.port = -1;
}

WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"created new session (no host/port yet)");
}
Expand Down Expand Up @@ -478,7 +491,9 @@ public synchronized Certificate[] getPeerCertificates()
X509Certificate exportCert;

if (ssl == null) {
throw new SSLPeerUnverifiedException("handshake not complete");
throw new SSLPeerUnverifiedException(
"internal WolfSSLSession null, handshake not complete or " +
"SSLSocket/Engine closed");
}

try {
Expand Down
182 changes: 173 additions & 9 deletions src/test/com/wolfssl/provider/jsse/test/WolfSSLSessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
Expand All @@ -38,20 +45,25 @@
import java.security.cert.CertificateException;
import java.util.ArrayList;

import java.net.InetSocketAddress;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionBindingEvent;
import javax.net.ssl.SSLSessionBindingListener;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLHandshakeException;

import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLContext;
import com.wolfssl.WolfSSLException;
import com.wolfssl.provider.jsse.WolfSSLProvider;
Expand All @@ -63,7 +75,7 @@ public class WolfSSLSessionTest {

@BeforeClass
public static void testProviderInstallationAtRuntime()
throws NoSuchProviderException {
throws NoSuchProviderException, WolfSSLException {

System.out.println("WolfSSLImplementSSLSession Class");

Expand All @@ -73,12 +85,8 @@ public static void testProviderInstallationAtRuntime()
Provider p = Security.getProvider("wolfJSSE");
assertNotNull(p);

try {
tf = new WolfSSLTestFactory();
} catch (WolfSSLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* Can throw WolfSSLException on error */
tf = new WolfSSLTestFactory();
}


Expand Down Expand Up @@ -435,6 +443,162 @@ public void testSessionContext()
pass("\t\t... passed");
}

@Test
public void testGetSessionInSocketConnection() throws Exception {

String protocol = null;
SSLContext ctx = null;

System.out.print("\tTesting SSLSocket.getSession");

if (WolfSSL.TLSv12Enabled()) {
protocol = "TLSv1.2";
} else if (WolfSSL.TLSv11Enabled()) {
protocol = "TLSv1.1";
} else if (WolfSSL.TLSv1Enabled()) {
protocol = "TLSv1.0";
} else {
System.out.println("\t... skipped");
return;
}

/* create new CTX */
ctx = tf.createSSLContext(protocol, engineProvider);

/* create SSLServerSocket first to get ephemeral port */
SSLServerSocket ss = (SSLServerSocket)ctx.getServerSocketFactory()
.createServerSocket(0);

SSLSocket cs = (SSLSocket)ctx.getSocketFactory().createSocket();
cs.connect(new InetSocketAddress(ss.getLocalPort()));
final SSLSocket server = (SSLSocket)ss.accept();
server.setNeedClientAuth(true);

ExecutorService es = Executors.newSingleThreadExecutor();
Future<Void> serverFuture = es.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
testSSLSession(server, false);
server.startHandshake();
testSSLSession(server, true);

} catch (SSLException e) {
error("\t... failed");
fail();
}
return null;
}
});

try {
testSSLSession(cs, false);
cs.startHandshake();
testSSLSession(cs, true);

} catch (SSLHandshakeException e) {
error("\t... failed");
fail();
}

es.shutdown();
serverFuture.get();
testSSLSession(cs, true);
cs.close();
testSSLSession(cs, true);
testSSLSession(server, true);
server.close();
testSSLSession(server, true);
ss.close();

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

/**
* Test SSLSocket.getSession() and calling methods on the
* SSLSession retrieved. */
private void testSSLSession(SSLSocket sock, boolean handshakeDone)
throws Exception {

int ret;
String val;
Certificate[] certs;
byte[] id;
SSLSession session;

if (sock == null) {
throw new Exception("SSLSocket was null in testSSLSession");
}

session = sock.getSession();
if (session == null) {
throw new Exception("SSLSocket.getSession() returned null");
}

val = session.getCipherSuite();
if (val == null || val.isEmpty()) {
throw new Exception(
"SSLSession.getCipherSuite() was null or empty");
}

val = session.getProtocol();
if (val == null || val.isEmpty()) {
throw new Exception(
"SSLSession.getProtocol() was null or empty");
}

val = session.getPeerHost();
if (handshakeDone && !sock.isClosed() &&
(val == null || val.isEmpty())) {
throw new Exception(
"SSLSession.getPeerHost() was null or empty");
}

ret = session.getPeerPort();
if (ret == 0) {
throw new Exception("SSLSession.getPeerPort() was 0");
}

certs = session.getLocalCertificates();
if (certs == null || certs.length == 0) {
throw new Exception(
"SSLSession.getLocalCertificates() was null or 0 length");
}

try {
certs = session.getPeerCertificates();
if (handshakeDone && (certs == null || certs.length == 0)) {
throw new Exception(
"SSLSession.getPeerCertificates was null or 0 length");
}
} catch (SSLPeerUnverifiedException e) {
if (handshakeDone && !sock.isClosed()) {
throw new Exception(
"SSLSession.getPeerCertificates threw " +
"SSLPeerUnverifiedException when handshake was done: " + e);
}
}

id = session.getId();
if (!sock.isClosed() && (id == null || id.length == 0)) {
throw new Exception("SSLSession.getId() was null or 0 length");
}

if (!sock.isClosed() && !session.isValid()) {
throw new Exception("SSLSession.isValid() is false");
}

ret = session.getPacketBufferSize();
if (ret == 0) {
throw new Exception("SSLSession.getPacketBufferSize() is 0");
}

ret = session.getApplicationBufferSize();
if (ret == 0) {
throw new Exception("SSLSession.getApplicationBufferSize() is 0");
}
}


private void pass(String msg) {
WolfSSLTestFactory.pass(msg);
Expand Down
13 changes: 13 additions & 0 deletions src/test/com/wolfssl/test/WolfSSLSessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.CountDownLatch;

import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLDebug;
Expand Down Expand Up @@ -991,6 +993,11 @@ public void test_WolfSSLSession_connectionWithDebug() throws Exception {
final WolfSSLContext srvCtx;
WolfSSLContext cliCtx;

/* Latch used to wait for server to finish handshake before
* test shuts down. Otherwise, we will sometimes miss debug
* messages from the server side. */
final CountDownLatch latch = new CountDownLatch(1);

System.out.print("\tTesting wolfssljni.debug");

/* Save original property value, then enable debug. Make sure
Expand Down Expand Up @@ -1063,6 +1070,8 @@ public Void call() throws Exception {
if (server != null) {
server.close();
}

latch.countDown();
}

return null;
Expand Down Expand Up @@ -1129,6 +1138,10 @@ public Void call() throws Exception {
}

} finally {

/* Wait for server to finish processing */
latch.await(10, TimeUnit.SECONDS);

/* Restore original property value */
if (originalProp == null || originalProp.isEmpty()) {
System.setProperty("wolfssljni.debug", "");
Expand Down

0 comments on commit eeaa1c4

Please sign in to comment.