http: optionally send SSL client certificate

This adds support for a new http.sslAutoClientCert config value.

In cURL 7.77 or later the schannel backend does not automatically send
client certificates from the Windows Certificate Store anymore.

This config value is only used if http.sslBackend is set to "schannel",
and can be used to opt in to the old behavior and force cURL to send
client certificates.

This fixes https://github.com/git-for-windows/git/issues/3292

Signed-off-by: Pascal Muller <pascalmuller@gmail.com>
This commit is contained in:
Pascal Muller 2021-06-23 21:21:10 +02:00 committed by Johannes Schindelin
parent 993102277a
commit 378c4b16f2
3 changed files with 34 additions and 3 deletions

View File

@ -249,6 +249,11 @@ http.schannelUseSSLCAInfo::
when the `schannel` backend was configured via `http.sslBackend`,
unless `http.schannelUseSSLCAInfo` overrides this behavior.
http.sslAutoClientCert::
As of cURL v7.77.0, the Secure Channel backend won't automatically
send client certificates from the Windows Certificate Store anymore.
To opt in to the old behavior, http.sslAutoClientCert can be set.
http.pinnedPubkey::
Public key of the https service. It may either be the filename of
a PEM or DER encoded public key file or a string starting with

View File

@ -37,6 +37,14 @@
#define GIT_CURL_NEED_TRANSFER_ENCODING_HEADER
#endif
/**
* CURLSSLOPT_AUTO_CLIENT_CERT was added in 7.77.0, released in May
* 2021.
*/
#if LIBCURL_VERSION_NUM >= 0x074d00
#define GIT_CURL_HAVE_CURLSSLOPT_AUTO_CLIENT_CERT
#endif
/**
* CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR were added in 7.85.0,
* released in August 2022.

24
http.c
View File

@ -162,6 +162,8 @@ static long http_schannel_check_revoke_mode =
*/
static int http_schannel_use_ssl_cainfo;
static int http_auto_client_cert;
static int always_auth_proactively(void)
{
return http_proactive_auth != PROACTIVE_AUTH_NONE &&
@ -450,6 +452,11 @@ static int http_options(const char *var, const char *value,
return 0;
}
if (!strcmp("http.sslautoclientcert", var)) {
http_auto_client_cert = git_config_bool(var, value);
return 0;
}
if (!strcmp("http.minsessions", var)) {
min_curl_sessions = git_config_int(var, value, ctx->kvi);
if (min_curl_sessions > 1)
@ -1074,9 +1081,20 @@ static CURL *get_curl_handle(void)
}
#endif
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
http_schannel_check_revoke_mode) {
curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, http_schannel_check_revoke_mode);
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend)) {
long ssl_options = 0;
if (http_schannel_check_revoke_mode) {
ssl_options |= http_schannel_check_revoke_mode;
}
if (http_auto_client_cert) {
#ifdef GIT_CURL_HAVE_CURLSSLOPT_AUTO_CLIENT_CERT
ssl_options |= CURLSSLOPT_AUTO_CLIENT_CERT;
#endif
}
if (ssl_options)
curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, ssl_options);
}
if (http_proactive_auth != PROACTIVE_AUTH_NONE)