From d0fea48604359239d71923447b9138b5c0c54cee Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Thu, 29 Apr 2021 00:56:01 -0700 Subject: [PATCH] ReferenceCountedOpenSslEngine unwrap handshake complete status fix (#11210) Motivation: ReferenceCountedOpenSslEngine may unwrap data and complete the handshake in a single unwrap() call. However it may return HanshakeStatus of HandshakeStatus of NEED_UNWRAP instead of FINISHED. This may result in the SslHandler sending the unwrapped data up the pipeline before notifying that the handshake has completed, and result in out-of-order events. Modifications: - if ReferenceCountedOpenSslEngine handshake status is NEED_UNWRAP and produced data, or NEED_WRAP and consumed some data, we should call handshake() to get the current state. Result: ReferenceCountedOpenSslEngine correctly indicates when the handshake has finished if at the same time data was produced or consumed. --- .../handler/ssl/ReferenceCountedOpenSslEngine.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java index 6251241983..1554137e1b 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java @@ -74,8 +74,8 @@ import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_2; import static io.netty.handler.ssl.SslUtils.PROTOCOL_TLS_V1_3; import static io.netty.handler.ssl.SslUtils.SSL_RECORD_HEADER_LENGTH; import static io.netty.util.internal.ObjectUtil.checkNotNull; -import static io.netty.util.internal.ObjectUtil.checkNotNullWithIAE; import static io.netty.util.internal.ObjectUtil.checkNotNullArrayParam; +import static io.netty.util.internal.ObjectUtil.checkNotNullWithIAE; import static java.lang.Integer.MAX_VALUE; import static java.lang.Math.min; import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED; @@ -1032,15 +1032,13 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.HandshakeStatus hs, int bytesConsumed, int bytesProduced) throws SSLException { - return newResult(mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED), - bytesConsumed, bytesProduced); + return newResult(mayFinishHandshake(hs, bytesConsumed, bytesProduced), bytesConsumed, bytesProduced); } private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.Status status, SSLEngineResult.HandshakeStatus hs, int bytesConsumed, int bytesProduced) throws SSLException { - return newResult(status, mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED), - bytesConsumed, bytesProduced); + return newResult(status, mayFinishHandshake(hs, bytesConsumed, bytesProduced), bytesConsumed, bytesProduced); } /** @@ -1927,6 +1925,12 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc return FINISHED; } + private SSLEngineResult.HandshakeStatus mayFinishHandshake( + SSLEngineResult.HandshakeStatus hs, int bytesConsumed, int bytesProduced) throws SSLException { + return hs == NEED_UNWRAP && bytesProduced > 0 || hs == NEED_WRAP && bytesConsumed > 0 ? + handshake() : mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED); + } + private SSLEngineResult.HandshakeStatus mayFinishHandshake(SSLEngineResult.HandshakeStatus status) throws SSLException { if (status == NOT_HANDSHAKING && handshakeState != HandshakeState.FINISHED) {