Ensure calling ReferenceCountedSslEngine.unwrap(...) / wrap(...) can be called after it was closed

Motivation:

The JDK implementation of SSLEngine allows to have unwrap(...) / wrap(...) called even after closeInbound() and closeOutbound() were called. We need to support the same in ReferenceCountedSslEngine.

Modification:

- Allow calling ReferenceCountedSslEngine.unwrap(...) / wrap(...) after the engine was closed
- Modify unit test to ensure correct behaviour.

Result:

Implementation works as expected.
This commit is contained in:
Norman Maurer 2017-01-13 15:25:07 +01:00
parent 821501717b
commit 91951a51ad
2 changed files with 39 additions and 7 deletions

View File

@ -553,6 +553,9 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
// If the inbound was done as well, we need to ensure we return NOT_HANDSHAKING to signal we are
// done.
hs = NOT_HANDSHAKING;
// As the inbound and the outbound is done we can shutdown the engine now.
shutdown();
}
} else {
rs = OK;
@ -585,10 +588,8 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
}
synchronized (this) {
// Check to make sure the engine has not been closed and the outbound is not considered as done while the
// handshake was not started at all.
if (isDestroyed() || (handshakeState == HandshakeState.NOT_STARTED && isOutboundDone())) {
return CLOSED_NOT_HANDSHAKING;
if (isOutboundDone()) {
return isInboundDone() || isDestroyed() ? CLOSED_NOT_HANDSHAKING : NEED_UNWRAP_CLOSED;
}
SSLEngineResult.HandshakeStatus status = NOT_HANDSHAKING;
@ -769,9 +770,8 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc
}
synchronized (this) {
// Check to make sure the engine has not been closed and the inbound was not marked as done.
if (isDestroyed() || (handshakeState == HandshakeState.NOT_STARTED && isInboundDone())) {
return CLOSED_NOT_HANDSHAKING;
if (isInboundDone()) {
return isOutboundDone() || isDestroyed() ? CLOSED_NOT_HANDSHAKING : NEED_WRAP_CLOSED;
}
// protect against protocol overflow attack vector

View File

@ -1317,6 +1317,31 @@ public abstract class SSLEngineTest {
assertTrue(client.isOutboundDone());
assertTrue(client.isInboundDone());
// Ensure that calling wrap or unwrap again will not produce a SSLException
encryptedServerToClient.clear();
plainServerOut.clear();
result = server.wrap(plainServerOut, encryptedServerToClient);
assertEngineRemainsClosed(result);
encryptedClientToServer.clear();
plainServerOut.clear();
result = server.unwrap(encryptedClientToServer, plainServerOut);
assertEngineRemainsClosed(result);
encryptedClientToServer.clear();
plainClientOut.clear();
result = client.wrap(plainClientOut, encryptedClientToServer);
assertEngineRemainsClosed(result);
encryptedServerToClient.clear();
plainClientOut.clear();
result = client.unwrap(encryptedServerToClient, plainClientOut);
assertEngineRemainsClosed(result);
} finally {
cert.delete();
cleanupClientSslEngine(client);
@ -1324,6 +1349,13 @@ public abstract class SSLEngineTest {
}
}
private static void assertEngineRemainsClosed(SSLEngineResult result) {
assertEquals(SSLEngineResult.Status.CLOSED, result.getStatus());
assertEquals(SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result.getHandshakeStatus());
assertEquals(0, result.bytesConsumed());
assertEquals(0, result.bytesProduced());
}
@Test
public void testMultipleRecordsInOneBufferWithNonZeroPosition() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate();