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]