3

I know which Certificate Authority (CA) my server uses for its TLS certs.

My client system also knows who the CA is.

When I use cURL, I can specify --cacert to specify a custom CA file to use, but it seems that this is used IN ADDITION to the trusted CAs installed on my system, not instead of.

So is there a way of telling cURL to ONLY accept CA certs that I know to expect, when making a connection to my server?

Otherwise, I can't detect a rogue CA from issuing a cert for my server unless I manually scrape the verbose connection details during connection...

1

Good question - in a browser there is certificate pinning. After looking this up I came across the curl flag --pinnedpubkey

Certificate pinning

TLS certificate pinning is a way to verify that the public key used to sign the servers certificate has not changed. It is "pinned".

When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and if it does not exactly match the public key provided to this option, curl will abort the connection before sending or receiving any data.

You tell curl a file name to read the sha256 value from, or you specify the base64 encoded hash directly in the command line with a sha256// prefix. You can specify one or more hashes like that, separated with semicolons (;).

curl --pinnedpubkey "sha256//83d34tasd3rt..." https://example.com/ This feature is not supported by all TLS backends.

Reference: https://ec.haxx.se/usingcurl-tls.html

| improve this answer | |
  • It's a good answer, but doesn't work for me - I know the root CA for the server issuing my certs, but I have no visibility of the certs themselves, so am unable to use this option. – StampyCode Jan 10 '19 at 16:28
  • You can find the pubkey of the server as visible to your box via curl -v https://host --pinnedpubkey sha256// and it will be above the failure message: but of course the only way to know it is correct for sure is to calculate it from the server certificate or trust the CA chain – fuzzyTew Jul 15 at 15:52
0

At least on "Debianic" Linux systems, curl uses /etc/ssl/certs/ca-certificates.crt as default for --cacert and /etc/ssl/certs as default for --capath.

You may set --cacert and --capath explicitly to "overwrite" these defaults. Note that you have to set both; otherwise the default is used for the non-given option.

Example:

curl --cacert my_certs_file --capath my_certs_dir ...

my_certs_file contains your custom CA file; my_certs_dir is a directory that is empty here.

It is also possible to store your custom CA file(s) in my_certs_dir (do not forget to execute c_rehash my_certs_dir after storing). The file my_certs_file may not be left empty (depends on curl version), but must contain at least one syntactically correct certificate.

(What a coincidence: Today I walked into the "default" trap, too--and found the described solution.)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.