diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 index 3611dbc8c6..bbeca4af1b 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 @@ -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 diff --git a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 index fc68238758..59d62b380a 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 @@ -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 diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index c538a966ec..a7ad454cf9 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -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 */