Skip to content

TLSv1.3 earlydata support for curl - #15211

Closed
icing wants to merge 3 commits into
curl:masterfrom
icing:tls-earlydata
Closed

TLSv1.3 earlydata support for curl#15211
icing wants to merge 3 commits into
curl:masterfrom
icing:tls-earlydata

Conversation

@icing

@icing icing commented Oct 9, 2024

Copy link
Copy Markdown
Contributor

Based on #14135, implement TLSv1.3 earlydata support for the curl command line, libcurl and its implementation in GnuTLS.

If a known TLS session announces early data support, and the feature is enabled and it is not a "connect-only" transfer, delay the TLS handshake until the first request is being sent.

  • Add --tls-earlydata as new boolean command line option for curl.
  • Add CURLSSLOPT_EARLYDATA to libcurl to enable use of the feature.
  • Add CURLINFO_EARLYDATA_SENT_T to libcurl, reporting the amount of bytes sent and accepted/rejected by the server.

Implementation details:

  • store the ALPN protocol selected at the SSL session.
  • When reusing the session and enabling earlydata, use exactly that ALPN protocol for negotiation with the server. When the sessions ALPN does not match the connections ALPN, earlydata will not be enabled.
  • Check that the server selected the correct ALPN protocol for an earlydata connect. If the server does not confirm or reports something different, the connect fails.
  • HTTP/2: delay sending the initial SETTINGS frames during connect, if not connect-only.

Verification:

  • add test_02_32 to verify earlydata GET with nghttpx.
  • add test_07_70 to verify earlydata PUT with nghttpx.
  • add support in 'hx-download', 'hx-upload' clients for the feature

/cc @ad-chaos

@icing

icing commented Oct 9, 2024

Copy link
Copy Markdown
Contributor Author

@tatsuhiro-t add you as reviewer should you be interested, since h2 and nghttpx are involved.

@icing icing added the TLS label Oct 9, 2024
@dfandrich

Copy link
Copy Markdown
Contributor

Analysis of PR #15211 at 3b7a2b52:

Test 303 failed, which has NOT been flaky recently, so there could be a real issue in the PR.

Test 1631 failed, which has NOT been flaky recently, so there could be a real issue in the PR.

Test 1632 failed, which has NOT been flaky recently, so there could be a real issue in the PR.

Generated by Testclutch

Comment thread docs/cmdline-opts/tls-earlydata.md Outdated
Comment thread docs/libcurl/curl_easy_getinfo.md Outdated
Comment thread docs/libcurl/opts/CURLINFO_EARLYDATA_SENT_T.md Outdated
Comment thread docs/libcurl/opts/CURLINFO_EARLYDATA_SENT_T.md Outdated
Comment thread docs/libcurl/opts/CURLINFO_EARLYDATA_SENT_T.md Outdated
Comment thread docs/libcurl/opts/CURLINFO_EARLYDATA_SENT_T.md Outdated
Comment thread docs/libcurl/opts/CURLINFO_EARLYDATA_SENT_T.md Outdated
Comment thread docs/libcurl/opts/CURLOPT_SSL_OPTIONS.md Outdated
Comment thread docs/libcurl/opts/CURLOPT_SSL_OPTIONS.md Outdated
icing added 3 commits October 10, 2024 11:02
Based on curl#14135, implement TLSv1.3 earlydata support for the
curl command line, libcurl and its implementation in GnuTLS.

If a known TLS session announces early data support, and the
feature is enabled *and* it is not a "connect-only" transfer,
delay the TLS handshake until the first request is being sent.

- Add --tls-earldata as new boolean command line option for curl.
- Add CURLSSLOPT_EARLYDATA to libcurl to enable use of the feature.
- Add CURLINFO_EARLYDATA_SENT_T to libcurl, reporting the amount of bytes sent and accepted/rejected by the server.

Implementation details:
- store the ALPN protocol selected at the SSL session.
- When reusing the session and enabling earlydata, use exactly
  that ALPN protocol for negoptiation with the server. When the
  sessions ALPN does not match the connections ALPN, earlydata
  will not be enabled.
- Check that the server selected the correct ALPN protocol for
  an earlydata connect. If the server does not confirm or reports
  something different, the connect fails.
- HTTP/2: delay sending the initial SETTINGS frames during connect,
  if not connect-only.

Verification:
- add test_02_32 to verify earlydata GET with nghttpx.
- add test_07_70 to verify earlydata PUT with nghttpx.
- add support in 'hx-download', 'hx-upload' clients for the feature
@icing
icing removed the request for review from tatsuhiro-t October 10, 2024 09:04
@tatsuhiro-t

Copy link
Copy Markdown
Contributor

FYI, by default, except for QUIC connections, nghttpx postpones forwarding HTTP requests sent in early data, including those sent in partially in it, until TLS handshake finishes.
--tls-no-postpone-early-data makes nghttpx forward HTTP requests to backends without waiting for handshake completion.

@ad-chaos

Copy link
Copy Markdown

This looks great!
It should now be straightforward to add early data support to the other backends, but perhaps after the gnutls implementation has seen some use in the wild?

@icing

icing commented Oct 11, 2024

Copy link
Copy Markdown
Contributor Author

This looks great! It should now be straightforward to add early data support to the other backends, but perhaps after the gnutls implementation has seen some use in the wild?

Yes, we'd like to gather some experience with 8.11.0 and expand this after that.

@ctz

ctz commented Oct 12, 2024

Copy link
Copy Markdown
Contributor

Implementation details:

  • store the ALPN protocol selected at the SSL session.
  • When reusing the session and enabling earlydata, use exactly that ALPN protocol for negotiation with the server. When the sessions ALPN does not match the connections ALPN, earlydata will not be enabled.
  • Check that the server selected the correct ALPN protocol for an earlydata connect. If the server does not confirm or reports something different, the connect fails.

This all seems a bit overwrought? The requirement to ensure ALPN does not change for 0-RTT is entirely on the server. The client doing anything is too late, because the early data would have already been processed by the server. The client varying its ALPN in order to coax the server to do the right thing should be unnecessary -- either the server does the right thing, or it doesn't and has a cross-protocol security vulnerability.

@icing

icing commented Oct 14, 2024

Copy link
Copy Markdown
Contributor Author

Implementation details:

  • store the ALPN protocol selected at the SSL session.
  • When reusing the session and enabling earlydata, use exactly that ALPN protocol for negotiation with the server. When the sessions ALPN does not match the connections ALPN, earlydata will not be enabled.
  • Check that the server selected the correct ALPN protocol for an earlydata connect. If the server does not confirm or reports something different, the connect fails.

This all seems a bit overwrought? The requirement to ensure ALPN does not change for 0-RTT is entirely on the server. The client doing anything is too late, because the early data would have already been processed by the server. The client varying its ALPN in order to coax the server to do the right thing should be unnecessary -- either the server does the right thing, or it doesn't and has a cross-protocol security vulnerability.

Can you describe how you would change it? As I see it, when curl wants to send early data, it needs to ALPN a specific protocol, so there is no confusion at the server. And curl starts a specific protocol, it needs to check that the server confirmed this, so that curl's protocol stack is correct in dealing with the responses.

pps83 pushed a commit to pps83/curl that referenced this pull request Apr 26, 2025
Based on curl#14135, implement TLSv1.3 earlydata support for the curl
command line, libcurl and its implementation in GnuTLS.

If a known TLS session announces early data support, and the feature is
enabled *and* it is not a "connect-only" transfer, delay the TLS
handshake until the first request is being sent.

- Add --tls-earldata as new boolean command line option for curl.
- Add CURLSSLOPT_EARLYDATA to libcurl to enable use of the feature.
- Add CURLINFO_EARLYDATA_SENT_T to libcurl, reporting the amount of
  bytes sent and accepted/rejected by the server.

Implementation details:
- store the ALPN protocol selected at the SSL session.
- When reusing the session and enabling earlydata, use exactly
  that ALPN protocol for negoptiation with the server. When the
  sessions ALPN does not match the connections ALPN, earlydata
  will not be enabled.
- Check that the server selected the correct ALPN protocol for
  an earlydata connect. If the server does not confirm or reports
  something different, the connect fails.
- HTTP/2: delay sending the initial SETTINGS frames during connect,
  if not connect-only.

Verification:
- add test_02_32 to verify earlydata GET with nghttpx.
- add test_07_70 to verify earlydata PUT with nghttpx.
- add support in 'hx-download', 'hx-upload' clients for the feature

Assisted-by: ad-chaos on github
Closes curl#15211
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

6 participants