vtls/vquic, keep peer name information together

- add `struct ssl_peer` to keep hostname, dispname and sni
  for a filter
- allocate `sni` for use in VTLS backend
- eliminate `Curl_ssl_snihost()` and its use of the download buffer
- use ssl_peer in SSL and QUIC filters

Closes #12349
This commit is contained in:
Stefan Eissing 2023-11-17 15:26:08 +01:00 committed by Daniel Stenberg
parent a9fd0d0083
commit fa714830e9
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
18 changed files with 190 additions and 273 deletions

View file

@ -133,6 +133,7 @@ void Curl_ngtcp2_ver(char *p, size_t len)
struct cf_ngtcp2_ctx {
struct cf_quic_ctx q;
struct ssl_peer peer;
ngtcp2_path connected_path;
ngtcp2_conn *qconn;
ngtcp2_cid dcid;
@ -561,7 +562,6 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
struct cf_ngtcp2_ctx *ctx = cf->ctx;
const uint8_t *alpn = NULL;
size_t alpnlen = 0;
unsigned char checkip[16];
DEBUGASSERT(!ctx->ssl);
ctx->ssl = SSL_new(ctx->sslctx);
@ -576,13 +576,8 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
SSL_set_alpn_protos(ctx->ssl, alpn, (int)alpnlen);
/* set SNI */
if((0 == Curl_inet_pton(AF_INET, cf->conn->host.name, checkip))
#ifdef ENABLE_IPV6
&& (0 == Curl_inet_pton(AF_INET6, cf->conn->host.name, checkip))
#endif
) {
char *snihost = Curl_ssl_snihost(data, cf->conn->host.name, NULL);
if(!snihost || !SSL_set_tlsext_host_name(ctx->ssl, snihost)) {
if(ctx->peer.sni) {
if(!SSL_set_tlsext_host_name(ctx->ssl, ctx->peer.sni)) {
failf(data, "Failed set SNI");
SSL_free(ctx->ssl);
ctx->ssl = NULL;
@ -600,7 +595,6 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
CURLcode result;
gnutls_datum_t alpn[2];
/* this will need some attention when HTTPS proxy over QUIC get fixed */
const char * const hostname = cf->conn->host.name;
long * const pverifyresult = &data->set.ssl.certverifyresult;
int rc;
@ -614,7 +608,7 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
return CURLE_OUT_OF_MEMORY;
result = gtls_client_init(data, conn_config, &data->set.ssl,
hostname, ctx->gtls, pverifyresult);
&ctx->peer, ctx->gtls, pverifyresult);
if(result)
return result;
@ -1932,19 +1926,11 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
CURLcode result = CURLE_OK;
const char *hostname, *disp_hostname;
int port;
char *snihost;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
Curl_conn_get_host(data, cf->sockindex, &hostname, &disp_hostname, &port);
snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost)
return CURLE_PEER_FAILED_VERIFICATION;
cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
cf->conn->httpversion = 30;
cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX;
@ -1956,19 +1942,19 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
if(!server_cert) {
return CURLE_PEER_FAILED_VERIFICATION;
}
result = Curl_ossl_verifyhost(data, cf->conn, server_cert);
result = Curl_ossl_verifyhost(data, cf->conn, &ctx->peer, server_cert);
X509_free(server_cert);
if(result)
return result;
#elif defined(USE_GNUTLS)
result = Curl_gtls_verifyserver(data, ctx->gtls->session,
conn_config, &data->set.ssl,
hostname, disp_hostname,
conn_config, &data->set.ssl, &ctx->peer,
data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
if(result)
return result;
#elif defined(USE_WOLFSSL)
if(wolfSSL_check_domain_name(ctx->ssl, snihost) == SSL_FAILURE)
if(!ctx->peer.sni ||
wolfSSL_check_domain_name(ctx->ssl, ctx->peer.sni) == SSL_FAILURE)
return CURLE_PEER_FAILED_VERIFICATION;
#endif
infof(data, "Verified certificate just fine");
@ -2399,6 +2385,7 @@ static void cf_ngtcp2_ctx_clear(struct cf_ngtcp2_ctx *ctx)
if(ctx->qconn)
ngtcp2_conn_del(ctx->qconn);
Curl_bufcp_free(&ctx->stream_bufcp);
Curl_ssl_peer_cleanup(&ctx->peer);
memset(ctx, 0, sizeof(*ctx));
ctx->qlogfd = -1;
@ -2470,6 +2457,10 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE,
H3_STREAM_POOL_SPARES);
result = Curl_ssl_peer_init(&ctx->peer, cf);
if(result)
return result;
#ifdef USE_OPENSSL
result = quic_ssl_ctx(&ctx->sslctx, cf, data);
if(result)

View file

@ -91,6 +91,7 @@ static void keylog_callback(const SSL *ssl, const char *line)
struct cf_quiche_ctx {
struct cf_quic_ctx q;
struct ssl_peer peer;
quiche_conn *qconn;
quiche_config *cfg;
quiche_h3_conn *h3c;
@ -131,6 +132,8 @@ static void cf_quiche_ctx_clear(struct cf_quiche_ctx *ctx)
if(ctx->cfg)
quiche_config_free(ctx->cfg);
Curl_bufcp_free(&ctx->stream_bufcp);
Curl_ssl_peer_cleanup(&ctx->peer);
memset(ctx, 0, sizeof(*ctx));
}
}
@ -182,12 +185,16 @@ static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct cf_quiche_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
unsigned char checkip[16];
CURLcode result;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
result = Curl_ssl_peer_init(&ctx->peer, cf);
if(result)
return result;
DEBUGASSERT(!ctx->sslctx);
ctx->sslctx = SSL_CTX_new(TLS_method());
if(!ctx->sslctx)
@ -218,13 +225,8 @@ static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data)
SSL_set_app_data(ctx->ssl, cf);
if((0 == Curl_inet_pton(AF_INET, cf->conn->host.name, checkip))
#ifdef ENABLE_IPV6
&& (0 == Curl_inet_pton(AF_INET6, cf->conn->host.name, checkip))
#endif
) {
char *snihost = Curl_ssl_snihost(data, cf->conn->host.name, NULL);
if(!snihost || !SSL_set_tlsext_host_name(ctx->ssl, snihost)) {
if(ctx->peer.sni) {
if(!SSL_set_tlsext_host_name(ctx->ssl, ctx->peer.sni)) {
failf(data, "Failed set SNI");
SSL_free(ctx->ssl);
ctx->ssl = NULL;
@ -1267,7 +1269,7 @@ static CURLcode cf_verify_peer(struct Curl_cfilter *cf,
result = CURLE_PEER_FAILED_VERIFICATION;
goto out;
}
result = Curl_ossl_verifyhost(data, cf->conn, server_cert);
result = Curl_ossl_verifyhost(data, cf->conn, &ctx->peer, server_cert);
X509_free(server_cert);
if(result)
goto out;