Skip to content
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

cURL can't verify ssl certificates (possibly only on Yosemite) #819

Closed
jonnybarnes opened this issue Sep 9, 2014 · 27 comments
Closed

cURL can't verify ssl certificates (possibly only on Yosemite) #819

jonnybarnes opened this issue Sep 9, 2014 · 27 comments

Comments

@jonnybarnes
Copy link

I'm running Yosemite beta 2, I have PHP-5.6 installed via homebrew compiled against homebrew-curl and homebrew-openssl. Guzzle can't verify SSL certs. For example:

$client = new \GuzzleHttp\Client();
$response = $client->get('https://google.com');
return $response;

results in a RequestException with error message cURL error 51: SSL: certificate verification failed (result: 5)

@jonnybarnes
Copy link
Author

This is definitely a Yosemite issue. I can replicate the error with curl --cacert /path/to/cacert.pem https://google.com. However on Yosemite curl https://google.com works.

I first noticed this on a simpler library that I could easily find the cURL code. Commenting out the lines that set a specific cacert file did the trick. I imagine that would also work for Guzzle on Yosemite but I'm not sure how do that.

@mtdowling
Copy link
Member

if /path/to/cacert.pem referencing the budled cacert in Guzzle?

@jonnybarnes
Copy link
Author

Confirmation curl fails with Guzzle's cert:

jonny@Jonathans-MacBook:~|⇒  curl --cacert /Users/jonny/git/webmentions-parser/vendor/guzzlehttp/guzzle/src/cacert.pem https://google.com
curl: (51) SSL: certificate verification failed (result: 5)

As I said its an error with Yosemite. The bug was introduced in cURL 7.37.1. As far as I can tell, the only way to "fix" this is have your code realise its running in Yosemite and then not specify a cacert when running curl_exec. I don't know how to do that.

Fortunately my live sites are running on a Linux VPS so aren't affected by this bug.

See here for upstream ref: http://curl.haxx.se/mail/tracker-2014-08/0007.html

@mtdowling
Copy link
Member

If you set the "verify" request option to true, cURL will use the CA cert bundle provided on the system. Maybe that will fix this for you? By the way, the next major version will use the system CA cert bundle by default and will no longer bundle a CA bundle.

@mtdowling
Copy link
Member

What happens when you set "verify" to true? If you have brew installed, can you try setting verify to /usr/local/etc/openssl/cert.pem? As I understand it, that's the bundle that's extracted from your keychain when homebrew is installed.

@jonnybarnes
Copy link
Author

Neither $client = new \GuzzleHttp\Client(['verify' => true]); nor $client = new \GuzzleHttp\Client(['verify' => '/usr/local/etc/openssl/cert.pem']); fix the issue.

To absolutely prove its a cacert issue this native cURL code works:

