Using CharlesProxy's root SSL with home-brew curl
Once I installed Homebrew’s curl for HTTP/2 usage, I discovered that I couldn’t automatically proxy SSL through Charles Proxy any more.
$ export HTTPS_PROXY=https://localhost:8888 $ curl https://api.joind.in/v2.1/ curl: (60) SSL certificate problem: self signed certificate in certificate chain More details here: https://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, 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.
This is a nuisance.
As I’ve noted previously, you need to install Charles’ root certificate to use it with SSL. On OS X, you do Help -> SSL Proxying -> Install Charles Root Certificate which installs it into the system keychain.
However, this doesn’t work with the Homebrew curl or with the curl functions inside PHP. To fix this, we need to add the Charles root certificate to OpenSSL’s default_cert_file.
I’ve talked about this file before. The quickest way to find it is to run:
$ php -r "print_r(openssl_get_cert_locations());"
on the command line. The output should be similar to:
Array ( [default_cert_file] => /usr/local/etc/openssl/cert.pem [default_cert_file_env] => SSL_CERT_FILE [default_cert_dir] => /usr/local/etc/openssl/certs [default_cert_dir_env] => SSL_CERT_DIR [default_private_dir] => /usr/local/etc/openssl/private [default_default_cert_area] => /usr/local/etc/openssl [ini_cafile] => [ini_capath] => )
As you can see, the file I need is /usr/local/etc/openssl/cert.pem.
Grab the root certificate from the Charles app. On Mac, that’s Help -> SSL Proxying -> Save Charles Root Certificate menu item.
You can then append the root certificate to the default cert file:
$ cat charles_root.crt >> /usr/local/etc/openssl/cert.pem
Now, everything works:
$ curl https://api.joind.in/v2.1/ {"events":"https:\/\/api.joind.in\/v2.1\/events","hot-events":"https:\/\/api.joind.in\/v2.1\/events?filter=hot","upcoming-events":"https:\/\/api.joind.in\/v2.1\/events?filter=upcoming","past-events":"https:\/\/api.joind.in\/v2.1\/events?filter=past","open-cfps":"https:\/\/api.joind.in\/v2.1\/events?filter=cfp","docs":"http:\/\/joindin.github.io\/joindin-api\/"}
(It also works in PHP as that’s linked against the same curl if you followed my post on enabling HTTP/2 in PHP.)