curl provides many options for configuring the way it negotiates an SSL
connection (with its default OpenSSL support), including ways to define
the SSL engine used, and parameters to set the format of the key and
certificate used.  Unfortunately, git does not parse some of the
critical ones needed by curl to support PKCS#11.

Add the following git config variables (and direct env-set variables):

* http.sslengine
  A string variable that sets CURLOPT_SSLENGINE on the back end.
  Can be set from environment using GIT_SSL_ENGINE.
* http.sslkeytype
  A string variable, either PEM/DER/ENG, that sets CURLOPT_SSLKEYTYPE.
  Can be set from environment using GIT_SSL_KEYTYPE.
* http.sslcerttype
  A string variable, either PEM/DER/ENG, that sets CURLOPT_SSLCERTTYPE.
  Can be set from environment using GIT_SSL_CERTTYPE.

Parsing these new variables combined with related patches to curl
will allow git to support native authentication with smart cards.

Note: It's difficult to test this without the related curl patches,
which I will be submitting soon.  At the very least, leaving these new
options unset doesn't break anything, and setting them has little
effect without the back-end curl changes needed to 'turn on' PKCS#11.
Any suggestions would be greatly appreciated.

Signed-off-by: Jerry Qassar <jqas...@gmail.com>
---
 Documentation/config.txt | 13 +++++++++++++
 http.c                   | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index c67038b..d155620 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1440,16 +1440,29 @@ http.sslVerify::
        over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
        variable.
 
+http.sslEngine::
+       String specifying the SSL engine to be used by curl.  This can be used 
to
+       specify non-default or dynamically loaded engines.  Can be overridden by
+       the 'GIT_SSL_ENGINE' environment variable.
+
 http.sslCert::
        File containing the SSL certificate when fetching or pushing
        over HTTPS. Can be overridden by the 'GIT_SSL_CERT' environment
        variable.
 
+http.sslCertType::
+       Specifies the format of the certificate to curl as one of (PEM|DER|ENG).
+       Can be overridden by the 'GIT_SSL_CERTTYPE' environment variable.
+
 http.sslKey::
        File containing the SSL private key when fetching or pushing
        over HTTPS. Can be overridden by the 'GIT_SSL_KEY' environment
        variable.
 
+http.sslKeyType::
+       Specifies the format of the private key to curl as one of (PEM|DER|ENG).
+       Can be overridden by the 'GIT_SSL_KEYTYPE' environment variable.
+
 http.sslCertPasswordProtected::
        Enable Git's password prompt for the SSL certificate.  Otherwise
        OpenSSL will prompt the user, possibly many times, if the
diff --git a/http.c b/http.c
index 92aba59..06cb22e 100644
--- a/http.c
+++ b/http.c
@@ -49,6 +49,10 @@ static struct credential http_auth = CREDENTIAL_INIT;
 static int http_proactive_auth;
 static const char *user_agent;
 
+static const char *ssl_keytype;
+static const char *ssl_certtype;
+static const char *ssl_engine;
+
 #if LIBCURL_VERSION_NUM >= 0x071700
 /* Use CURLOPT_KEYPASSWD as is */
 #elif LIBCURL_VERSION_NUM >= 0x070903
@@ -211,6 +215,17 @@ static int http_options(const char *var, const char 
*value, void *cb)
        if (!strcmp("http.useragent", var))
                return git_config_string(&user_agent, var, value);
 
+       /* Adding parsing for curl options relating to engines and */
+       /* key/cert types.  This is necessary if attempting to     */
+       /* specify an external engine (e.g. for smartcards.)       */
+
+       if (!strcmp("http.sslkeytype", var))
+               return git_config_string(&ssl_keytype, var, value);
+       if (!strcmp("http.sslcerttype", var))
+               return git_config_string(&ssl_certtype, var, value);
+       if (!strcmp("http.sslengine", var))
+               return git_config_string(&ssl_engine, var, value);
+
        /* Fall back on the default ones */
        return git_default_config(var, value, cb);
 }
@@ -321,6 +336,22 @@ static CURL *get_curl_handle(void)
                curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
        }
 
+       /* Adding setting of engine-related curl SSL options. */
+       if (ssl_engine != NULL) {
+               curl_easy_setopt(result, CURLOPT_SSLENGINE, ssl_engine);
+
+               /* Within the lifetime of a single git execution, setting
+                * the default does nothing interesting.  When curl properly
+                * duplicates handles, the engine choice will propagate.
+                */
+               /* curl_easy_setopt(result, CURLOPT_SSLENGINE_DEFAULT, 1L); */
+       }
+
+       if (ssl_keytype != NULL)
+               curl_easy_setopt(result, CURLOPT_SSLKEYTYPE, ssl_keytype);
+       if (ssl_certtype != NULL)
+               curl_easy_setopt(result, CURLOPT_SSLCERTTYPE, ssl_certtype);
+
        return result;
 }
 
@@ -405,6 +436,11 @@ void http_init(struct remote *remote, const char *url, int 
proactive_auth)
                        ssl_cert_password_required = 1;
        }
 
+       /* Added environment variables for expanded engine-related options. */
+       set_from_env(&ssl_keytype, "GIT_SSL_KEYTYPE");
+       set_from_env(&ssl_certtype, "GIT_SSL_CERTTYPE");
+       set_from_env(&ssl_engine, "GIT_SSL_ENGINE");
+
 #ifndef NO_CURL_EASY_DUPHANDLE
        curl_default = get_curl_handle();
 #endif
-- 
1.8.2.1.342.gfa7285d.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to