quic: don't set SNI if hostname is an IP address

We already do this for TLS connections.

RFC 6066 says: Literal IPv4 and IPv6 addresses are not permitted in
"HostName".

Ref: https://www.rfc-editor.org/rfc/rfc6066#section-3

Fixes https://github.com/curl/curl/issues/11827
Closes https://github.com/curl/curl/pull/11828
This commit is contained in:
vvb2060 2023-09-11 03:50:10 +08:00 committed by Jay Satiro
parent 39c883560a
commit d5c562cd0d
2 changed files with 32 additions and 4 deletions

View File

@ -58,6 +58,7 @@
#include "dynbuf.h" #include "dynbuf.h"
#include "http1.h" #include "http1.h"
#include "select.h" #include "select.h"
#include "inet_pton.h"
#include "vquic.h" #include "vquic.h"
#include "vquic_int.h" #include "vquic_int.h"
#include "vtls/keylog.h" #include "vtls/keylog.h"
@ -511,8 +512,8 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
struct cf_ngtcp2_ctx *ctx = cf->ctx; struct cf_ngtcp2_ctx *ctx = cf->ctx;
const uint8_t *alpn = NULL; const uint8_t *alpn = NULL;
size_t alpnlen = 0; size_t alpnlen = 0;
unsigned char checkip[16];
(void)data;
DEBUGASSERT(!ctx->ssl); DEBUGASSERT(!ctx->ssl);
ctx->ssl = SSL_new(ctx->sslctx); ctx->ssl = SSL_new(ctx->sslctx);
@ -526,7 +527,19 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
SSL_set_alpn_protos(ctx->ssl, alpn, (int)alpnlen); SSL_set_alpn_protos(ctx->ssl, alpn, (int)alpnlen);
/* set SNI */ /* set SNI */
SSL_set_tlsext_host_name(ctx->ssl, cf->conn->host.name); 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)) {
failf(data, "Failed set SNI");
SSL_free(ctx->ssl);
ctx->ssl = NULL;
return CURLE_QUIC_CONNECT_ERROR;
}
}
return CURLE_OK; return CURLE_OK;
} }
#elif defined(USE_GNUTLS) #elif defined(USE_GNUTLS)

View File

@ -45,8 +45,10 @@
#include "vquic_int.h" #include "vquic_int.h"
#include "curl_quiche.h" #include "curl_quiche.h"
#include "transfer.h" #include "transfer.h"
#include "inet_pton.h"
#include "vtls/openssl.h" #include "vtls/openssl.h"
#include "vtls/keylog.h" #include "vtls/keylog.h"
#include "vtls/vtls.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"
@ -175,8 +177,8 @@ static CURLcode quic_x509_store_setup(struct Curl_cfilter *cf,
static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data) static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data)
{ {
struct cf_quiche_ctx *ctx = cf->ctx; struct cf_quiche_ctx *ctx = cf->ctx;
unsigned char checkip[16];
(void)data;
DEBUGASSERT(!ctx->sslctx); DEBUGASSERT(!ctx->sslctx);
ctx->sslctx = SSL_CTX_new(TLS_method()); ctx->sslctx = SSL_CTX_new(TLS_method());
if(!ctx->sslctx) if(!ctx->sslctx)
@ -199,7 +201,20 @@ static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data)
return CURLE_QUIC_CONNECT_ERROR; return CURLE_QUIC_CONNECT_ERROR;
SSL_set_app_data(ctx->ssl, cf); SSL_set_app_data(ctx->ssl, cf);
SSL_set_tlsext_host_name(ctx->ssl, cf->conn->host.name);
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)) {
failf(data, "Failed set SNI");
SSL_free(ctx->ssl);
ctx->ssl = NULL;
return CURLE_QUIC_CONNECT_ERROR;
}
}
return CURLE_OK; return CURLE_OK;
} }