Skip to content

Commit

Permalink
http: optionally send SSL client certificate
Browse files Browse the repository at this point in the history
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 #3292

Signed-off-by: Pascal Muller <pascalmuller@gmail.com>
  • Loading branch information
pascalmuller authored and dscho committed Sep 24, 2024
1 parent 27e161a commit ed39322
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Documentation/config/http.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,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
Expand Down
8 changes: 8 additions & 0 deletions git-curl-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,12 @@
#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1
#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

#endif
26 changes: 22 additions & 4 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ static int 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 &&
Expand Down Expand Up @@ -449,6 +451,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)
Expand Down Expand Up @@ -1101,13 +1108,24 @@ static CURL *get_curl_handle(void)
}
#endif

if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
http_schannel_check_revoke_mode) {
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend)) {
long ssl_options = 0;
if (http_schannel_check_revoke_mode) {
#ifdef GIT_CURL_HAVE_CURLSSLOPT_NO_REVOKE
curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, http_schannel_check_revoke_mode);
ssl_options |= http_schannel_check_revoke_mode;
#else
warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"));
warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"));
#endif
}

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)
Expand Down

0 comments on commit ed39322

Please sign in to comment.