pjfanning opened a new pull request, #3738:
URL: https://github.com/apache/pekko/pull/3738

   ### Motivation
   On plaintext-output cancellation, the GraphStage TLS engine (#3727) drains 
plaintext it has already accepted for the established session, but stops if a 
new handshake is required. It treated any `NEED_WRAP` handshake status as a new 
handshake. A TLS 1.3 KeyUpdate that requests an update puts the JDK engine into 
`NEED_WRAP` until the response is wrapped. So a KeyUpdate received before or 
during the drain closed outbound and discarded the accepted plaintext, although 
no new handshake was involved.
   
   KeyUpdates are rare in practice (the JDK triggers them after 
`jdk.tls.keyLimits`, by default a very large data volume), but long-lived 
connections can hit one.
   
   ### Modification
   - `TlsGraphStage.canDrainAcceptedUserInput` also allows `NEED_WRAP` when the 
established session is TLS 1.3. TLS 1.3 has no renegotiation, so this is a 
post-handshake message such as a KeyUpdate response. The drain wraps that 
response first, then the accepted plaintext, then closes as before.
   - TLS 1.2 still stops the drain on `NEED_WRAP`, because it may start a 
renegotiation.
   - The stream IO guide and the scaladsl/javadsl `TLS` scaladoc describe the 
KeyUpdate case next to the existing "draining stops if a new handshake is 
required" text.
   - Test-only: the scripted `SSLEngine` in `TlsGraphStageDeferredCloseSpec` 
can report a session protocol and, like the JDK, wrap only the handshake 
message (consuming no plaintext) while `NEED_WRAP`.
   
   ### Result
   A TLS 1.3 KeyUpdate no longer discards plaintext accepted before 
plaintext-output cancellation. TLS 1.2 behaviour is unchanged.
   
   ### Tests
   - `stream-tests/testOnly 
org.apache.pekko.stream.io.TlsGraphStageDeferredCloseSpec`: 25 passed.
     - New: `keep draining accepted plaintext after a TLS 1.3 KeyUpdate 
received before/after output cancellation`. Both fail without the fix 
(`ByteString() was not equal to ByteString(92, 90)`: nothing sent, the accepted 
plaintext was discarded).
     - New: `stop draining when a TLS 1.2 engine needs to wrap during output 
cancellation`. Guards the unchanged TLS 1.2 behaviour; passes with and without 
the fix.
   - `stream-tests/testOnly org.apache.pekko.stream.io.Tls*`: 11 suites, 288 
passed
   - `scalafmt --mode diff-ref=upstream/main`: clean
   - MiMa not run: the change is a private method in the internal 
`TlsGraphStage` logic.
   
   The tests use a scripted engine because the JDK has no API to send a 
KeyUpdate, and `jdk.tls.keyLimits` is read once per JVM, so it can't be lowered 
reliably inside the shared test JVM.
   
   ### References
   Refs #3727
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to