Skip to content

WebSocket handshake fails over WSS, if client uses TLS False Start #940

Closed

Description

@avojenk

Describe the bug
If client uses TLS False Start, WebSocket handshake data sent from client gets thrown away in server.
Related to #466 and #665.
TLS False Start (https://tools.ietf.org/html/rfc7918) means the client can start sending application data immediately after sending ChangeCipherSpec and Finished messages during the TLS handshake, as opposed to having to wait for the server to respond with its ChangeCipherSpec and Finished messages.
The issue is similar to #665 in that any remaining data in the inCrypt buffer is dropped when processHandshake calls createBuffers(), but applying the fix proposed in #665 is only part of the solution, because in this case the data is received during the handshake and when handshake completes, no additional SSLSocketChannel2.read is attempted, which would restore the data. Not sure why, I haven't looked further than SSLSocketChannel2 in the code.

#466 was also caused by this issue.
#466 (comment)
Java 8 does support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, the cipher suites mentioned in the SO post and which aren't supported by default with the limited crypto policy are AES_256 ciphers.
Disabling this cipher suite "fixed" the issue because TLS False Start can be used by the client when certain preconditions are met, one of which is a whitelisted cipher suite (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 is one of them). When this cipher suite is removed, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (in my case) gets negotiated, which isn't whitelisted.

To Reproduce
Use Firefox, has false start enabled by default (can be disabled in about:config security.ssl.enable_false_start). Can play around with this setting to make sure the issue is occurring because of TLS False Start.
Not reproducible with Chrome: did have TLS False Start enabled at some point, but is disabled by default now and only enabled if server supports ALPN (Application-Layer Protocol Negotiation): https://arstechnica.com/information-technology/2012/04/google-abandons-noble-experiment-to-make-ssl-less-painful/
Use CustomSSLWebSocketServerFactory with all cipher suites enabled (DefaultSSLWebSocketServerFactory disables TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 as of v1.3.4).
Use some packet sniffing tool to make sure TLS False Start occurs. Won't occur when TLS session resumption gets used.

Environment:

  • Version used: 1.4.0
  • Java version: 1.8
  • Operating System and version: Win 7
  • Endpoint Name and version: Firefox 69.0

Activity

  1. marci4 commented on Nov 15, 2019

    @marci4
    Collaborator

    Hello @avojenk,
    thx for looking into your issue.
    If I understand you correctly, not supporting AES_X should help?

    Or do you have some proposed changes?

    Best regards,
    Marcel

  2. liuqixing commented on Dec 5, 2019

    @liuqixing

    Why don't deploy your Java-WebSocket project as a Docker behind a NGINX gateway over proxy_pass.
    If so, NGINX will help you manage SSL certificates.

    So I often said that NGINX is our friend forever.
    I did all projects like this.

  3. jiangjianping commented on Dec 17, 2019

    @jiangjianping

    We confirmed that this fix #958 almost. After patching, the problem occurred very rarely.

  4. added this to the Release 1.4.1 milestone on Jan 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions