Merge pull request #2277 from eclipse/jetty-9.4.x-2255-notify_ssl_handshake_on_write_failures

Issue #2255 - Notify SSL handshake failures on write failures.
This commit is contained in:
Joakim Erdfelt 2018-03-02 09:45:38 -06:00 committed by GitHub
commit 2879d5a5a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 36 additions and 34 deletions

View File

@ -25,6 +25,7 @@ import java.nio.channels.ClosedChannelException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
@ -427,7 +428,7 @@ public class SslConnection extends AbstractConnection
private boolean _fillRequiresFlushToProgress;
private boolean _flushRequiresFillToProgress;
private boolean _cannotAcceptMoreAppDataToFlush;
private boolean _handshaken;
private AtomicReference<Handshake> _handshake = new AtomicReference<>(Handshake.INITIAL);
private boolean _underFlown;
private final Callback _writeCallback = new WriteCallBack();
@ -639,7 +640,7 @@ public class SslConnection extends AbstractConnection
// Let's try reading some encrypted data... even if we have some already.
int net_filled = getEndPoint().fill(_encryptedInput);
if (net_filled > 0 && !_handshaken && _sslEngine.isOutboundDone())
if (net_filled > 0 && _handshake.get() == Handshake.INITIAL && _sslEngine.isOutboundDone())
throw new SSLHandshakeException("Closed during handshake");
decryption: while (true)
@ -718,7 +719,7 @@ public class SslConnection extends AbstractConnection
case OK:
{
if (unwrapHandshakeStatus == HandshakeStatus.FINISHED)
handshakeFinished();
handshakeSucceeded();
// Check whether re-negotiation is allowed
if (!allowRenegotiate(handshakeStatus))
@ -791,24 +792,9 @@ public class SslConnection extends AbstractConnection
}
}
}
catch (SSLHandshakeException x)
{
notifyHandshakeFailed(_sslEngine, x);
failure = x;
throw x;
}
catch (SSLException x)
{
if (!_handshaken)
{
x = (SSLException)new SSLHandshakeException(x.getMessage()).initCause(x);
notifyHandshakeFailed(_sslEngine, x);
}
failure = x;
throw x;
}
catch (Throwable x)
{
handshakeFailed(x);
failure = x;
throw x;
}
@ -841,18 +827,10 @@ public class SslConnection extends AbstractConnection
}
}
private void handshakeFinished()
private void handshakeSucceeded()
{
if (_handshaken)
if (_handshake.compareAndSet(Handshake.INITIAL, Handshake.SUCCEEDED))
{
if (LOG.isDebugEnabled())
LOG.debug("Renegotiated {}", SslConnection.this);
if (_renegotiationLimit>0)
_renegotiationLimit--;
}
else
{
_handshaken = true;
if (LOG.isDebugEnabled())
LOG.debug("{} handshake succeeded {}/{} {}",
_sslEngine.getUseClientMode() ? "client" : "resumed server",
@ -860,11 +838,28 @@ public class SslConnection extends AbstractConnection
SslConnection.this);
notifyHandshakeSucceeded(_sslEngine);
}
else if (_handshake.get() == Handshake.SUCCEEDED)
{
if (LOG.isDebugEnabled())
LOG.debug("Renegotiated {}", SslConnection.this);
if (_renegotiationLimit>0)
_renegotiationLimit--;
}
}
private void handshakeFailed(Throwable failure)
{
if (_handshake.compareAndSet(Handshake.INITIAL, Handshake.FAILED))
{
if (!(failure instanceof SSLHandshakeException))
failure = new SSLHandshakeException(failure.getMessage()).initCause(failure);
notifyHandshakeFailed(_sslEngine, failure);
}
}
private boolean allowRenegotiate(HandshakeStatus handshakeStatus)
{
if (!_handshaken || handshakeStatus == HandshakeStatus.NOT_HANDSHAKING)
if (_handshake.get() == Handshake.INITIAL || handshakeStatus == HandshakeStatus.NOT_HANDSHAKING)
return true;
if (!isRenegotiationAllowed())
@ -1006,7 +1001,7 @@ public class SslConnection extends AbstractConnection
LOG.debug("wrap {} {} {}", wrapResultStatus, BufferUtil.toHexSummary(_encryptedOutput), SslConnection.this);
if (wrapResult.getHandshakeStatus() == HandshakeStatus.FINISHED)
handshakeFinished();
handshakeSucceeded();
HandshakeStatus handshakeStatus = _sslEngine.getHandshakeStatus();
@ -1016,7 +1011,7 @@ public class SslConnection extends AbstractConnection
getEndPoint().shutdownOutput();
return allConsumed;
}
// if we have net bytes, let's try to flush them
if (BufferUtil.hasContent(_encryptedOutput))
if (!getEndPoint().flush(_encryptedOutput))
@ -1065,9 +1060,9 @@ public class SslConnection extends AbstractConnection
}
}
}
catch (SSLHandshakeException x)
catch (Throwable x)
{
notifyHandshakeFailed(_sslEngine, x);
handshakeFailed(x);
throw x;
}
finally
@ -1236,4 +1231,11 @@ public class SslConnection extends AbstractConnection
}
}
}
private enum Handshake
{
INITIAL,
SUCCEEDED,
FAILED
}
}