CURL PHP SSL - Can't check server side, but not always

I ran into some problems using Mandrill PHP API

SSL certificate problem: unable to get local issuer certificate

      

I am posting online about setting up a cacarts file for cURL. So I have the current cert extract from http://curl.haxx.se/docs/caextract.html and also the configured (VALID) path for this file inPHP.ini

curl.cainfo=some\local\path\\certs\cacert.pem

      

Now I am testing multiple HTTPS sites (test src here )

$this->nxs_cURLTest("https://mandrillapp.com/api/1.0/users/ping.json", "TestApiCALL", "Mandrill API CERT");
$this->nxs_cURLTest("https://www.google.com/intl/en/contact/", "HTTPS to Google", "Mountain View, CA");
$this->nxs_cURLTest("http://www.google.com/intl/en/contact/", "HTTP to Google", "Mountain View, CA");
$this->nxs_cURLTest("https://www.facebook.com/", "HTTPS to Facebook", 'id="facebook"');
$this->nxs_cURLTest("https://www.linkedin.com/", "HTTPS to LinkedIn", 'link rel="canonical" href="https://www.linkedin.com/"');
$this->nxs_cURLTest("https://twitter.com/", "HTTPS to Twitter", 'link rel="canonical" href="https://twitter.com/"');
$this->nxs_cURLTest("https://www.pinterest.com/", "HTTPS to Pinterest", 'content="Pinterest"');
$this->nxs_cURLTest("https://www.tumblr.com/", "HTTPS to Tumblr", 'content="Tumblr"');

      

and got inconsistent results like:

Testing ... https://mandrillapp.com/api/1.0/users/ping.json - https://mandrillapp.com/api/1.0/users/ping.json
....TestApiCALL - Problem

SSL certificate problem: unable to get local issuer certificate
Array
(
    [url] => https://mandrillapp.com/api/1.0/users/ping.json
    [content_type] => 
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.14
    [namelookup_time] => 0
    [connect_time] => 0.062
    [pretransfer_time] => 0
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => -1
    [starttransfer_time] => 0
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [primary_ip] => 54.195.231.78
    [primary_port] => 443
    [local_ip] => 192.168.2.142
    [local_port] => 63719
    [redirect_url] => 
)

There is a problem with cURL. You need to contact your server admin or hosting provider.Testing ... https://www.google.com/intl/en/contact/ - https://www.google.com/intl/en/contact/
....HTTPS to Google - OK
Testing ... http://www.google.com/intl/en/contact/ - http://www.google.com/intl/en/contact/
....HTTP to Google - OK
Testing ... https://www.facebook.com/ - https://www.facebook.com/
....HTTPS to Facebook - OK
Testing ... https://www.linkedin.com/ - https://www.linkedin.com/
....HTTPS to LinkedIn - OK
Testing ... https://twitter.com/ - https://twitter.com/
....HTTPS to Twitter - OK
Testing ... https://www.pinterest.com/ - https://www.pinterest.com/
....HTTPS to Pinterest - Problem

SSL certificate problem: unable to get local issuer certificate
Array
(
    [url] => https://www.pinterest.com/
    [content_type] => 
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.078
    [namelookup_time] => 0
    [connect_time] => 0.016
    [pretransfer_time] => 0
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => -1
    [starttransfer_time] => 0
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [primary_ip] => 23.65.117.124
    [primary_port] => 443
    [local_ip] => 192.168.2.142
    [local_port] => 63726
    [redirect_url] => 
)

There is a problem with cURL. You need to contact your server admin or hosting provider.Testing ... https://www.tumblr.com/ - https://www.tumblr.com/
....HTTPS to Tumblr - OK

      

As you can see, in general config SSL works, but for some reason for 2 calls

I got the same error. The above links open just in the browser and their certificates with CA targets are valid. What could be the reason here?

EDIT:

I spent about 6 hours trying to fix this and find a clue about what is going on about 2 minutes after posting the question on SO. So I read again the information on http://curl.haxx.se/docs/caextract.html about the excerpts provided. That I looked in the eyes (now, but not 100 times, I've read this before)

Remote RSA-1024

Around the beginning of September 2014, Mozilla removed the trust bits from certificates in its CA bundle that still use RSA 1024 key bits. This can make the TLS libraries difficult to validate some sites if the corresponding library does not properly support "path discovery" as in RFC 4158. (This includes OpenSSL and GnuTLS.)

The last CA bundle we converted before this cleanup: the older ca-bundle from github.

So I took a shot and a tired budle from "to cleanup" - all tests are going through now! So another question is about my machine's legacy software like OpenSSL, PHP, cURL, etc., or is it that sites that fail on tests are in the legacy certificate format as per RFC 4158 and what is causing the problem?

+3


source to share


1 answer


So, one more question: is it about my machine's legacy software like OpenSSL, PHP, cURL, etc., or is it that sites that failed in tests had an outdated RFC-compliant certificate format 4158 and what is causing the problem?

Probably none of them. Remote certificates where the old Root-CA only has a 1024-bit key. These certificates are somehow replaced with new certificates, but not in the same place, that is, if you often have several possible trust paths:

host-cert -> intermediate.1 -> 2048bit intermediate.2 -> 1024bit root-CA
host-cert -> intermediate.1 -> 2048bit new root

      

The public key 2048bit new root

is the same as one of the 2048bit intermediate.2

, so the signature for intermediate.1

will still match, so chain validation will succeed. But while most TLS stacks try to find the best chain, OpenSSL insists on the longest chain. This means that the server is sending the chain

host-cert -> intermediate.1 -> 2048bit intermediate.2

      



then OpenSSL will insist on discovering the root-CA subscription intermediate.2

even if it is signed by the root-CA intermediate.1

(i.e. 2048bit new root

). If the old one is 1024bit root-CA

no longer in the trust store, validation will not complete. If instead the server only sends

host-cert -> intermediate.1

      

then the check will be done with 2048bit new root

. But many servers will still send a longer chain to maintain compatibility with older clients that don't 2048bit new root

.

Everything is very ugly and the bug was reported in 2012 and again in 2015 . OpenSSL 1.0.2 (freshly released) has at least an option X509_V_FLAG_TRUSTED_FIRST

to work around this issue, and there are changes in OpenSSL git that seem to fix the issue, but it's unclear if they get each backported to 1.0.2 or below :(

Now, you're better off just storing the old 1024-bit certificates in the trust store.

+1


source







All Articles