Building notes, projects, and occasional rants

GitHub, CA errors and old curl's

A couple weeks back I noticed someone on Twitter having problems cloning git repos from GitHub using HTTPS. I didn't pay attention to it because I usually use git: protocol - nothing against HTTP, just habit.

But today, on a Mac OS X 10.5.8 system, I noticed something similar:

$ curl -LO
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   185  100   185    0     0    301      0 --:--:-- --:--:-- --:--:--   301
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here:

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). The default
 bundle is named curl-ca-bundle.crt; you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

Now, you can work around it quickly if you add --insecure to that command line, but that feels dirty.

I checked on my other Mac, running 10.6.6, and I had no problems. The curl version in Leopard is just too old, and lacks some of the new certification authorities:

### 10.5.8
$ curl --version 
curl 7.16.4 (i386-apple-darwin9.0) libcurl/7.16.4 OpenSSL/0.9.7l zlib/1.2.3

### 10.6.6
$ curl --version 
curl 7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3

If you check curl SSL certs documentation you'll see that, yes 7.16 is very old and until 7.18.0, the bundled CA file is "severely outdated".

The solution is to update the bundled CA file. First we need to find it and curl-config --ca is your friend:

$ curl-config --ca

I though "I'll just copy the file from 10.6.6..." and be done with it, but no such file is present on my Snow Leopard. I assume that curl uses the system keychain in 10.6, but I don't know for sure.

So we do it the hard way. I'm just interested on accessing GitHub without problems so I checked the CA GitHub uses and downloaded the CA chain from them: you'll need both the "DigiCert High Assurance EV Root CA" and the "DigiCert High Assurance EV CA-1".

Put those file in a directory, open a terminal to it and type:

cat /usr/share/curl/curl-ca-bundle.crt \
    DigiCertHighAssuranceEVRootCA.crt \
    DigiCertHighAssunceEVCA-1.crt \
    >> curl-ca-bundle-new.crt

To test this new CA bundle you can use:

curl --cacert curl-ca-bundle-new.crt -LO

and the download should work perfectly.

To make this change more permanent you can replace the original curl-ca-bundle-new.crt with this commands:

sudo cp /usr/share/curl/curl-ca-bundle.crt /usr/share/curl/curl-ca-bundle.crt-backup
sudo cp curl-ca-bundle-new.crt /usr/share/curl/curl-ca-bundle.crt
sudo chmod 644 /usr/share/curl/curl-ca-bundle.crt
sudo chown root:wheel /usr/share/curl/curl-ca-bundle.crt

And that's it! All your HTTPS downloads from GitHub should now be CA errors free, including clones using https:// URLs.

Although I had this problem on a Mac, the solution should work as well with other operating systems, as soon as you find the location of the curl-ca-bundle.crt file.