WolfSSLSocket: check if Socket closed before TLS shutdown

pull/56/head
Chris Conlon 2020-10-14 13:53:20 -07:00
parent f1020fa8fa
commit 518e3b39dd
2 changed files with 73 additions and 0 deletions

View File

@ -932,6 +932,17 @@ public class WolfSSLSocket extends SSLSocket {
"entered close()");
try {
/* Check if underlying Socket is still open before closing,
* in case application calls SSLSocket.close() multiple times */
synchronized (handshakeLock) {
if (this.connectionClosed == true || super.isClosed()) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"Socket already closed, skipping TLS shutdown");
return;
}
}
if (ssl != null) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"shutting down SSL/TLS connection");

View File

@ -1390,6 +1390,68 @@ public class WolfSSLSocketTest {
System.out.println("\t... passed");
}
@Test
public void testDoubleSocketClose() throws Exception {
String protocol = null;
System.out.print("\tTesting duplicate close");
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\t... skipped");
return;
}
/* create new CTX */
this.ctx = tf.createSSLContext(protocol, ctxProvider);
/* 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();
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Void> serverFuture = es.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
server.startHandshake();
} catch (SSLException e) {
System.out.println("\t\t... failed");
fail();
}
return null;
}
});
try {
cs.startHandshake();
} catch (SSLHandshakeException e) {
System.out.println("\t\t... failed");
fail();
}
es.shutdown();
serverFuture.get();
cs.close();
server.close();
ss.close();
cs.close();
System.out.println("\t\t... passed");
}
protected class TestServer extends Thread
{
private SSLContext ctx;