-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
verify certificates against the SSL backend's default 'capath' #31
Comments
Hi, thanks for the report. I'm not sure I completely understand the issue. Or... do you want to use CAPATH and CAINFO at the sane time? |
This looks like a nice write-up: |
What I actually want is to disable CAINFO and only check the default CAPATH. With PHP's own curl extension, parsing the ~300k certificate store for every request has a significant performance impact, and we usually set CAINFO to a dummy (e.g. expired) CA certificate. |
Hm, okay. As far as I understand the issues presented in above article, it seems that the, let's call it, CAPATH is ultimately an OS thing. So even if we only look at openssl, the "CAPATH" might be different depending on the OS? Do you have any suggestions on how to go forward about this? |
The idea is - and casual testing appears to show that the PHP curl extension works like this - that the compiled in defaults of the SSL backend "just work", i.e. neither the user nor the ext-http should be required to guess which CAPATH might be appropriate. Right now, using the openssl backend, I haven't managed to convince ext-http to use the hashed directories without explicitly setting CAPATH correctly. With PHP curl, I can just set CAINFO to a dummy CA to achieve this. Using the NSS backend on CentOS or RHEL, ext-http already behaves like this, i.e. running a http\Client\Request with $request->setOptions(array('ssl' => array('cainfo' => '..../ssl/dummyCA.pem'))); works (assuming you have populated the sqlite PKI db). With an OpenSSL backend, it throws a "Peer certificate cannot be authenticated" exception instead. |
Okay.
Do you mean that it does not work without setting a dummy
ATM pecl_http's If so, what does Currently, we reset every used curl option before we use a curl handle, because they may be re-used, so "just letting curl alone with its default CAPATH" would not work out that easily... 😞 Thanks! |
Curl + NSS works both if I set a dummy CA, if I set 'cainfo' to a proper CA bundle and if I leave the setting untouched.
It does work, but I don't want to use the CA bundle, I want to use the hashed directory the default CAPATH points to (probably: the default built into openssl, which is used if CAPATH isn't set). This is for performance reasons, as stated in the curl manpage: "Using --capath can allow OpenSSL-powered curl to make SSL-connections much more efficiently).
It correctly identifies the location of the bundle: configure:6600: checking for bundled SSL CA info
The man page for SSL_CTX_load_verify_locations (https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_load_verify_locations.html), which is used internally by curl if CAPATH !=NULL || CAINFO != NULL seems to indicat that just setting the capath to NULL should result in the desired behavior, however, the following doesn't work for me: $request->setSslOptions(array("cainfo" => '.../dummyCA.pem', "capath" => NULL)); |
Doesn't seem so... it says that |
Looks like you're correct. SSL_CTX_load_verify_locations() doesn't make any efforts to set the defaults if any of the parameters is NULL, but it also doesn't destroy the default values, if they were previously set, which appears to be the case initially. As a result, that doesn't help at all if you want to reset the curl handle to a known state and reuse the defaults. |
Yes, if curl was built with either
Exactly :( |
Oookay, actually, I guess I see a possible solution. We should actually only use Looks like a valid bug, after all. |
Would be awesome, if you checked the default_capath branch to see if that works out for you? |
Did you re-phpize and re-configure and make sure that php_http_client_curl.c got re-compiled (make clean, or something)? I get this with a fresh build (2.5.x series, though):
|
I think the
Since |
facepalm, okay, please give ffee4ca a try! Thank you. |
With ffee4ca (+ adjustment in ZVAL_STRING for PHP 7), it configures and builds:
but a small test program that just makes a new requst to https://google.com/, sets options:
and prints the result still fails with "Peer certificate cannot be authenticated with given CA certificates; SSL certificate problem: unable to get local issuer certificate". |
Hmm... what about setting |
Ha, guess what's in curl 7.48 :) |
Hey, I just verified that it's using the hashed capath for me on Debian:
|
I've tried NULL, false, true, '', and finally '/dev/null'. The latter displays invalid (random) characters in the error message:
On Ubuntu 15.10, the same command line never touches the hashed directory:
|
So, did make any progress with this? Did you fetch the latest commits, too? |
I've finally found the time to look closer into this. You patch actually works as well as one could expect. |
Yay, thanks for verifying! |
+ Added http\Client\Curl\User interface for userland event loops + Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS + Added http\Client::setDebug(callable $debug) + Added http\Client\Curl\FEATURES constants and namespace + Added http\Client\Curl\VERSIONS constants and namespace + Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() + http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests + Improved configure checks for default CA bundles + Improved negotiation precision * Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. * Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) * Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) * Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) * Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) * Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) * Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) * Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) * Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) * Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) * Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) * Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) * Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) * Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) Changes from beta1: * Fixed PHP-5.3 compatibility * Fixed recursive calls to the event loop dispatcher Changes from beta2: * Fix bug #73055: crash in http\QueryString (Mike, @rc0r) (CVE-2016-7398) * Fix bug #73185: Buffer overflow in HTTP parse_hostinfo() (Mike, @rc0r) * Fix HTTP/2 version parser for older libcurl versions (Mike)
+ Added http\Client\Curl\User interface for userland event loops + Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS + Added http\Client::setDebug(callable $debug) + Added http\Client\Curl\FEATURES constants and namespace + Added http\Client\Curl\VERSIONS constants and namespace + Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() + http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests + Improved configure checks for default CA bundles + Improved negotiation precision * Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. * Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) * Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) * Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) * Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) * Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) * Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) * Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) * Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) * Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) * Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) * Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) * Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) * Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) Changes from beta1: * Fixed recursive calls to the event loop dispatcher Changes from beta2: + Improved configure checks for IDNA libraries (added --with-http-libicu-dir, --with-http-libidnkit{,2}-dir, --with-http-libidn2-dir) * Fix bug #73055: crash in http\QueryString (Mike, @rc0r) (CVE-2016-7398) * Fix bug #73185: Buffer overflow in HTTP parse_hostinfo() (Mike, @rc0r) * Fix HTTP/2 version parser for older libcurl versions (Mike) * Fix gh-issue #52: Underscores in host names: libidn Failed to parse IDN (Mike, @canavan)
+ Added http\Client\Curl\User interface for userland event loops + Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS + Added http\Client::setDebug(callable $debug) + Added http\Client\Curl\FEATURES constants and namespace + Added http\Client\Curl\VERSIONS constants and namespace + Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() + http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests + Improved configure checks for default CA bundles + Improved negotiation precision * Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. * Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) * Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) * Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) * Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) * Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) * Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) * Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) * Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) * Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) * Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) * Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) * Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) * Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) Changes from beta1: * Fixed PHP-5.3 compatibility * Fixed recursive calls to the event loop dispatcher Changes from beta2: * Fix bug #73055: crash in http\QueryString (Mike, @rc0r) (CVE-2016-7398) * Fix bug #73185: Buffer overflow in HTTP parse_hostinfo() (Mike, @rc0r) (CVE-2016-7961) * Fix HTTP/2 version parser for older libcurl versions (Mike)
+ Added http\Client\Curl\User interface for userland event loops + Added http\Url::IGNORE_ERRORS, http\Url::SILENT_ERRORS and http\Url::STDFLAGS + Added http\Client::setDebug(callable $debug) + Added http\Client\Curl\FEATURES constants and namespace + Added http\Client\Curl\VERSIONS constants and namespace + Added share_cookies and share_ssl (libcurl >= 7.23.0) options to http\Client::configure() + http\Client uses curl_share handles to properly share cookies and SSL/TLS sessions between requests + Improved configure checks for default CA bundles + Improved negotiation precision * Fixed regression introduced by http\Params::PARSE_RFC5987: negotiation using the params parser would receive param keys without the trailing asterisk, stripped by http\Params::PARSE_RFC5987. * Fix gh-issue #50: http\Client::dequeue() within http\Client::setDebug() causes segfault (Mike, Maik Wagner) * Fix gh-issue #47: http\Url: Null pointer deref in sanitize_value() (Mike, @rc0r) * Fix gh-issue #45: HTTP/2 response message parsing broken with libcurl >= 7.49.1 (Mike) * Fix gh-issue #43: Joining query with empty original variable in query (Mike, Sander Backus) * Fix gh-issue #42: fatal error when using punycode in URLs (Mike, Sebastian Thielen) * Fix gh-issue #41: Use curl_version_info_data.features when initializing options (Mike) * Fix gh-issue #40: determinde the SSL backend used by curl at runtime (Mike, @rcanavan) * Fix gh-issue #39: Notice: http\Client::enqueue(): Could not set option proxy_service_name (Mike, @rcanavan) * Fix gh-issue #38: Persistent curl handles: error code not properly reset (Mike, @afflerbach) * Fix gh-issue #36: Unexpected cookies sent if persistent_handle_id is used (Mike, @rcanavan, @afflerbach) * Fix gh-issue #34: allow setting multiple headers with the same name (Mike, @rcanavan) * Fix gh-issue #33: allow setting prodyhost request option to NULL (Mike, @rcanavan) * Fix gh-issue #31: add/improve configure checks for default CA bundle/path (Mike, @rcanavan) Changes from beta1: * Fixed recursive calls to the event loop dispatcher Changes from beta2: + Improved configure checks for IDNA libraries (added --with-http-libicu-dir, --with-http-libidnkit{,2}-dir, --with-http-libidn2-dir) * Fix bug #73055: crash in http\QueryString (Mike, @rc0r) (CVE-2016-7398) * Fix bug #73185: Buffer overflow in HTTP parse_hostinfo() (Mike, @rc0r) (CVE-2016-7961) * Fix HTTP/2 version parser for older libcurl versions (Mike) * Fix gh-issue #52: Underscores in host names: libidn Failed to parse IDN (Mike, @canavan)
By default, ext-http currently does not verify certificates against the 'capath' that is built into the SSL backend used by curl. Therefore, a hashed directory of certificates isn't checked unless the location is explicitly set.
Since the correct value for CURLOPT_CAPATH depends on the type of SSL backend used and its compile-time and run-time configuration, it's difficult to even make a good educated guess which value to set in ['ssl']['capath'].
With the "plain" curl PHP extension, the default CAPATH of the SSL backend is used to verify a peer's SSL certificate, even if CURLOP_CAINFO is set to a non-default file.
The text was updated successfully, but these errors were encountered: