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 */
|
/* Return new session if in server mode, or if host is null */
|
||||||
if (!clientMode || host == null) {
|
if (!clientMode || host == null) {
|
||||||
return this.getSession(ssl, clientMode);
|
return this.getSession(ssl, clientMode, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
@ -527,18 +527,22 @@ public class WolfSSLAuthStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a new session, does not check/save for resumption
|
/** Returns a new session, does not check/save for resumption
|
||||||
|
*
|
||||||
* @param ssl WOLFSSL class to reference with new session
|
* @param ssl WOLFSSL class to reference with new session
|
||||||
* @param clientMode true if on client side, false if server
|
* @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
|
* @return a new SSLSession on success
|
||||||
*/
|
*/
|
||||||
protected synchronized WolfSSLImplementSSLSession getSession(
|
protected synchronized WolfSSLImplementSSLSession getSession(
|
||||||
WolfSSLSession ssl, boolean clientMode) {
|
WolfSSLSession ssl, boolean clientMode, String host, int port) {
|
||||||
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"creating new session");
|
"creating new session");
|
||||||
|
|
||||||
WolfSSLImplementSSLSession ses =
|
WolfSSLImplementSSLSession ses =
|
||||||
new WolfSSLImplementSSLSession(ssl, this);
|
new WolfSSLImplementSSLSession(ssl, this, host, port);
|
||||||
|
|
||||||
ses.setValid(true);
|
ses.setValid(true);
|
||||||
ses.isFromTable = false;
|
ses.isFromTable = false;
|
||||||
|
|
|
@ -1262,6 +1262,7 @@ public class WolfSSLEngineHelper {
|
||||||
int ret, err;
|
int ret, err;
|
||||||
byte[] serverId = null;
|
byte[] serverId = null;
|
||||||
String hostAddress = null;
|
String hostAddress = null;
|
||||||
|
String sessCacheHostname = this.hostname;
|
||||||
|
|
||||||
if (!modeSet) {
|
if (!modeSet) {
|
||||||
throw new SSLException("setUseClientMode has not been called");
|
throw new SSLException("setUseClientMode has not been called");
|
||||||
|
@ -1293,7 +1294,13 @@ public class WolfSSLEngineHelper {
|
||||||
|
|
||||||
return WolfSSL.SSL_HANDSHAKE_FAILURE;
|
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) {
|
if (this.clientMode) {
|
||||||
|
|
|
@ -147,12 +147,14 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession
|
||||||
*
|
*
|
||||||
* @param in WolfSSLSession to be used with this object
|
* @param in WolfSSLSession to be used with this object
|
||||||
* @param params WolfSSLAuthStore for this session
|
* @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,
|
public WolfSSLImplementSSLSession (WolfSSLSession in,
|
||||||
WolfSSLAuthStore params) {
|
WolfSSLAuthStore params,
|
||||||
|
String host, int port) {
|
||||||
this.ssl = in;
|
this.ssl = in;
|
||||||
this.port = -1;
|
this.host = host;
|
||||||
this.host = null;
|
|
||||||
this.authStore = params;
|
this.authStore = params;
|
||||||
this.valid = false; /* flag if joining or resuming session is allowed */
|
this.valid = false; /* flag if joining or resuming session is allowed */
|
||||||
this.peerCerts = null;
|
this.peerCerts = null;
|
||||||
|
@ -163,6 +165,12 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession
|
||||||
creation = new Date();
|
creation = new Date();
|
||||||
accessed = new Date();
|
accessed = new Date();
|
||||||
|
|
||||||
|
if (port > 0) {
|
||||||
|
this.port = port;
|
||||||
|
} else {
|
||||||
|
this.port = -1;
|
||||||
|
}
|
||||||
|
|
||||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
"created new session (no host/port yet)");
|
"created new session (no host/port yet)");
|
||||||
}
|
}
|
||||||
|
@ -478,7 +486,9 @@ public class WolfSSLImplementSSLSession extends ExtendedSSLSession
|
||||||
X509Certificate exportCert;
|
X509Certificate exportCert;
|
||||||
|
|
||||||
if (ssl == null) {
|
if (ssl == null) {
|
||||||
throw new SSLPeerUnverifiedException("handshake not complete");
|
throw new SSLPeerUnverifiedException(
|
||||||
|
"internal WolfSSLSession null, handshake not complete or " +
|
||||||
|
"SSLSocket/Engine closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -24,6 +24,13 @@ package com.wolfssl.provider.jsse.test;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.fail;
|
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.io.IOException;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
@ -38,20 +45,25 @@ import java.security.UnrecoverableKeyException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLSocket;
|
||||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
import javax.net.ssl.SSLServerSocket;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.SSLSessionBindingEvent;
|
import javax.net.ssl.SSLSessionBindingEvent;
|
||||||
import javax.net.ssl.SSLSessionBindingListener;
|
import javax.net.ssl.SSLSessionBindingListener;
|
||||||
import javax.net.ssl.SSLSessionContext;
|
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.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import com.wolfssl.WolfSSL;
|
||||||
import com.wolfssl.WolfSSLContext;
|
import com.wolfssl.WolfSSLContext;
|
||||||
import com.wolfssl.WolfSSLException;
|
import com.wolfssl.WolfSSLException;
|
||||||
import com.wolfssl.provider.jsse.WolfSSLProvider;
|
import com.wolfssl.provider.jsse.WolfSSLProvider;
|
||||||
|
@ -63,7 +75,7 @@ public class WolfSSLSessionTest {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void testProviderInstallationAtRuntime()
|
public static void testProviderInstallationAtRuntime()
|
||||||
throws NoSuchProviderException {
|
throws NoSuchProviderException, WolfSSLException {
|
||||||
|
|
||||||
System.out.println("WolfSSLImplementSSLSession Class");
|
System.out.println("WolfSSLImplementSSLSession Class");
|
||||||
|
|
||||||
|
@ -73,12 +85,8 @@ public class WolfSSLSessionTest {
|
||||||
Provider p = Security.getProvider("wolfJSSE");
|
Provider p = Security.getProvider("wolfJSSE");
|
||||||
assertNotNull(p);
|
assertNotNull(p);
|
||||||
|
|
||||||
try {
|
/* Can throw WolfSSLException on error */
|
||||||
tf = new WolfSSLTestFactory();
|
tf = new WolfSSLTestFactory();
|
||||||
} catch (WolfSSLException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,6 +443,162 @@ public class WolfSSLSessionTest {
|
||||||
pass("\t\t... passed");
|
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) {
|
private void pass(String msg) {
|
||||||
WolfSSLTestFactory.pass(msg);
|
WolfSSLTestFactory.pass(msg);
|
||||||
|
|
|
@ -41,6 +41,8 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
import com.wolfssl.WolfSSL;
|
import com.wolfssl.WolfSSL;
|
||||||
import com.wolfssl.WolfSSLDebug;
|
import com.wolfssl.WolfSSLDebug;
|
||||||
|
@ -991,6 +993,11 @@ public class WolfSSLSessionTest {
|
||||||
final WolfSSLContext srvCtx;
|
final WolfSSLContext srvCtx;
|
||||||
WolfSSLContext cliCtx;
|
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");
|
System.out.print("\tTesting wolfssljni.debug");
|
||||||
|
|
||||||
/* Save original property value, then enable debug. Make sure
|
/* Save original property value, then enable debug. Make sure
|
||||||
|
@ -1063,6 +1070,8 @@ public class WolfSSLSessionTest {
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
server.close();
|
server.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1129,6 +1138,10 @@ public class WolfSSLSessionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
|
/* Wait for server to finish processing */
|
||||||
|
latch.await(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
/* Restore original property value */
|
/* Restore original property value */
|
||||||
if (originalProp == null || originalProp.isEmpty()) {
|
if (originalProp == null || originalProp.isEmpty()) {
|
||||||
System.setProperty("wolfssljni.debug", "");
|
System.setProperty("wolfssljni.debug", "");
|
||||||
|
|
Loading…
Reference in New Issue