$ch = curl_init();
$options = array(
    CURLOPT_URL => 'https://google.com',
    CURLOPT_HEADER => true,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
var_dump($response);
curl_close($ch);

@jonnybarnes
Copy link
Author

OK, misread the docs. This works:

$client = new \GuzzleHttp\Client(['defaults' => ['verify' => true]]);

However, whilst my PHP installation is certainly compiled against both brew installed cURL and brew installed OpenSSL, setting verify to /usr/local/etc/openssl/cert.pem fails with the original error message.

@mtdowling
Copy link
Member

Very strange. It looks like the cURL issue is marked as pending-invalid. If this new breaking change behavior is not cURL's fault, whose is it? Not being able to provide a CA bundle that works on Linux to OS X seems like a pretty big problem.

@jonnybarnes
Copy link
Author

OK, I've got the original code working, i.e.

$client = new \GuzzleHttp\Client();
$response = $client->get('https://google.com');
return $response;

In order to get this working I re-compiled cURL in homebrew with the flag --with-openssl. This makes cURL use brew installed OpenSSL instead of Apple's darwinssl. Guzzle now works. The only issue now is simply typing curl https://google.com it complains about not being able to verify the certificate, i.e. I now need to pass the --cacert flag. But I think I can set a shell variable for this purpose.

I think I'll open an issue with Homebrew to verify this.

@jonnybarnes
Copy link
Author

I think you can close this issue now. The latest public beta of Yosemite was released recently and I think its fixed the issue. The following now works:

curl --cacert /Users/jonny/git/webmentions-parser/vendor/guzzlehttp/guzzle/src/cacert.pem https://google.com

So presumably people using Guzzle without messing around with homebrew's cURL like I have won't get any errors.

Though it'd be nice if someone could confirm.

@mtdowling
Copy link
Member

Glad to hear it's working now. I don't have Yosemite so I can't confirm. I'll close this, but if someone still finds an issue, they can feel free to reopen the issue.

@pacagit
Copy link

pacagit commented Oct 20, 2014

This issues isn't fixed in the current Yosemite distribution...

@mtdowling
Copy link
Member

Which version of guzzle are you using? What's your error message?

On Oct 20, 2014, at 4:02 AM, pacagit notifications@github.com wrote:

This issues isn't fixed in the current Yosemite distribution...


Reply to this email directly or view it on GitHub.

@pacagit
Copy link

pacagit commented Oct 20, 2014

Hi,
yosemite, php 5.5, and guzzlehttp/guzzle": "~5.0"
When i try to login to linkedin/google by oauth i have the error "SSLRead() return error -9806" :s

@mtdowling
Copy link
Member

Guzzle 5 uses the default system certificates when run using a cURL RingPHP handler. Try sending a normal curl request from the command line using, say your root user to see if this is a user-specific or environment specific issue. If the error persists, then you can use a custom CA bundle for all requests with a Guzzle client using the following:

$client = new GuzzleHttp\Client([
    'defaults' => [
        "verify" => "/path/to/my/ca-bundle.crt"
    ]
]);

A maintained CA bundle can be found here: https://github.com/bagder/ca-bundle (though you need to make a decision on if you trust this bundle yourself).

@alvarow
Copy link

alvarow commented Nov 20, 2014

For what it's worth http://curl.haxx.se/docs/caextract.html

@BenjaminNolan
Copy link

Do either of those include Entrust's G2 certificate? Between that and bloody Google forcing everything to require reissuing, I'm seeing SSL errors left, right, and centre. >.<

@hookdump
Copy link

So, has anyone figured out how to solve this?

@mtdowling
Copy link
Member

@hookdump What isn't working for you? Did you see #819 (comment)?

@jonnybarnes
Copy link
Author

@hookdump as @mtdowling said, this should be working now? If you use homebrew make sure that the curl command points to the system version. You can check with the output from which curl.

@Synchro
Copy link

Synchro commented Apr 19, 2016

I was getting this error 60 with PHP 5.6.20 on 10.11.4 with guzzle 6.2.0, tracked it down to my libcurl (7.48 from homebrew) being compiled with libressl. I recompiled using the default openssl and the problem went away. Seems likely that it's because of this bug.

@ice6
Copy link

ice6 commented May 2, 2016

although this issue was closed, but I hope my answer can help the later googlers.
use this command to check the Certificate chain
openssl s_client -host {the-site-with-tls-problem} -port 443
then check whether the issuer's Root Certificates exist in your system, if not, add the Root Certificate to your own system at the risk of yourself :)

for example, a common missed Root Certificates is Equifax Secure Certificate Authority.

@rickrvo
Copy link

rickrvo commented Sep 26, 2016

check your ~/.gitconfig file
I fixed my problem by temporarily removing the lines mentioning sslCAInfo and sslVerify.

then don't forget to add them later case the certificate is one that you are using for something else.

@a-ast
Copy link

a-ast commented Nov 13, 2016

OSX EL Capitan (10.11.1)
PHP: 5.6.27
Guzzle: 6.2.2

I have the same issue:
Works: curl https://google.com
Fails: curl --cacert /usr/local/etc/openssl/cert.pem https://google.com
with error

curl: (51) SSL: certificate verification failed (result: 5)

Tried and didn't work:

  1. $client = new Client(['defaults' => ['verify' => true]]);
  2. $client = new Client(['defaults' => ['verify' => false]]);
  3. $client = new Client(['defaults' => ['verify' => '/usr/local/etc/openssl/cert.pem']]);
  4. $client = new Client(['defaults' => ['verify' => {cert from http://curl.haxx.se/docs/caextract.html}]]);
  5. Latest curl installed with homebrew also fails

@Guillaumez
Copy link

Updating PHP did the thing

@mirko77
Copy link

mirko77 commented Apr 26, 2017

@a-ast I have the same problem, did you manage to fix it?

@mathiasconradt
Copy link

@Guillaumez From which php version to which did you update?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests