mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:41:40 +03:00
h3: HTTPS-RR use in HTTP/3
When HTTPS-RR is needed for the HTTP/3 handshake, delay the connect until it arrives. Relevant only for TLS backends that support ECH, for now. Closes #21253
This commit is contained in:
parent
3bde26dac8
commit
d99df64405
6 changed files with 52 additions and 15 deletions
|
|
@ -52,6 +52,7 @@
|
||||||
#include "rand.h"
|
#include "rand.h"
|
||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
#include "cfilters.h"
|
#include "cfilters.h"
|
||||||
|
#include "cf-dns.h"
|
||||||
#include "cf-socket.h"
|
#include "cf-socket.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
|
|
@ -2594,6 +2595,18 @@ static CURLcode cf_ngtcp2_on_session_reuse(struct Curl_cfilter *cf,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cf_ngtcp2_need_httpsrr(struct Curl_easy *data)
|
||||||
|
{
|
||||||
|
#ifdef USE_OPENSSL
|
||||||
|
return Curl_ossl_need_httpsrr(data);
|
||||||
|
#elif defined(USE_WOLFSSL)
|
||||||
|
return Curl_wssl_need_httpsrr(data);
|
||||||
|
#else
|
||||||
|
(void)data;
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Might be called twice for happy eyeballs.
|
* Might be called twice for happy eyeballs.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2708,8 +2721,14 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
|
|
||||||
*done = FALSE;
|
*done = FALSE;
|
||||||
pktx_init(&pktx, cf, data);
|
|
||||||
|
|
||||||
|
if(cf_ngtcp2_need_httpsrr(data) &&
|
||||||
|
!Curl_conn_dns_resolved_https(data, cf->sockindex)) {
|
||||||
|
CURL_TRC_CF(data, cf, "need HTTPS-RR, delaying connect");
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
pktx_init(&pktx, cf, data);
|
||||||
CF_DATA_SAVE(save, cf, data);
|
CF_DATA_SAVE(save, cf, data);
|
||||||
|
|
||||||
if(!ctx->qconn) {
|
if(!ctx->qconn) {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "uint-hash.h"
|
#include "uint-hash.h"
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "cfilters.h"
|
#include "cfilters.h"
|
||||||
|
#include "cf-dns.h"
|
||||||
#include "cf-socket.h"
|
#include "cf-socket.h"
|
||||||
#include "curl_trc.h"
|
#include "curl_trc.h"
|
||||||
#include "rand.h"
|
#include "rand.h"
|
||||||
|
|
@ -1378,6 +1379,12 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
|
|
||||||
*done = FALSE;
|
*done = FALSE;
|
||||||
|
if(Curl_ossl_need_httpsrr(data) &&
|
||||||
|
!Curl_conn_dns_resolved_https(data, cf->sockindex)) {
|
||||||
|
CURL_TRC_CF(data, cf, "need HTTPS-RR, delaying connect");
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
vquic_ctx_update_time(&ctx->q, Curl_pgrs_now(data));
|
vquic_ctx_update_time(&ctx->q, Curl_pgrs_now(data));
|
||||||
|
|
||||||
if(!ctx->qconn) {
|
if(!ctx->qconn) {
|
||||||
|
|
|
||||||
|
|
@ -3424,7 +3424,7 @@ ossl_init_session_and_alpns(struct ossl_ctx *octx,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST
|
#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST
|
||||||
static bool ossl_ech_need_httpsrr(struct Curl_easy *data)
|
bool Curl_ossl_need_httpsrr(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
if(!CURLECH_ENABLED(data))
|
if(!CURLECH_ENABLED(data))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -3506,7 +3506,7 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx,
|
||||||
const unsigned char *ecl = rinfo->echconfiglist;
|
const unsigned char *ecl = rinfo->echconfiglist;
|
||||||
size_t elen = rinfo->echconfiglist_len;
|
size_t elen = rinfo->echconfiglist_len;
|
||||||
|
|
||||||
infof(data, "ECH: ECHConfig from DoH HTTPS RR");
|
infof(data, "ECH: ECHConfig from HTTPS RR");
|
||||||
if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) {
|
if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) {
|
||||||
infof(data, "ECH: SSL_set1_ech_config_list failed");
|
infof(data, "ECH: SSL_set1_ech_config_list failed");
|
||||||
if(data->set.tls_ech & CURLECH_HARD)
|
if(data->set.tls_ech & CURLECH_HARD)
|
||||||
|
|
@ -3550,7 +3550,13 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx,
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SSL_SET1_ECH_CONFIG_LIST */
|
#else /* HAVE_SSL_SET1_ECH_CONFIG_LIST */
|
||||||
|
bool Curl_ossl_need_httpsrr(struct Curl_easy *data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif /* else HAVE_SSL_SET1_ECH_CONFIG_LIST */
|
||||||
|
|
||||||
static CURLcode ossl_init_ssl(struct ossl_ctx *octx,
|
static CURLcode ossl_init_ssl(struct ossl_ctx *octx,
|
||||||
struct Curl_cfilter *cf,
|
struct Curl_cfilter *cf,
|
||||||
|
|
@ -4943,15 +4949,11 @@ static CURLcode ossl_connect(struct Curl_cfilter *cf,
|
||||||
connssl->io_need = CURL_SSL_IO_NEED_NONE;
|
connssl->io_need = CURL_SSL_IO_NEED_NONE;
|
||||||
|
|
||||||
if(ssl_connect_1 == connssl->connecting_state) {
|
if(ssl_connect_1 == connssl->connecting_state) {
|
||||||
#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST
|
if(Curl_ossl_need_httpsrr(data) &&
|
||||||
/* if we do ECH and need the HTTPS-RR information for it,
|
|
||||||
* we delay the connect until it arrives or DNS resolve fails. */
|
|
||||||
if(ossl_ech_need_httpsrr(data) &&
|
|
||||||
!Curl_conn_dns_resolved_https(data, cf->sockindex)) {
|
!Curl_conn_dns_resolved_https(data, cf->sockindex)) {
|
||||||
CURL_TRC_CF(data, cf, "need HTTPS-RR for ECH, delaying connect");
|
CURL_TRC_CF(data, cf, "need HTTPS-RR, delaying connect");
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
CURL_TRC_CF(data, cf, "ossl_connect, step1");
|
CURL_TRC_CF(data, cf, "ossl_connect, step1");
|
||||||
result = ossl_connect_step1(cf, data);
|
result = ossl_connect_step1(cf, data);
|
||||||
if(result)
|
if(result)
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,9 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
|
||||||
void *ssl_user_data,
|
void *ssl_user_data,
|
||||||
Curl_ossl_init_session_reuse_cb *sess_reuse_cb);
|
Curl_ossl_init_session_reuse_cb *sess_reuse_cb);
|
||||||
|
|
||||||
|
/* Is a resolved HTTPS-RR needed for initializing OpenSSL? */
|
||||||
|
bool Curl_ossl_need_httpsrr(struct Curl_easy *data);
|
||||||
|
|
||||||
#ifndef HAVE_OPENSSL3
|
#ifndef HAVE_OPENSSL3
|
||||||
#define SSL_get1_peer_certificate SSL_get_peer_certificate
|
#define SSL_get1_peer_certificate SSL_get_peer_certificate
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1297,7 +1297,7 @@ static CURLcode wssl_init_ech(struct wssl_ctx *wctx,
|
||||||
const unsigned char *ecl = rinfo->echconfiglist;
|
const unsigned char *ecl = rinfo->echconfiglist;
|
||||||
size_t elen = rinfo->echconfiglist_len;
|
size_t elen = rinfo->echconfiglist_len;
|
||||||
|
|
||||||
infof(data, "ECH: ECHConfig from DoH HTTPS RR");
|
infof(data, "ECH: ECHConfig from HTTPS RR");
|
||||||
if(wolfSSL_SetEchConfigs(wctx->ssl, ecl, (word32)elen) !=
|
if(wolfSSL_SetEchConfigs(wctx->ssl, ecl, (word32)elen) !=
|
||||||
WOLFSSL_SUCCESS) {
|
WOLFSSL_SUCCESS) {
|
||||||
infof(data, "ECH: wolfSSL_SetEchConfigs failed");
|
infof(data, "ECH: wolfSSL_SetEchConfigs failed");
|
||||||
|
|
@ -1487,17 +1487,20 @@ out:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG
|
bool Curl_wssl_need_httpsrr(struct Curl_easy *data)
|
||||||
static bool wssl_ech_need_httpsrr(struct Curl_easy *data)
|
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG
|
||||||
if(!CURLECH_ENABLED(data))
|
if(!CURLECH_ENABLED(data))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if((data->set.tls_ech & CURLECH_GREASE) ||
|
if((data->set.tls_ech & CURLECH_GREASE) ||
|
||||||
(data->set.tls_ech & CURLECH_CLA_CFG))
|
(data->set.tls_ech & CURLECH_CLA_CFG))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
#else
|
||||||
|
(void)data;
|
||||||
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function loads all the client/CA certificates and CRLs. Setup the TLS
|
* This function loads all the client/CA certificates and CRLs. Setup the TLS
|
||||||
|
|
@ -2171,7 +2174,7 @@ static CURLcode wssl_connect(struct Curl_cfilter *cf,
|
||||||
#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG
|
#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG
|
||||||
/* if we do ECH and need the HTTPS-RR information for it,
|
/* if we do ECH and need the HTTPS-RR information for it,
|
||||||
* we delay the connect until it arrives or DNS resolve fails. */
|
* we delay the connect until it arrives or DNS resolve fails. */
|
||||||
if(wssl_ech_need_httpsrr(data) &&
|
if(Curl_wssl_need_httpsrr(data) &&
|
||||||
!Curl_conn_dns_resolved_https(data, cf->sockindex)) {
|
!Curl_conn_dns_resolved_https(data, cf->sockindex)) {
|
||||||
CURL_TRC_CF(data, cf, "need HTTPS-RR for ECH, delaying connect");
|
CURL_TRC_CF(data, cf, "need HTTPS-RR for ECH, delaying connect");
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,9 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
|
||||||
void *ssl_user_data,
|
void *ssl_user_data,
|
||||||
Curl_wssl_init_session_reuse_cb *sess_reuse_cb);
|
Curl_wssl_init_session_reuse_cb *sess_reuse_cb);
|
||||||
|
|
||||||
|
/* Is a resolved HTTPS-RR needed for initializing wolfSSL? */
|
||||||
|
bool Curl_wssl_need_httpsrr(struct Curl_easy *data);
|
||||||
|
|
||||||
CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
|
CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct wssl_ctx *wssl);
|
struct wssl_ctx *wssl);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue