Merge branch 'ce/https-public-key-pinning'
authorJunio C Hamano <gitster@pobox.com>
Wed, 24 Feb 2016 21:25:58 +0000 (13:25 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 24 Feb 2016 21:25:58 +0000 (13:25 -0800)
You can now set http.[<url>.]pinnedpubkey to specify the pinned
public key when building with recent enough versions of libcURL.

* ce/https-public-key-pinning:
http: implement public key pinning

Documentation/config.txt
http.c
index 542cb229c86415aeb338814c2caf4e746d3c33f5..2cd6bdd7d2bc2816c1a9aed1c6a26bbd3285777c 100644 (file)
@@ -1733,6 +1733,14 @@ http.sslCAPath::
        with when fetching or pushing over HTTPS. Can be overridden
        by the 'GIT_SSL_CAPATH' environment variable.
 
+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
+       'sha256//' followed by the base64 encoded sha256 hash of the
+       public key. See also libcurl 'CURLOPT_PINNEDPUBLICKEY'. git will
+       exit with an error if this option is set but not supported by
+       cURL.
+
 http.sslTry::
        Attempt to use AUTH SSL/TLS and encrypted data transfers
        when connecting via regular FTP protocol. This might be needed
diff --git a/http.c b/http.c
index 279b6f2e9a35d69c6ce36416fd00662e4e3511b0..1d5e3bbd11ae0e7dc0e682d3914e07cc13a0ce14 100644 (file)
--- a/http.c
+++ b/http.c
@@ -62,6 +62,9 @@ static const char *ssl_key;
 #if LIBCURL_VERSION_NUM >= 0x070908
 static const char *ssl_capath;
 #endif
+#if LIBCURL_VERSION_NUM >= 0x072c00
+static const char *ssl_pinnedkey;
+#endif
 static const char *ssl_cainfo;
 static long curl_low_speed_limit = -1;
 static long curl_low_speed_time = -1;
@@ -310,6 +313,15 @@ static int http_options(const char *var, const char *value, void *cb)
                return 0;
        }
 
+       if (!strcmp("http.pinnedpubkey", var)) {
+#if LIBCURL_VERSION_NUM >= 0x072c00
+               return git_config_pathname(&ssl_pinnedkey, var, value);
+#else
+               warning(_("Public key pinning not supported with cURL < 7.44.0"));
+               return 0;
+#endif
+       }
+
        /* Fall back on the default ones */
        return git_default_config(var, value, cb);
 }
@@ -512,6 +524,10 @@ static CURL *get_curl_handle(void)
 #if LIBCURL_VERSION_NUM >= 0x070908
        if (ssl_capath != NULL)
                curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath);
+#endif
+#if LIBCURL_VERSION_NUM >= 0x072c00
+       if (ssl_pinnedkey != NULL)
+               curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
 #endif
        if (ssl_cainfo != NULL)
                curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);