12

My code is trying to access an HTTPS server and it has its own certificate. Example, the IP is "10.0.1.101".

If I go through Safari and access "http://10.0.1.101", everything's OK. I do a simple curl_easy_perform() for this URL and data can be pulled from the HTTP URL. Cool.

I then try to access "https://10.0.1.101" (yes, HTTPS) and from Safari, I accept the certificate and give it a "trust" option and after that, Safari access to the HTTPS URL is OK.

So the certificate has been added to the Mac Keychain but when I try a curl_easy_perform() on the HTTPS URL, it still returns with a CURLE_SSL_CACERT. libcurl could not authenticate the HTTPS certificate with known CA certificates.

What is the missing link between libcurl's certificate checking and Mac Keychain? Is there even a link at all? Is it possible to make libcurl look into the Mac Keychain for certificates? If so, how?

radj
  • 4,360
  • 7
  • 26
  • 41
  • Can we use CURLOPT_CAINFO option to point to a keychain file? – radj Sep 16 '11 at 01:19
  • 1
    There's a `security` command in terminal, I think you can use the output of that command to get the trust chain. (I'm not a certificate or terminal expert, tried in a script and it works with curl) – Marcelo Alves Sep 16 '11 at 01:19
  • @Marcelo Alves, thanks. It looks like a good starting point but if you can, will you share the steps how you did it? – radj Sep 16 '11 at 01:30
  • I've tried "security add-trusted-cert PathToPEMFile.pem" on both user and system keychain but libcurl still fails. – radj Sep 16 '11 at 01:44

3 Answers3

10

"New" curl on Mac OS does not "look" at system Keychain database (old curl versions worked great with -E option).

You can still make it work with curl on newer versions of Mac OS:

brew install curl

(installs version of curl that works with Client Certificates read from Keychain)

and then something like:

/usr/local/opt/curl/bin/curl -E wlad https://mail.securedbyclientcertificate.com/access/

(in -E you type name of your client certificate in Keychain database)

Mac OS will ask you for permission to read from Keychain, type your MacOS password and select "Always Allow"..

rkta
  • 3,959
  • 7
  • 25
  • 37
wlad
  • 101
  • 1
  • 2
  • 1
    phew! that was quite helpful. – Abe Jul 31 '18 at 02:44
  • 1
    I'm on a new Macbook with macOS 10.15.5. I have MacPorts, but using the 'native' ver of `curl`. When I try to d/l the latest `youtube-dl`: `sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl`, I get a cert expired error. he youtube-dl maintainers say their cert is valid & up-to-date. How can I fix this? –  Jun 06 '20 at 02:08
  • 4
    Even the latest version in `brew install curl` doesnt support reading from keychain. I had to installed to a specific version to make it work. documenting it here in case someone really needs it. `brew extract --version=7.69 curl homebrew/cask` and `brew install curl@7.69` – ghitesh Mar 31 '21 at 14:28
  • We can specify certificate like ` CURL_CA_BUNDLE=./cacert.pem curl 'https://local.io/'` For more, see https://curl.se/docs/sslcerts.html – ahuigo Mar 25 '23 at 21:00
5

Nope. libcurl built to use OpenSSL will only read CA certs from a single PEM file or from a directory of CA certs that have been prepared OpenSSL-style.

There's no special magic for the Mac Keychain implemented.

Daniel Stenberg
  • 54,736
  • 17
  • 146
  • 222
  • 2
    Really? Well then, this is *weird*. My machine running Mountain Lion "just works" and recognizes the cert fine, but my machine running Yosemite is *no go*. – Michael Oct 04 '15 at 03:01
  • 1
    Notice that this answer was posted in 2011, thus libcurl doesn't support OS X keychain at that time. – WeZZard Jun 19 '18 at 22:42
4

In current versions of MacOS you can tell the system installed curl to use the Keychain using the CURL_SSL_BACKEND environment variable e.g. to use a named client cert from the Keychain (it will pop up a Keychain authentication dialogue):

CURL_SSL_BACKEND=secure-transport curl --cert "My Cert" htps://10.0.1.101/
Pierz
  • 7,064
  • 52
  • 59