@@ -1645,6 +1645,10 @@ protected void handshake(BufferType type, boolean delegate, SSLEngine clientEngi
16451645 if (isHandshakeFinished (clientResult )) {
16461646 clientHandshakeFinished = true ;
16471647 }
1648+
1649+ if (clientResult .getStatus () == Status .BUFFER_OVERFLOW ) {
1650+ cTOs = increaseDstBuffer (clientEngine .getSession ().getPacketBufferSize (), type , cTOs );
1651+ }
16481652 }
16491653
16501654 if (!serverHandshakeFinished ) {
@@ -1656,6 +1660,10 @@ protected void handshake(BufferType type, boolean delegate, SSLEngine clientEngi
16561660 if (isHandshakeFinished (serverResult )) {
16571661 serverHandshakeFinished = true ;
16581662 }
1663+
1664+ if (serverResult .getStatus () == Status .BUFFER_OVERFLOW ) {
1665+ sTOc = increaseDstBuffer (serverEngine .getSession ().getPacketBufferSize (), type , sTOc );
1666+ }
16591667 }
16601668
16611669 cTOs .flip ();
@@ -1674,10 +1682,16 @@ protected void handshake(BufferType type, boolean delegate, SSLEngine clientEngi
16741682 runDelegatedTasks (delegate , clientResult , clientEngine );
16751683 assertEquals (sTOc .position () - sTOcPos , clientResult .bytesConsumed ());
16761684 assertEquals (clientAppReadBuffer .position () - clientAppReadBufferPos , clientResult .bytesProduced ());
1685+ assertEquals (0 , clientAppReadBuffer .position ());
16771686
16781687 if (isHandshakeFinished (clientResult )) {
16791688 clientHandshakeFinished = true ;
16801689 }
1690+
1691+ if (clientResult .getStatus () == Status .BUFFER_OVERFLOW ) {
1692+ clientAppReadBuffer = increaseDstBuffer (
1693+ clientEngine .getSession ().getApplicationBufferSize (), type , clientAppReadBuffer );
1694+ }
16811695 } else {
16821696 assertEquals (0 , sTOc .remaining ());
16831697 }
@@ -1688,26 +1702,59 @@ protected void handshake(BufferType type, boolean delegate, SSLEngine clientEngi
16881702 runDelegatedTasks (delegate , serverResult , serverEngine );
16891703 assertEquals (cTOs .position () - cTOsPos , serverResult .bytesConsumed ());
16901704 assertEquals (serverAppReadBuffer .position () - serverAppReadBufferPos , serverResult .bytesProduced ());
1705+ assertEquals (0 , serverAppReadBuffer .position ());
16911706
16921707 if (isHandshakeFinished (serverResult )) {
16931708 serverHandshakeFinished = true ;
16941709 }
1710+
1711+ if (serverResult .getStatus () == Status .BUFFER_OVERFLOW ) {
1712+ serverAppReadBuffer = increaseDstBuffer (
1713+ serverEngine .getSession ().getApplicationBufferSize (), type , serverAppReadBuffer );
1714+ }
16951715 } else {
16961716 assertFalse (cTOs .hasRemaining ());
16971717 }
16981718
1699- cTOsHasRemaining = cTOs .hasRemaining ();
1700- sTOcHasRemaining = sTOc .hasRemaining ();
1719+ cTOsHasRemaining = compactOrClear (cTOs );
1720+ sTOcHasRemaining = compactOrClear (sTOc );
1721+
1722+ serverAppReadBuffer .clear ();
1723+ clientAppReadBuffer .clear ();
17011724
1702- sTOc .compact ();
1703- cTOs .compact ();
1725+ if (clientEngine .getHandshakeStatus () == SSLEngineResult .HandshakeStatus .NOT_HANDSHAKING ) {
1726+ clientHandshakeFinished = true ;
1727+ }
1728+
1729+ if (serverEngine .getHandshakeStatus () == SSLEngineResult .HandshakeStatus .NOT_HANDSHAKING ) {
1730+ serverHandshakeFinished = true ;
1731+ }
17041732 } while (!clientHandshakeFinished || !serverHandshakeFinished ||
17051733 // We need to ensure we feed all the data to the engine to not end up with a corrupted state.
17061734 // This is especially important with TLS1.3 which may produce sessions after the "main handshake" is
17071735 // done
17081736 cTOsHasRemaining || sTOcHasRemaining );
17091737 }
17101738
1739+ private static boolean compactOrClear (ByteBuffer buffer ) {
1740+ if (buffer .hasRemaining ()) {
1741+ buffer .compact ();
1742+ return true ;
1743+ }
1744+ buffer .clear ();
1745+ return false ;
1746+ }
1747+
1748+ private ByteBuffer increaseDstBuffer (int maxBufferSize ,
1749+ BufferType type , ByteBuffer dstBuffer ) {
1750+ assumeFalse (maxBufferSize == dstBuffer .remaining ());
1751+ // We need to increase the destination buffer
1752+ dstBuffer .flip ();
1753+ ByteBuffer tmpBuffer = allocateBuffer (type , maxBufferSize + dstBuffer .remaining ());
1754+ tmpBuffer .put (dstBuffer );
1755+ return tmpBuffer ;
1756+ }
1757+
17111758 private static boolean isHandshakeFinished (SSLEngineResult result ) {
17121759 return result .getHandshakeStatus () == SSLEngineResult .HandshakeStatus .FINISHED ;
17131760 }
@@ -4243,6 +4290,40 @@ public void testInvalidSNIIsIgnoredAndNotThrow(SSLEngineTestParam param) throws
42434290 }
42444291 }
42454292
4293+ @ MethodSource ("newTestParams" )
4294+ @ ParameterizedTest
4295+ public void testBufferUnderflowPacketSizeDependency (SSLEngineTestParam param ) throws Exception {
4296+ SelfSignedCertificate ssc = new SelfSignedCertificate ();
4297+ clientSslCtx = wrapContext (param , SslContextBuilder .forClient ()
4298+ .keyManager (ssc .certificate (), ssc .privateKey ())
4299+ .trustManager ((TrustManagerFactory ) null )
4300+ .sslProvider (sslClientProvider ())
4301+ .sslContextProvider (clientSslContextProvider ())
4302+ .protocols (param .protocols ())
4303+ .ciphers (param .ciphers ())
4304+ .build ());
4305+ serverSslCtx = wrapContext (param , SslContextBuilder .forServer (ssc .certificate (), ssc .privateKey ())
4306+ .sslProvider (sslServerProvider ())
4307+ .sslContextProvider (serverSslContextProvider ())
4308+ .protocols (param .protocols ())
4309+ .ciphers (param .ciphers ())
4310+ .clientAuth (ClientAuth .REQUIRE )
4311+ .build ());
4312+ SSLEngine clientEngine = null ;
4313+ SSLEngine serverEngine = null ;
4314+ try {
4315+ clientEngine = wrapEngine (clientSslCtx .newEngine (UnpooledByteBufAllocator .DEFAULT ));
4316+ serverEngine = wrapEngine (serverSslCtx .newEngine (UnpooledByteBufAllocator .DEFAULT ));
4317+
4318+ handshake (param .type (), param .delegate (), clientEngine , serverEngine );
4319+ } catch (SSLHandshakeException expected ) {
4320+ // Expected
4321+ } finally {
4322+ cleanupClientSslEngine (clientEngine );
4323+ cleanupServerSslEngine (serverEngine );
4324+ }
4325+ }
4326+
42464327 protected SSLEngine wrapEngine (SSLEngine engine ) {
42474328 return engine ;
42484329 }
0 commit comments