http: implement public key pinning

Add the http.pinnedpubkey configuration option for public key pinning. It allows any string supported by libcurl -- base64(sha256(pubkey)) or filename of the full public key. If cURL does not support pinning (is too old) output a warning to the user. Signed-off-by: Christoph Egger <christoph@christoph-egger.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christoph Egger committed Feb 15, 2016 at 15:04 UTC aeff8a61216bf6e0d663c08c583bc8552fa3c344
2 files changed +23
Documentation/config.txt
+8
@@ -1679,6 +1679,14 @@ http.sslCAPath::
1679 with when fetching or pushing over HTTPS. Can be overridden
1680 by the 'GIT_SSL_CAPATH' environment variable.
1681
1682 +http.pinnedpubkey::
1683 + Public key of the https service. It may either be the filename of
1684 + a PEM or DER encoded public key file or a string starting with
1685 + 'sha256//' followed by the base64 encoded sha256 hash of the
1686 + public key. See also libcurl 'CURLOPT_PINNEDPUBLICKEY'. git will
1687 + exit with an error if this option is set but not supported by
1688 + cURL.
1689 +
1690 http.sslTry::
1691 Attempt to use AUTH SSL/TLS and encrypted data transfers
1692 when connecting via regular FTP protocol. This might be needed
http.c
+15
@@ -57,6 +57,9 @@ static const char *ssl_key;
57 #if LIBCURL_VERSION_NUM >= 0x070908
58 static const char *ssl_capath;
59 #endif
60 +#if LIBCURL_VERSION_NUM >= 0x072c00
61 +static const char *ssl_pinnedkey;
62 +#endif
63 static const char *ssl_cainfo;
64 static long curl_low_speed_limit = -1;
65 static long curl_low_speed_time = -1;
@@ -273,6 +276,14 @@ static int http_options(const char *var, const char *value, void *cb)
276 if (!strcmp("http.useragent", var))
277 return git_config_string(&user_agent, var, value);
278
279 + if (!strcmp("http.pinnedpubkey", var)) {
280 +#if LIBCURL_VERSION_NUM >= 0x072c00
281 + return git_config_pathname(&ssl_pinnedkey, var, value);
282 +#else
283 + warning(_("Public key pinning not supported with cURL < 7.44.0"));
284 + return 0;
285 +#endif
286 + }
287 /* Fall back on the default ones */
288 return git_default_config(var, value, cb);
289 }
@@ -414,6 +425,10 @@ static CURL *get_curl_handle(void)
425 #if LIBCURL_VERSION_NUM >= 0x070908
426 if (ssl_capath != NULL)
427 curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath);
428 +#endif
429 +#if LIBCURL_VERSION_NUM >= 0x072c00
430 + if (ssl_pinnedkey != NULL)
431 + curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
432 #endif
433 if (ssl_cainfo != NULL)
434 curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);