vtls: pass on the right SNI name

The TLS backends convert the host name to SNI name and need to use that.
This involves cutting off any trailing dot and lowercasing.

Co-authored-by: Jay Satiro
Closes #8320
This commit is contained in:
Daniel Stenberg 2022-01-22 23:44:00 +01:00
parent b27ad8e1d3
commit 2218c3a57e
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
13 changed files with 125 additions and 78 deletions

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2019 - 2021, Michael Forney, <mforney@mforney.org> * Copyright (C) 2019 - 2022, Michael Forney, <mforney@mforney.org>
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -465,6 +465,14 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
} }
hostname = NULL; hostname = NULL;
} }
else {
char *snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
hostname = snihost;
}
if(!br_ssl_client_reset(&backend->ctx, hostname, 0)) if(!br_ssl_client_reset(&backend->ctx, hostname, 0))
return CURLE_FAILED_INIT; return CURLE_FAILED_INIT;

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -830,8 +830,13 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */ /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) { if(sni) {
char *snihost = Curl_ssl_snihost(data, sni, NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
result = set_buffer(data, BACKEND->handle, result = set_buffer(data, BACKEND->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE); GSK_SSL_EXTN_SERVERNAME_REQUEST, snihost, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL) if(result == CURLE_UNSUPPORTED_PROTOCOL)
result = CURLE_OK; result = CURLE_OK;
} }

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -542,11 +542,15 @@ gtls_connect_step1(struct Curl_easy *data,
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
#endif #endif
sni && sni) {
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, size_t snilen;
strlen(hostname)) < 0)) char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
infof(data, "WARNING: failed to configure server name indication (SNI) " if(!snihost || gnutls_server_name_set(session, GNUTLS_NAME_DNS, snihost,
"TLS extension"); snilen) < 0) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
}
/* Use default priorities */ /* Use default priorities */
rc = gnutls_set_default_priority(session); rc = gnutls_set_default_priority(session);

View file

@ -561,12 +561,15 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
mbedtls_ssl_conf_own_cert(&backend->config, mbedtls_ssl_conf_own_cert(&backend->config,
&backend->clicert, &backend->pk); &backend->clicert, &backend->pk);
} }
if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) { {
/* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and* char *snihost = Curl_ssl_snihost(data, hostname, NULL);
the name to set in the SNI extension. So even if curl connects to a if(!snihost || mbedtls_ssl_set_hostname(&backend->ssl, snihost)) {
host specified as an IP address, this function must be used. */ /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and
failf(data, "couldn't set hostname in mbedTLS"); the name to set in the SNI extension. So even if curl connects to a
return CURLE_SSL_CONNECT_ERROR; host specified as an IP address, this function must be used. */
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
} }
#ifdef HAS_ALPN #ifdef HAS_ALPN

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -1865,7 +1865,6 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
CURLcode result; CURLcode result;
bool second_layer = FALSE; bool second_layer = FALSE;
SSLVersionRange sslver_supported; SSLVersionRange sslver_supported;
SSLVersionRange sslver = { SSLVersionRange sslver = {
SSL_LIBRARY_VERSION_TLS_1_0, /* min */ SSL_LIBRARY_VERSION_TLS_1_0, /* min */
#ifdef SSL_LIBRARY_VERSION_TLS_1_3 #ifdef SSL_LIBRARY_VERSION_TLS_1_3
@ -1878,6 +1877,11 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
SSL_LIBRARY_VERSION_TLS_1_0 SSL_LIBRARY_VERSION_TLS_1_0
#endif #endif
}; };
char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
backend->data = data; backend->data = data;
@ -2140,11 +2144,11 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
goto error; goto error;
/* propagate hostname to the TLS layer */ /* propagate hostname to the TLS layer */
if(SSL_SetURL(backend->handle, SSL_HOST_NAME()) != SECSuccess) if(SSL_SetURL(backend->handle, snihost) != SECSuccess)
goto error; goto error;
/* prevent NSS from re-using the session for a different hostname */ /* prevent NSS from re-using the session for a different hostname */
if(SSL_SetSockPeerID(backend->handle, SSL_HOST_NAME()) != SECSuccess) if(SSL_SetSockPeerID(backend->handle, snihost) != SECSuccess)
goto error; goto error;
return CURLE_OK; return CURLE_OK;

View file

@ -3244,21 +3244,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
#endif #endif
sni) { sni) {
size_t nlen = strlen(hostname); char *snihost = Curl_ssl_snihost(data, hostname, NULL);
if((long)nlen >= data->set.buffer_size) if(!snihost || !SSL_set_tlsext_host_name(backend->handle, snihost)) {
/* this is seriously messed up */ failf(data, "Failed set SNI");
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
}
/* RFC 6066 section 3 says the SNI field is case insensitive, but browsers
send the data lowercase and subsequently there are now numerous servers
out there that don't work unless the name is lowercased */
Curl_strntolower(data->state.buffer, hostname, nlen);
data->state.buffer[nlen] = 0;
DEBUGASSERT(nlen);
DEBUGASSERT(data->state.buffer[nlen-1] != '.');
if(!SSL_set_tlsext_host_name(backend->handle, data->state.buffer))
infof(data, "WARNING: failed to configure server name indication (SNI) "
"TLS extension");
} }
#endif #endif

View file

@ -368,7 +368,14 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
backend->config = rustls_client_config_builder_build(config_builder); backend->config = rustls_client_config_builder_build(config_builder);
DEBUGASSERT(rconn == NULL); DEBUGASSERT(rconn == NULL);
result = rustls_client_connection_new(backend->config, hostname, &rconn); {
char *snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
result = rustls_client_connection_new(backend->config, snihost, &rconn);
}
if(result != RUSTLS_RESULT_OK) { if(result != RUSTLS_RESULT_OK) {
rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen); rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen);
failf(data, "rustls_client_connection_new: %.*s", errorlen, errorbuf); failf(data, "rustls_client_connection_new: %.*s", errorlen, errorbuf);

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
* *
@ -765,7 +765,6 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
struct in6_addr addr6; struct in6_addr addr6;
#endif #endif
TCHAR *host_name;
CURLcode result; CURLcode result;
char * const hostname = SSL_HOST_NAME(); char * const hostname = SSL_HOST_NAME();
struct ssl_backend_data *backend = connssl->backend; struct ssl_backend_data *backend = connssl->backend;
@ -846,10 +845,21 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
} }
if(!backend->cred) { if(!backend->cred) {
char *snihost;
result = schannel_acquire_credential_handle(data, conn, sockindex); result = schannel_acquire_credential_handle(data, conn, sockindex);
if(result != CURLE_OK) { if(result != CURLE_OK) {
return result; return result;
} }
/* A hostname associated with the credential is needed by
InitializeSecurityContext for SNI and other reasons. */
snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
backend->cred->sni_hostname = curlx_convert_UTF8_to_tchar(snihost);
if(!backend->cred->sni_hostname)
return CURLE_OUT_OF_MEMORY;
} }
/* Warn if SNI is disabled due to use of an IP address */ /* Warn if SNI is disabled due to use of an IP address */
@ -936,10 +946,6 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
/* Schannel InitializeSecurityContext: /* Schannel InitializeSecurityContext:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
@ -948,13 +954,12 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
us problems with inbuf regardless. https://github.com/curl/curl/issues/983 us problems with inbuf regardless. https://github.com/curl/curl/issues/983
*/ */
sspi_status = s_pSecFn->InitializeSecurityContext( sspi_status = s_pSecFn->InitializeSecurityContext(
&backend->cred->cred_handle, NULL, host_name, backend->req_flags, 0, 0, &backend->cred->cred_handle, NULL, backend->cred->sni_hostname,
backend->req_flags, 0, 0,
(backend->use_alpn ? &inbuf_desc : NULL), (backend->use_alpn ? &inbuf_desc : NULL),
0, &backend->ctxt->ctxt_handle, 0, &backend->ctxt->ctxt_handle,
&outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp); &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
if(sspi_status != SEC_I_CONTINUE_NEEDED) { if(sspi_status != SEC_I_CONTINUE_NEEDED) {
char buffer[STRERROR_LEN]; char buffer[STRERROR_LEN];
Curl_safefree(backend->ctxt); Curl_safefree(backend->ctxt);
@ -1027,16 +1032,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
SECURITY_STATUS sspi_status = SEC_E_OK; SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result; CURLcode result;
bool doread; bool doread;
char * const hostname = SSL_HOST_NAME();
const char *pubkey_ptr; const char *pubkey_ptr;
struct ssl_backend_data *backend = connssl->backend; struct ssl_backend_data *backend = connssl->backend;
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 2/3)",
hostname, conn->remote_port));
if(!backend->cred || !backend->ctxt) if(!backend->cred || !backend->ctxt)
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
@ -1083,7 +1083,6 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
} }
for(;;) { for(;;) {
TCHAR *host_name;
if(doread) { if(doread) {
/* read encrypted handshake data from socket */ /* read encrypted handshake data from socket */
result = Curl_read_plain(conn->sock[sockindex], result = Curl_read_plain(conn->sock[sockindex],
@ -1136,17 +1135,12 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
memcpy(inbuf[0].pvBuffer, backend->encdata_buffer, memcpy(inbuf[0].pvBuffer, backend->encdata_buffer,
backend->encdata_offset); backend->encdata_offset);
host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
sspi_status = s_pSecFn->InitializeSecurityContext( sspi_status = s_pSecFn->InitializeSecurityContext(
&backend->cred->cred_handle, &backend->ctxt->ctxt_handle, &backend->cred->cred_handle, &backend->ctxt->ctxt_handle,
host_name, backend->req_flags, 0, 0, &inbuf_desc, 0, NULL, backend->cred->sni_hostname, backend->req_flags,
0, 0, &inbuf_desc, 0, NULL,
&outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp); &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
/* free buffer for received handshake data */ /* free buffer for received handshake data */
Curl_safefree(inbuf[0].pvBuffer); Curl_safefree(inbuf[0].pvBuffer);
@ -2138,6 +2132,7 @@ static void schannel_session_free(void *ptr)
cred->refcount--; cred->refcount--;
if(cred->refcount == 0) { if(cred->refcount == 0) {
s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
curlx_unicodefree(cred->sni_hostname);
Curl_safefree(cred); Curl_safefree(cred);
} }
} }
@ -2170,7 +2165,6 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
SecBuffer outbuf; SecBuffer outbuf;
SecBufferDesc outbuf_desc; SecBufferDesc outbuf_desc;
CURLcode result; CURLcode result;
TCHAR *host_name;
DWORD dwshut = SCHANNEL_SHUTDOWN; DWORD dwshut = SCHANNEL_SHUTDOWN;
InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut)); InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
@ -2185,10 +2179,6 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
} }
host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
/* setup output buffer */ /* setup output buffer */
InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, &outbuf, 1); InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
@ -2196,7 +2186,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
sspi_status = s_pSecFn->InitializeSecurityContext( sspi_status = s_pSecFn->InitializeSecurityContext(
&backend->cred->cred_handle, &backend->cred->cred_handle,
&backend->ctxt->ctxt_handle, &backend->ctxt->ctxt_handle,
host_name, backend->cred->sni_hostname,
backend->req_flags, backend->req_flags,
0, 0,
0, 0,
@ -2207,8 +2197,6 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
&backend->ret_flags, &backend->ret_flags,
&backend->ctxt->time_stamp); &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
/* send close message which is in output buffer */ /* send close message which is in output buffer */
ssize_t written; ssize_t written;

View file

@ -8,7 +8,7 @@
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al. * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -76,6 +76,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
struct Curl_schannel_cred { struct Curl_schannel_cred {
CredHandle cred_handle; CredHandle cred_handle;
TimeStamp time_stamp; TimeStamp time_stamp;
TCHAR *sni_hostname;
int refcount; int refcount;
}; };

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>. * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
@ -2028,8 +2028,13 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
* Both hostname check and SNI require SSLSetPeerDomainName(). * Both hostname check and SNI require SSLSetPeerDomainName().
* Also: the verifyhost setting influences SNI usage */ * Also: the verifyhost setting influences SNI usage */
if(conn->ssl_config.verifyhost) { if(conn->ssl_config.verifyhost) {
err = SSLSetPeerDomainName(backend->ssl_ctx, hostname, size_t snilen;
strlen(hostname)); char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
err = SSLSetPeerDomainName(backend->ssl_ctx, snihost, snilen);
if(err != noErr) { if(err != noErr) {
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d", infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",

View file

@ -871,6 +871,32 @@ CURLcode Curl_ssl_random(struct Curl_easy *data,
return Curl_ssl->random(data, entropy, length); return Curl_ssl->random(data, entropy, length);
} }
/*
* Curl_ssl_snihost() converts the input host name to a suitable SNI name put
* in data->state.buffer. Returns a pointer to the name (or NULL if a problem)
* and stores the new length in 'olen'.
*
* SNI fields must not have any trailing dot and while RFC 6066 section 3 says
* the SNI field is case insensitive, browsers always send the data lowercase
* and subsequently there are numerous servers out there that don't work
* unless the name is lowercased.
*/
char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen)
{
size_t len = strlen(host);
if(len && (host[len-1] == '.'))
len--;
if((long)len >= data->set.buffer_size)
return NULL;
Curl_strntolower(data->state.buffer, host, len);
data->state.buffer[len] = 0;
if(olen)
*olen = len;
return data->state.buffer;
}
/* /*
* Public key pem to der conversion * Public key pem to der conversion
*/ */

View file

@ -172,6 +172,7 @@ bool Curl_ssl_tls13_ciphersuites(void);
data->set.str[STRING_SSL_PINNEDPUBLICKEY] data->set.str[STRING_SSL_PINNEDPUBLICKEY]
#endif #endif
char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen);
bool Curl_ssl_config_matches(struct ssl_primary_config *data, bool Curl_ssl_config_matches(struct ssl_primary_config *data,
struct ssl_primary_config *needle); struct ssl_primary_config *needle);
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,

View file

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -462,12 +462,17 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if((hostname_len < USHRT_MAX) && if((hostname_len < USHRT_MAX) &&
(0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
(0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) && (0 == Curl_inet_pton(AF_INET6, hostname, &addr6))
#endif #endif
(wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname, ) {
(unsigned short)hostname_len) != 1)) { size_t snilen;
infof(data, "WARNING: failed to configure server name indication (SNI) " char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
"TLS extension"); if(!snihost ||
wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, snihost,
(unsigned short)snilen) != 1) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
}
} }
} }
#endif #endif
@ -590,7 +595,6 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
int ret = -1; int ret = -1;
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend; struct ssl_backend_data *backend = connssl->backend;
const char * const hostname = SSL_HOST_NAME();
const char * const dispname = SSL_HOST_DISPNAME(); const char * const dispname = SSL_HOST_DISPNAME();
const char * const pinnedpubkey = SSL_PINNED_PUB_KEY(); const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
@ -601,9 +605,10 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* Enable RFC2818 checks */ /* Enable RFC2818 checks */
if(SSL_CONN_CONFIG(verifyhost)) { if(SSL_CONN_CONFIG(verifyhost)) {
ret = wolfSSL_check_domain_name(backend->handle, hostname); char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
if(ret == SSL_FAILURE) if(!snihost ||
return CURLE_OUT_OF_MEMORY; (wolfSSL_check_domain_name(backend->handle, snihost) == SSL_FAILURE))
return CURLE_SSL_CONNECT_ERROR;
} }
ret = SSL_connect(backend->handle); ret = SSL_connect(backend->handle);