JSSE: add SSLSocket.getSession() tests throughout different times of connection establishment
parent
ed3db7a92c
commit
f164e6465d
|
@ -326,7 +326,7 @@ public class WolfSSLAuthStore {
|
|||
|
||||
/* 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,
|
||||
|
@ -527,18 +527,22 @@ public class WolfSSLAuthStore {
|
|||
}
|
||||
|
||||
/** 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;
|
||||
|
|
|
@ -1262,6 +1262,7 @@ public class WolfSSLEngineHelper {
|
|||
int ret, err;
|
||||
byte[] serverId = null;
|
||||
String hostAddress = null;
|
||||
String sessCacheHostname = this.hostname;
|
||||
|
||||
if (!modeSet) {
|
||||
throw new SSLException("setUseClientMode has not been called");
|
||||
|
@ -1293,7 +1294,13 @@ public class WolfSSLEngineHelper {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -147,12 +147,14 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession
|
|||
*
|
||||
* @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.host = host;
|
||||
this.authStore = params;
|
||||
this.valid = false; /* flag if joining or resuming session is allowed */
|
||||
this.peerCerts = null;
|
||||
|
@ -163,6 +165,12 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession
|
|||
creation = new Date();
|
||||
accessed = new Date();
|
||||
|
||||
if (port > 0) {
|
||||
this.port = port;
|
||||
} else {
|
||||
this.port = -1;
|
||||
}
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"created new session (no host/port yet)");
|
||||
}
|
||||
|
@ -478,7 +486,9 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession
|
|||
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 {
|
||||
|
|
|
@ -24,6 +24,13 @@ package com.wolfssl.provider.jsse.test;
|
|||
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;
|
||||
|
@ -38,20 +45,25 @@ import java.security.UnrecoverableKeyException;
|
|||
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;
|
||||
|
@ -63,7 +75,7 @@ public class WolfSSLSessionTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void testProviderInstallationAtRuntime()
|
||||
throws NoSuchProviderException {
|
||||
throws NoSuchProviderException, WolfSSLException {
|
||||
|
||||
System.out.println("WolfSSLImplementSSLSession Class");
|
||||
|
||||
|
@ -73,12 +85,8 @@ public class WolfSSLSessionTest {
|
|||
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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -435,6 +443,162 @@ public class WolfSSLSessionTest {
|
|||
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);
|
||||
|
|
|
@ -41,6 +41,8 @@ import java.util.concurrent.ExecutorService;
|
|||
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;
|
||||
|
@ -991,6 +993,11 @@ public class WolfSSLSessionTest {
|
|||
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
|
||||
|
@ -1063,6 +1070,8 @@ public class WolfSSLSessionTest {
|
|||
if (server != null) {
|
||||
server.close();
|
||||
}
|
||||
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -1129,6 +1138,10 @@ public class WolfSSLSessionTest {
|
|||
}
|
||||
|
||||
} 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", "");
|
||||
|
|
Loading…
Reference in New Issue