-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
curl: add build option to use the native CA store by default #18279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Once again I must object. I don't want to rehash all of #16181 but people may not read all my comments so I will discuss here briefly. The --ca-native option imports CAs in addition to other CA import options. Enabling it by default is going to change the behavior to always import those CAs even when the user has selected a different CA option. This changes curl behavior in a way that is undesirable (in my opinion) and, objectively, unexpected. Apple did something similar in their SSL library (fork of LibreSSL I think it was) to import native CAs even if the user has specified their own and I thought it was a security issue, but Apple didn't think so. I think @bagder commented on this as well somewhere. Adding a build-time fallback, like we already do with CURL_CA_FALLBACK, could work. diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index a2ab831..aa4288d 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -3384,7 +3384,11 @@ static CURLcode ossl_populate_x509_store(struct Curl_cfilter *cf,
https://stackoverflow.com/questions/9507184/
https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037
https://datatracker.ietf.org/doc/html/rfc5280 */
+#ifdef CURL_NATIVE_CA_FALLBACK
+ if(!ssl_cafile && !ssl_capath && !ca_info_blob) {
+#else
if(ssl_config->native_ca_store) {
+#endif
const char *storeNames[] = {
"ROOT", /* Trusted Root Certification Authorities */
"CA" /* Intermediate Certification Authorities */ The user can already put --ca-native in their curlrc. Also CA native on Windows does not work properly unless the OS already has the root certificates in the store, and that is not always the case with Windows. It gets the root certs on demand, see #12303. |
Unless I'm missing something the issue you raise is only present if curl is implicitly The point of this PR is to make these implicit (and in many cases insecure), or explicit I think explicitly passing extra CA roots is still a valid use-case. Disabling them (In case of Apple, they patched the TLS library, with an undisclosed source If one doesn't want curl to pick up on-disk CA bundles by default, this build edit:
They can, but in practice few people seem to be doing that. As for #12303, either we can't really do anything about it and it affects every |
I don't understand your logic around this. The user can already use the curlrc to set default options. Adding this is like adding --ca-native to everyone's curlrc and their OS store's certificates would be used in addition to whatever CA options they specified (or the autodetected curl-ca-bundle.crt, CURL_CA_BUNDLE env etc). Users are not going to expect that. IMO the only advantage over a fallback is it compensates for bad user config. |
The goal of this option is to make it unnecessary to configure CA roots With this option enabled, it's possible to drop these manual methods. Making CA roots actually useful and do what they were designed to do: Would the pre-existing manual configs cause issues if they remain enabled? But, it's just an option, no one is forced to enable it at build time, and it's |
@jay Please understand that there is other people want to use curl different the way you want it. |
The issue is it overrides the user's expectation by using those OS certs in addition to whatever certs they specified (or were detected as documented). I don't understand how a fallback is not sufficient for all of this. At this point I think we are just repeating ourselves and we disagree.
Sure I understand this but if you switch to an SSL backend that is not the native backend (eg switch from Schannel to OpenSSL) then it is not going to be the same as using the native backend. OpenSSL takes a certificate bundle or certificate locations. Side note: OpenSSL has its own preliminary support for native CA with special string "org.openssl.winstore://". It's complicated though because from what I read it requires setting an environment variable and it has to be passed specially instead of to their X509_STORE_load_file/X509_STORE_load_path so in an existing application (like curl) that uses those functions you can't pass it. For example AFAICT you can't |
I agree. If we talking about specific on windows, openssl with the option enable native certificate, it not the same as using schannel. But I am talking about specific on windows, doing http3 on windows, then you need to use backend different from schannel, for example openssl, then you must use enable native certificate option always for doing ssl. For this use case we need / want enable native certificate always in the compilation time. |
I can only speak for myself, but my expectation has always been that HTTPS What actual issues can this cause in practice? Would these affect most users? |
Sure I agree. curl is used many ways though and users may specify their own CA certificates or a limited set or location, they may not be passing a bundle with all known root CAs like cacert.pem to access every HTTPS URL. The user has some intention to use their CA certs, or some CA certs were autodetected as we document (we can assume some intention there). In practice the build option in this PR would make those builds of curl behave in a way that goes against the documented behavior of the CA options. I know a better out-of-box experience is desired but this is not the way to go about it. |
As distro packagers, we just want to be able to build full-featured, out-of-the-box curl.exe with cmake --build, rather than need a bunch of non-standard steps to avoid building a garbage that doesn't work at all for the end users. As curl.exe end users, we just want http3 enabled curl.exe to work just like Windows builtin curl.exe. If someone feels there is something wrong with this, just disable the option when building, rather than block merging this PR. curl should not sacrifice the experience of the vast majority of users because of someone's edge use case. Even if this PR was blocked, we would have patched curl anyway to get actual usable curl.exe. |
Since this is a build option and not even set by default, I am in favor of it. curl users on all platforms are used to |
That could be done with a fallback as I mentioned earlier in the thread. There's no reason to the change the user's --cacert choice. Why do it that way? I am very much against that and I'm surprised you aren't as well. Let's say we do this and we end up with builds of curl distributed on vcpkg that have this behavior enabled, and the user specifies --cacert private.crt with the expectation that they are connecting to their corporate or government server and now the OS store certs are used as well. It is backdoor behavior if a big govt wanted to cut the route. Do you not remember https://daniel.haxx.se/blog/2024/03/08/the-apple-curl-security-incident-12604/ |
No there isn't. I wasn't aware this did. --cacert should override the default. I was under the impression that this changes the default, which is that the title says. |
Looking shallowly as this proposal and Lines 3456 to 3464 in b3570b3
Lines 3456 to 3464 in b3570b3
At the end, both |
@michael-o don't mixup native-ca and "ca-fallback" though. The first one uses "the native CA store" (which primarily is a thing on Windows and macOS) while the second option more mysteriously uses "the TLS library's fallback" and the second is only an OpenSSL (hack) - that most typically would be used when you rely on some specific magic behavior of your OpenSSL. We already have native-ca support in the OpenSSL backend, as this PR is about an option to set that by default. |
Ah, thanks for the clarification. |
If it this is true, you should add an option that call something In my opinion, as a security reason, Because you already have an api that doing undesired behavior, I think you should start to deprecated the As a philosophy of curl, doing only the things the user explicit ask for. This is not the way with |
This patch does nothing else than allow enabling If someone is concerned by big-government (or big-corp) CA's installed in the OS, the native It seems fair to assume that those concerned by a planted/forced/malicious CA root on their |
If someone has access to mess around with your system certificate store, you're screwed. They obviously have administrator rights to the entire system and monitor all your network traffic. A curl.exe that doesn't use the system certificate store doesn't solve anything. |
No that's not a given. It was an example of how an attacker could take advantage of using certificates that the user did not expect. That's not to say someone hacked your certificate store. Like the user trusts CA X only to connect to server Y. |
Usage: - cmake: `-DCURL_CA_NATIVE_BY_DEFAULT=ON` - autotools: `--enable-ca-native-by-default` - CPPFLAGS: `-DCURL_CA_NATIVE_BY_DEFAULT` If enabled a built-time, the native CA be disabled at runtime with the `--no-ca-native` command-line option. I'm opening again, because: - there is repeat and active interest in this option. - it helps integrating curl with Windows for those who need this. - it frees applications/user from the task of securely distributing, and keeping up-to-date, a CA bundle. - it frees potentially many curl tool users from configuring a CA bundle manually to access HTTPS URLs. This is traditionally difficult on Windows because there is no concept of a protected, non-world-writable directory to securely store a CA bundle. Ref: curl#16181 (previous attempt) Ref: curl#9348 Ref: microsoft/vcpkg#46459 (comment)
@vszakats Can this be generalized that is works for both libcurl and curl? Configured once during build and then used by all consumers w/o configuring anything on lib or tool level? |
Yes, it could be extended to libcurl. The issues this PR intends to help IMO it'd be nice to make this work by default in libcurl too, and may also |
I dare you say that 90+% of the users are unable to comprehend what's needs to be done and what a CA is and so on. The idea I had is that |
Started #18567 to clarify terminology and, hopefully, get us to agree on the usability criteria. We need this to guide our implementations. |
In the curl tool.
To enable:
--enable-ca-native-by-default
-DCURL_CA_NATIVE_BY_DEFAULT=ON
-DCURL_CA_NATIVE_BY_DEFAULT
When enabled, consider disabling implicit on-disk CA bundles, to avoid
auto-loading potentially outdated, redundant bundles from unsafe,
world-writable, paths:
--disable-ca-search
-DCURL_DISABLE_CA_SEARCH=ON
-DCURL_DISABLE_CA_SEARCH
When enabled, native CA can be disabled at run-time with
the
--no-ca-native
and/or--no-proxy-ca-native
command-line options.Rationale: This build option:
distributing, and keeping up-to-date, a CA bundle.
manually to access HTTPS (and other TLS) URLs. This is traditionally
difficult on Windows because there is no concept of a universal,
protected, non-world-writable, location on the file system to securely
store a CA bundle.
these features are not supported with Schannel (e.g. HTTP/3, ECH) on
any Windows version.
possible with Schannel, because MultiSSL is not an option, and HTTP/3
is not supported with Schannel.
Ref: #16181 (previous attempt)
Ref: #9348
Ref: #9350
Ref: #13111
Ref: microsoft/vcpkg#46459 (comment)
Ref: 22652a5 #14582
→ disable on-disk search and other file-based bundle methods by default.