Re: [PATCH v4] http: add http.sslVerifyStatus to check stapled OCSP responses

Junio C Hamano <[email protected]>
Newsgroups org.kernel.vger.git
Message-ID <[email protected]>
graysongordon-gl <[email protected]> writes:

> Verified: t5551 over plain http and t5559 over https both pass all 61
> tests, with the four new ones skipping on the former and running on the
> latter.
>  Documentation/config/http.adoc | 17 +++++++++++++++++
>  http.c                         | 10 ++++++++++
>  t/t5551-http-fetch-smart.sh    | 29 +++++++++++++++++++++++++++++
>  3 files changed, 56 insertions(+)

OK, instead of adding a new test script that weighs 72-line we are
testing the feature with 29-line addition, which sounds like a good
economy ;-).

The code changes and the documentation haven't changed since the
previous round, both looking good.

Will replace.  Thanks.

> diff --git a/Documentation/config/http.adoc b/Documentation/config/http.adoc
> index 792a71b413..40b849bf7f 100644
> --- a/Documentation/config/http.adoc
> +++ b/Documentation/config/http.adoc
> @@ -196,6 +196,23 @@ http.sslVerify::
>  	over HTTPS. Defaults to true. Can be overridden by the
>  	`GIT_SSL_NO_VERIFY` environment variable.
>  
> +http.sslVerifyStatus::
> +	Whether to check the revocation status of the server
> +	certificate using the stapled OCSP response supplied during
> +	the TLS handshake ("OCSP stapling"). Defaults to false.
> ++
> +This is fail-closed: if the server staples no response, verification
> +fails. Set it per remote, e.g.
> +`http.https://example.com/.sslVerifyStatus`, rather than globally.
> ++
> +What it changes depends on the TLS backend libcurl was built against.
> +An OpenSSL-linked build ignores a stapled response unless this is set.
> +A GnuTLS-linked build consults the staple during ordinary certificate
> +verification, so it already rejects a revoked certificate under
> +`http.sslVerify` alone, and setting this to `false` does not disable
> +that. Where a backend cannot check the staple at all, git fails with an
> +error rather than continuing unchecked.
> +
>  http.sslCert::
>  	File containing the SSL certificate when fetching or pushing
>  	over HTTPS. Can be overridden by the `GIT_SSL_CERT` environment
> diff --git a/http.c b/http.c
> index caccf2108e..94f8dd817a 100644
> --- a/http.c
> +++ b/http.c
> @@ -44,6 +44,7 @@ static CURL *curl_default;
>  char curl_errorstr[CURL_ERROR_SIZE];
>  
>  static int curl_ssl_verify = -1;
> +static int curl_ssl_verify_status;
>  static int curl_ssl_try;
>  static char *curl_http_version;
>  static char *ssl_cert;
> @@ -400,6 +401,10 @@ static int http_options(const char *var, const char *value,
>  		curl_ssl_verify = git_config_bool(var, value);
>  		return 0;
>  	}
> +	if (!strcmp("http.sslverifystatus", var)) {
> +		curl_ssl_verify_status = git_config_bool(var, value);
> +		return 0;
> +	}
>  	if (!strcmp("http.sslcipherlist", var))
>  		return git_config_string(&ssl_cipherlist, var, value);
>  	if (!strcmp("http.sslversion", var))
> @@ -1133,6 +1138,11 @@ static CURL *get_curl_handle(void)
>  		curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2L);
>  	}
>  
> +	if (curl_ssl_verify_status &&
> +	    curl_easy_setopt(result, CURLOPT_SSL_VERIFYSTATUS, 1L) != CURLE_OK)
> +		die(_("http.sslVerifyStatus is set, but the TLS backend of "
> +		      "this libcurl cannot verify certificate status"));
> +
>      if (curl_http_version) {
>  		long opt;
>  		if (!get_curl_http_version_opt(curl_http_version, &opt)) {
> diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
> index 805bec025c..c11e96c1ac 100755
> --- a/t/t5551-http-fetch-smart.sh
> +++ b/t/t5551-http-fetch-smart.sh
> @@ -680,6 +680,35 @@ test_expect_success 'passing hostname resolution information works' '
>  	git -c "http.curloptResolve=$BOGUS_HOST:$LIB_HTTPD_PORT:127.0.0.1" ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null
>  '
>  
> +test_lazy_prereq SSL_VERIFYSTATUS '
> +	test "$HTTPD_PROTO" = "https" &&
> +	test_might_fail git -c http.sslVerifyStatus=true \
> +		ls-remote "$HTTPD_URL/smart/repo.git" 2>err &&
> +	! grep "cannot verify certificate status" err
> +'
> +
> +test_expect_success SSL_VERIFYSTATUS 'http.sslVerifyStatus=true fails without a staple' '
> +	test_must_fail git -c http.sslVerifyStatus=true \
> +		ls-remote "$HTTPD_URL/smart/repo.git"
> +'
> +
> +test_expect_success SSL_VERIFYSTATUS 'http.sslVerifyStatus=false is a no-op' '
> +	git -c http.sslVerifyStatus=false \
> +		ls-remote "$HTTPD_URL/smart/repo.git" >actual &&
> +	test_line_count -gt 0 actual
> +'
> +
> +test_expect_success SSL_VERIFYSTATUS 'per-URL sslVerifyStatus applies to a matching URL' '
> +	test_must_fail git -c "http.$HTTPD_URL/.sslVerifyStatus=true" \
> +		ls-remote "$HTTPD_URL/smart/repo.git"
> +'
> +
> +test_expect_success SSL_VERIFYSTATUS 'per-URL sslVerifyStatus is not applied to other URLs' '
> +	git -c "http.https://example.com/.sslVerifyStatus=true" \
> +		ls-remote "$HTTPD_URL/smart/repo.git" >actual &&
> +	test_line_count -gt 0 actual
> +'
> +
>  # here user%40host is the URL-encoded version of user@host,
>  # which is our intentionally-odd username to catch parsing errors
>  url_user=$HTTPD_URL_USER/auth/smart/repo.git
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.