mirror of
https://github.com/curl/curl.git
synced 2026-08-26 21:44:10 +03:00
ngtcp2+openssL: fix early data
Openssl needs an additional call into its API at just the right time to *really* enable early data use. Add checks after handshake if early data was really successful, more stringent than we used before. test_02_32: enable early data test wiht more backends and platforms to see how CI now copes with it. Fixes #22649 Closes #22657 Reported-by: Rarylson Freitas
This commit is contained in:
parent
5267ed859d
commit
d1702a24b3
3 changed files with 31 additions and 16 deletions
|
|
@ -103,7 +103,6 @@ BoringSSL). It works on TCP and QUIC connections using ngtcp2.
|
|||
This option works on a best effort basis,
|
||||
in cases when it was not possible to send early data the request is resent
|
||||
normally post-handshake.
|
||||
This option does not work when using QUIC.
|
||||
(Added in 8.11.0 for GnuTLS and 8.13.0 for OpenSSL, quictls and wolfSSL)
|
||||
|
||||
# DEFAULT
|
||||
|
|
|
|||
|
|
@ -274,15 +274,24 @@ static int cb_ngtcp2_handshake_completed(ngtcp2_conn *tconn, void *user_data)
|
|||
}
|
||||
if(ctx->use_earlydata) {
|
||||
#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA)
|
||||
ctx->earlydata_accepted =
|
||||
(SSL_get_early_data_status(ctx->tls.ossl.ssl) !=
|
||||
SSL_EARLY_DATA_REJECTED);
|
||||
/* Check for bug that OpenSSL did not even send the early data. */
|
||||
if(SSL_get_early_data_status(ctx->tls.ossl.ssl) == SSL_EARLY_DATA_NOT_SENT)
|
||||
CURL_TRC_CF(data, cf, "OpenSSL did not send early data");
|
||||
#endif
|
||||
#ifdef USE_GNUTLS
|
||||
|
||||
#if NGTCP2_VERSION_NUM >= 0x011700
|
||||
ctx->earlydata_accepted =
|
||||
!ngtcp2_conn_get_tls_early_data_rejected2(ctx->qconn);
|
||||
#else /* older NGTCP2 */
|
||||
#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA)
|
||||
int ossl_early_status = SSL_get_early_data_status(ctx->tls.ossl.ssl);
|
||||
if(ossl_early_status == SSL_EARLY_DATA_NOT_SENT)
|
||||
CURL_TRC_CF(data, cf, "OpenSSL did not send early data");
|
||||
ctx->earlydata_accepted = (ossl_early_status == SSL_EARLY_DATA_ACCEPTED);
|
||||
#elif defined(USE_GNUTLS)
|
||||
int flags = gnutls_session_get_flags(ctx->tls.gtls.session);
|
||||
ctx->earlydata_accepted = !!(flags & GNUTLS_SFLAGS_EARLY_DATA);
|
||||
#endif
|
||||
#ifdef USE_WOLFSSL
|
||||
#elif defined(USE_WOLFSSL)
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
ctx->earlydata_accepted =
|
||||
(wolfSSL_get_early_data_status(ctx->tls.wssl.ssl) !=
|
||||
|
|
@ -291,7 +300,8 @@ static int cb_ngtcp2_handshake_completed(ngtcp2_conn *tconn, void *user_data)
|
|||
DEBUGASSERT(0); /* should not come here if ED is disabled. */
|
||||
ctx->earlydata_accepted = FALSE;
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
#endif
|
||||
#endif /* OPENSSL or GNUTLS or WOLFSSL */
|
||||
#endif /* older NGTCP2 */
|
||||
CURL_TRC_CF(data, cf, "server did%s accept %zu bytes of early data",
|
||||
ctx->earlydata_accepted ? "" : " not", ctx->earlydata_skip);
|
||||
Curl_pgrsEarlyData(data, ctx->earlydata_accepted ?
|
||||
|
|
@ -1068,6 +1078,18 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
|
|||
#error "ngtcp2 TLS backend not defined"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA) && \
|
||||
defined(OPENSSL_QUIC_API2)
|
||||
/* We need to tell OpenSSL to *really* use Early Data for QUIC and
|
||||
* this only works *after* ngtcp2 has tweaked all SSL parameters,
|
||||
* otherwise OpenSSL does not accept it. */
|
||||
if(ctx->use_earlydata &&
|
||||
!SSL_set_quic_tls_early_data_enabled(ctx->tls.ossl.ssl, 1)) {
|
||||
CURL_TRC_CF(data, cf, "OpenSSL refused to use early data");
|
||||
ctx->use_earlydata = FALSE;
|
||||
cf->connected = FALSE;
|
||||
}
|
||||
#endif
|
||||
ngtcp2_ccerr_default(&ctx->last_error);
|
||||
|
||||
return CURLE_OK;
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ class TestDownload:
|
|||
assert r.total_connects <= 3, r.dump_logs()
|
||||
|
||||
# nghttpx is the only server we have that supports TLS early data
|
||||
@pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx")
|
||||
@pytest.mark.skipif(condition=not Env.have_h3_server(), reason="no nghttpx with QUIC")
|
||||
@pytest.mark.skipif(condition=not Env.curl_is_debug(), reason="needs curl debug")
|
||||
@pytest.mark.skipif(condition=not Env.curl_is_verbose(), reason="needs curl verbose strings")
|
||||
@pytest.mark.parametrize("proto", Env.http_protos())
|
||||
|
|
@ -535,12 +535,6 @@ class TestDownload:
|
|||
pytest.skip('TLS earlydata not implemented')
|
||||
if proto == 'h3' and not env.curl_can_h3_early_data():
|
||||
pytest.skip("h3 early data not supported")
|
||||
if proto != 'h3' and sys.platform.startswith('darwin') and env.ci_run:
|
||||
pytest.skip('failing on macOS CI runners')
|
||||
if proto == 'h3' and env.curl_uses_lib('wolfssl'):
|
||||
pytest.skip('h3 wolfssl early data failing')
|
||||
if proto == 'h3' and env.curl_uses_lib('gnutls'):
|
||||
pytest.skip('h3 gnutls early data failing')
|
||||
count = 2
|
||||
docname = 'data-10k'
|
||||
# we want this test to always connect to nghttpx, since it is
|
||||
|
|
@ -571,7 +565,7 @@ class TestDownload:
|
|||
if m:
|
||||
earlydata[int(m.group(1))] = int(m.group(2))
|
||||
continue
|
||||
if re.match(r'\[1-1] \* SSL reusing session.*', line):
|
||||
if re.match(r'\[1-1] \* (\[1-1] )?SSL reusing session.*', line):
|
||||
reused_session = True
|
||||
assert reused_session, 'session was not reused for 2nd transfer'
|
||||
assert earlydata[0] == 0, f'{earlydata}'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue