package org.webpieces.ssl.api; import java.io.IOException; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.List; import javax.net.ssl.SSLEngine; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.webpieces.data.api.BufferCreationPool; import org.webpieces.data.api.BufferPool; public class TestSSLEngineClose { private AsyncSSLEngine clientEngine; private AsyncSSLEngine svrEngine; private MockSslListener clientListener = new MockSslListener(); private MockSslListener svrListener = new MockSslListener(); @Before public void setup() throws GeneralSecurityException, IOException { MockSSLEngineFactory sslEngineFactory = new MockSSLEngineFactory(); BufferPool pool = new BufferCreationPool(false, 17000, 1000); SSLEngine client = sslEngineFactory.createEngineForSocket(); SSLEngine svr = sslEngineFactory.createEngineForServerSocket(); clientEngine = AsyncSSLFactory.create("client", client, pool, clientListener); svrEngine = AsyncSSLFactory.create("svr", svr, pool, svrListener); clientEngine.beginHandshake(); ByteBuffer buffer = clientListener.getToSendToSocket().get(0); svrEngine.feedEncryptedPacket(buffer); svrListener.getRunnable().run(); ByteBuffer buf = svrListener.getToSendToSocket().get(0); clientEngine.feedEncryptedPacket(buf); clientListener.getRunnable().run(); List<ByteBuffer> buffers = clientListener.getToSendToSocket(); svrEngine.feedEncryptedPacket(buffers.get(0)); svrListener.getRunnable().run(); svrEngine.feedEncryptedPacket(buffers.get(1)); svrEngine.feedEncryptedPacket(buffers.get(2)); Assert.assertTrue(svrListener.connected); List<ByteBuffer> toClientBuffers = svrListener.getToSendToSocket(); clientEngine.feedEncryptedPacket(toClientBuffers.get(0)); clientEngine.feedEncryptedPacket(toClientBuffers.get(1)); Assert.assertTrue(clientListener.connected); transferBigData(); } @Test public void testBasicCloseFromServer() throws GeneralSecurityException, IOException { svrEngine.close(); List<ByteBuffer> bufs = svrListener.getToSendToSocket(); clientEngine.feedEncryptedPacket(bufs.get(0)); Assert.assertTrue(clientListener.closed); Assert.assertFalse(clientListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, clientEngine.getConnectionState()); ByteBuffer buf = clientListener.getToSendToSocket().get(0); svrEngine.feedEncryptedPacket(buf); Assert.assertTrue(svrListener.closed); Assert.assertTrue(svrListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, svrEngine.getConnectionState()); } @Test public void testBasicCloseFromClient() throws GeneralSecurityException, IOException { clientEngine.close(); Assert.assertFalse(clientListener.closed); Assert.assertEquals(ConnectionState.DISCONNECTING, clientEngine.getConnectionState()); ByteBuffer bufs = clientListener.getToSendToSocket().get(0); svrEngine.feedEncryptedPacket(bufs); Assert.assertTrue(svrListener.closed); Assert.assertFalse(svrListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, svrEngine.getConnectionState()); ByteBuffer buf = svrListener.getToSendToSocket().get(0); clientEngine.feedEncryptedPacket(buf); Assert.assertTrue(clientListener.closed); Assert.assertTrue(clientListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, clientEngine.getConnectionState()); } @Test public void testBothEndsAtSameTime() { clientEngine.close(); svrEngine.close(); ByteBuffer clientBuf = clientListener.getToSendToSocket().get(0); ByteBuffer svrBuf = svrListener.getToSendToSocket().get(0); clientEngine.feedEncryptedPacket(svrBuf); Assert.assertTrue(clientListener.closed); Assert.assertTrue(clientListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, clientEngine.getConnectionState()); svrEngine.feedEncryptedPacket(clientBuf); Assert.assertTrue(svrListener.closed); Assert.assertTrue(svrListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, svrEngine.getConnectionState()); } @Test public void testRaceWithCloseCall() { svrEngine.close(); ByteBuffer svrBuf = svrListener.getToSendToSocket().get(0); clientEngine.feedEncryptedPacket(svrBuf); Assert.assertTrue(clientListener.closed); Assert.assertFalse(clientListener.clientInitiated); Assert.assertEquals(ConnectionState.DISCONNECTED, clientEngine.getConnectionState()); ByteBuffer clientBuf = clientListener.getToSendToSocket().get(0); clientEngine.close(); svrEngine.feedEncryptedPacket(clientBuf); } private void transferBigData() { ByteBuffer b = ByteBuffer.allocate(17000); b.put((byte) 1); b.put((byte) 2); b.position(b.limit()-2); //simulate buffer full of 0's except first 2 and last 2 b.put((byte) 3); b.put((byte) 4); b.flip(); clientEngine.feedPlainPacket(b); List<ByteBuffer> encrypted = clientListener.getToSendToSocket(); //results in two ssl packets instead of the one that was fed in.. Assert.assertEquals(2, encrypted.size()); svrEngine.feedEncryptedPacket(encrypted.get(0)); ByteBuffer buffer = svrListener.getToSendToClient().get(0); svrEngine.feedEncryptedPacket(encrypted.get(1)); ByteBuffer buffer2 = svrListener.getToSendToClient().get(0); Assert.assertEquals(17000, buffer.remaining()+buffer2.remaining()); } }