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 <jqassar@xxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html