ngtcp2+openssL: fix early data
No binary (build failed)
—
(log yok)
| @@ -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}' | |