156 lines
7.2 KiB
Markdown
156 lines
7.2 KiB
Markdown
SSL Certificate Verification
|
|
============================
|
|
|
|
SSL is TLS
|
|
----------
|
|
|
|
SSL is the old name. It is called TLS these days.
|
|
|
|
Native SSL
|
|
----------
|
|
|
|
If libcurl was built with Schannel or Secure Transport support (the native SSL
|
|
libraries included in Windows and Mac OS X), then this does not apply to
|
|
you. Scroll down for details on how the OS-native engines handle SSL
|
|
certificates. If you are not sure, then run "curl -V" and read the results. If
|
|
the version string says `Schannel` in it, then it was built with Schannel
|
|
support.
|
|
|
|
It is about trust
|
|
-----------------
|
|
|
|
This system is about trust. In your local CA certificate store you have certs
|
|
from *trusted* Certificate Authorities that you then can use to verify that
|
|
the server certificates you see are valid. They are signed by one of the
|
|
certificate authorities you trust.
|
|
|
|
Which certificate authorities do you trust? You can decide to trust the same
|
|
set of companies your operating system trusts, or the set one of the known
|
|
browsers trust. That is basically trust via someone else you trust. You should
|
|
just be aware that modern operating systems and browsers are setup to trust
|
|
*hundreds* of companies and in recent years several certificate authorities
|
|
have been found untrustworthy.
|
|
|
|
Certificate Verification
|
|
------------------------
|
|
|
|
libcurl performs peer SSL certificate verification by default. This is done
|
|
by using a CA certificate store that the SSL library can use to make sure the
|
|
peer's server certificate is valid.
|
|
|
|
If you communicate with HTTPS, FTPS or other TLS-using servers using
|
|
certificates in the CA store, you can be sure that the remote server really is
|
|
the one it claims to be.
|
|
|
|
If the remote server uses a self-signed certificate, if you do not install a CA
|
|
cert store, if the server uses a certificate signed by a CA that is not
|
|
included in the store you use or if the remote host is an impostor
|
|
impersonating your favorite site, and you want to transfer files from this
|
|
server, do one of the following:
|
|
|
|
1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
|
|
`curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);`
|
|
|
|
With the curl command line tool, you disable this with `-k`/`--insecure`.
|
|
|
|
2. Get a CA certificate that can verify the remote server and use the proper
|
|
option to point out this CA cert for verification when connecting. For
|
|
libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAINFO, cacert);`
|
|
|
|
With the curl command line tool: `--cacert [file]`
|
|
|
|
3. Add the CA cert for your server to the existing default CA certificate
|
|
store. The default CA certificate store can be changed at compile time with
|
|
the following configure options:
|
|
|
|
`--with-ca-bundle=FILE`: use the specified file as the CA certificate
|
|
store. CA certificates need to be concatenated in PEM format into this
|
|
file.
|
|
|
|
`--with-ca-path=PATH`: use the specified path as CA certificate store. CA
|
|
certificates need to be stored as individual PEM files in this directory.
|
|
You may need to run c_rehash after adding files there.
|
|
|
|
If neither of the two options is specified, configure will try to
|
|
auto-detect a setting. It's also possible to explicitly not set any
|
|
default store but rely on the built in default the crypto library may
|
|
provide instead. You can achieve that by passing both
|
|
`--without-ca-bundle` and `--without-ca-path` to the configure script.
|
|
|
|
If you use Internet Explorer, this is one way to get extract the CA cert
|
|
for a particular server:
|
|
|
|
- View the certificate by double-clicking the padlock
|
|
- Find out where the CA certificate is kept (Certificate>
|
|
Authority Information Access>URL)
|
|
- Get a copy of the crt file using curl
|
|
- Convert it from crt to PEM using the OpenSSL tool:
|
|
`openssl x509 -inform DES -in yourdownloaded.crt -out outcert.pem -text`
|
|
- Add the `outcert.pem` to the CA certificate store or use it stand-alone
|
|
as described below.
|
|
|
|
If you use the `openssl` tool, this is one way to get extract the CA cert
|
|
for a particular server:
|
|
|
|
- `openssl s_client -showcerts -servername server -connect server:443 > cacert.pem`
|
|
- type "quit", followed by the "ENTER" key
|
|
- The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
|
|
markers.
|
|
- If you want to see the data in the certificate, you can do: `openssl
|
|
x509 -inform PEM -in certfile -text -out certdata` where `certfile` is
|
|
the cert you extracted from logfile. Look in `certdata`.
|
|
- If you want to trust the certificate, you can add it to your CA
|
|
certificate store or use it stand-alone as described. Just remember that
|
|
the security is no better than the way you obtained the certificate.
|
|
|
|
4. If you are using the curl command line tool and the TLS backend is not
|
|
Schannel then you can specify your own CA cert file by setting the
|
|
environment variable `CURL_CA_BUNDLE` to the path of your choice.
|
|
|
|
If you are using the curl command line tool on Windows, curl will search
|
|
for a CA cert file named "curl-ca-bundle.crt" in these directories and in
|
|
this order:
|
|
1. application's directory
|
|
2. current working directory
|
|
3. Windows System directory (e.g. C:\windows\system32)
|
|
4. Windows Directory (e.g. C:\windows)
|
|
5. all directories along %PATH%
|
|
|
|
5. Get another CA cert bundle. One option is to extract the one a recent
|
|
Firefox browser uses by running 'make ca-bundle' in the curl build tree
|
|
root, or possibly download a version that was generated this way for you:
|
|
[CA Extract](https://curl.se/docs/caextract.html)
|
|
|
|
Neglecting to use one of the above methods when dealing with a server using a
|
|
certificate that is not signed by one of the certificates in the installed CA
|
|
certificate store, will cause SSL to report an error ("certificate verify
|
|
failed") during the handshake and SSL will then refuse further communication
|
|
with that server.
|
|
|
|
Certificate Verification with Schannel and Secure Transport
|
|
-----------------------------------------------------------
|
|
|
|
If libcurl was built with Schannel (Microsoft's native TLS engine) or Secure
|
|
Transport (Apple's native TLS engine) support, then libcurl will still perform
|
|
peer certificate verification, but instead of using a CA cert bundle, it will
|
|
use the certificates that are built into the OS. These are the same
|
|
certificates that appear in the Internet Options control panel (under Windows)
|
|
or Keychain Access application (under OS X). Any custom security rules for
|
|
certificates will be honored.
|
|
|
|
Schannel will run CRL checks on certificates unless peer verification is
|
|
disabled. Secure Transport on iOS will run OCSP checks on certificates unless
|
|
peer verification is disabled. Secure Transport on OS X will run either OCSP
|
|
or CRL checks on certificates if those features are enabled, and this behavior
|
|
can be adjusted in the preferences of Keychain Access.
|
|
|
|
HTTPS proxy
|
|
-----------
|
|
|
|
Since version 7.52.0, curl can do HTTPS to the proxy separately from the
|
|
connection to the server. This TLS connection is handled separately from the
|
|
server connection so instead of `--insecure` and `--cacert` to control the
|
|
certificate verification, you use `--proxy-insecure` and `--proxy-cacert`.
|
|
With these options, you make sure that the TLS connection and the trust of the
|
|
proxy can be kept totally separate from the TLS connection to the server.
|