gnutls: support CURLSSLOPT_NATIVE_CA

Remove the CURL_CA_FALLBACK logic. That build option was added to allow
primarily OpenSSL to use the default paths for loading the CA certs. For
GnuTLS it was instead made to load the "system certs", which is
different and not desirable.

The native CA store loading is now asked for with this option.

Follow-up to 7b55279d1d

Co-authored-by: Jay Satiro

Closes #12137
This commit is contained in:
Daniel Stenberg 2023-10-16 14:46:36 +02:00
parent 7eb31c852d
commit 9cf4759354
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 60 additions and 48 deletions

View File

@ -62,12 +62,13 @@ library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes
precedence. (Added in 7.70.0)
.IP CURLSSLOPT_NATIVE_CA
Tell libcurl to use the operating system's native CA store for certificate
verification. Works only on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora,
RHEL), macOS, Android and iOS when built to use wolfSSL (since 8.3.0) or on
Windows when built to use OpenSSL. If you set this option and also set a CA
certificate file or directory then during verification those certificates
are searched in addition to the native CA store.
(Added in 7.71.0)
verification. If you set this option and also set a CA certificate file or
directory then during verification those certificates are searched in addition
to the native CA store.
Works with wolfSSL on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora, RHEL),
macOS, Android and iOS (added in 8.3.0), with GnuTLS (added in 8.5.0) or on
Windows when built to use OpenSSL (Added in 7.71.0).
.IP CURLSSLOPT_AUTO_CLIENT_CERT
Tell libcurl to automatically locate and use a client certificate for
authentication, when requested by the server. This option is only supported

View File

@ -61,12 +61,13 @@ library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes
precedence. (Added in 7.70.0)
.IP CURLSSLOPT_NATIVE_CA
Tell libcurl to use the operating system's native CA store for certificate
verification. Works only on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora,
RHEL), macOS, Android and iOS when built to use wolfSSL (since 8.3.0) or on
Windows when built to use OpenSSL. If you set this option and also set a CA
certificate file or directory then during verification those certificates
are searched in addition to the native CA store.
(Added in 7.71.0)
verification. If you set this option and also set a CA certificate file or
directory then during verification those certificates are searched in addition
to the native CA store.
Works with wolfSSL on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora, RHEL),
macOS, Android and iOS (added in 8.3.0), with GnuTLS (added in 8.5.0) or on
Windows when built to use OpenSSL (Added in 7.71.0).
.IP CURLSSLOPT_AUTO_CLIENT_CERT
Tell libcurl to automatically locate and use a client certificate for
authentication, when requested by the server. This option is only supported

View File

@ -460,50 +460,60 @@ CURLcode gtls_client_init(struct Curl_easy *data,
}
#endif
if(config->CAfile) {
/* set the trusted CA cert bundle file */
gnutls_certificate_set_verify_flags(gtls->cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
if(config->verifypeer) {
bool imported_native_ca = false;
rc = gnutls_certificate_set_x509_trust_file(gtls->cred,
config->CAfile,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)",
config->CAfile, gnutls_strerror(rc));
if(config->verifypeer) {
*pverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
if(ssl_config->native_ca_store) {
rc = gnutls_certificate_set_x509_system_trust(gtls->cred);
if(rc < 0)
infof(data, "error reading native ca store (%s), continuing anyway",
gnutls_strerror(rc));
else {
infof(data, "found %d certificates in native ca store", rc);
if(rc > 0)
imported_native_ca = true;
}
}
else
infof(data, "found %d certificates in %s", rc, config->CAfile);
}
if(config->CApath) {
/* set the trusted CA cert directory */
rc = gnutls_certificate_set_x509_trust_dir(gtls->cred,
config->CApath,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)",
config->CApath, gnutls_strerror(rc));
if(config->verifypeer) {
*pverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
if(config->CAfile) {
/* set the trusted CA cert bundle file */
gnutls_certificate_set_verify_flags(gtls->cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
rc = gnutls_certificate_set_x509_trust_file(gtls->cred,
config->CAfile,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)%s",
config->CAfile, gnutls_strerror(rc),
(imported_native_ca ? ", continuing anyway" : ""));
if(!imported_native_ca) {
*pverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
}
}
else
infof(data, "found %d certificates in %s", rc, config->CAfile);
}
else
infof(data, "found %d certificates in %s", rc, config->CApath);
}
#ifdef CURL_CA_FALLBACK
/* use system ca certificate store as fallback */
if(config->verifypeer && !(config->CAfile || config->CApath)) {
/* this ignores errors on purpose */
gnutls_certificate_set_x509_system_trust(gtls->cred);
if(config->CApath) {
/* set the trusted CA cert directory */
rc = gnutls_certificate_set_x509_trust_dir(gtls->cred,
config->CApath,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)%s",
config->CApath, gnutls_strerror(rc),
(imported_native_ca ? ", continuing anyway" : ""));
if(!imported_native_ca) {
*pverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
}
}
else
infof(data, "found %d certificates in %s", rc, config->CApath);
}
}
#endif
if(config->CRLfile) {
/* set the CRL list file */