curl · Report #3969368
CVE-2026-80231: native CA store conn reuse
How it was found
Summary
native_ca_store is in struct ssl_config_data (line 73 of vtls_config.h), not ssl_primary_config. match_ssl_primary_config() does not compare it. On macOS, Curl_ssl_easy_config_complete() (line 258) auto-sets native_ca_store = TRUE when no custom CA is configured — without modifying ssl_options. When CURL_CA_BUNDLE is defined, the auto-fill gives both transfers the same primary.CAfile, making all primary config fields match while native_ca_store differs.
Transfer A (explicit CURLOPT_CAINFO = CURL_CA_BUNDLE path): custom_cafile=TRUE, auto-setting prevented, native_ca_store=FALSE — OpenSSL-only verification.
Transfer B (no CURLOPT_CAINFO): auto-fill sets same CAfile, custom_cafile=FALSE, auto native_ca_store=TRUE — intended SecTrust verification.
match_ssl_primary_config sees matching CAfile + ssl_options → connection reused. B inherits A's connection without SecTrust ever running.
Reproduction
macOS baremetal (poc-native-ca.c), built with -DUSE_APPLE_SECTRUST=ON -DCURL_CA_BUNDLE=<path> -DCURL_USE_OPENSSL=ON:
- Transfer A: explicit
CURLOPT_CAINFO=CURL_CA_BUNDLEpath → OpenSSL verifies - Transfer B: no
CAINFO→ auto-fill, autonative_ca_store=TRUE→ should use SecTrust - Observe:
"Reusing existing https: connection"— SecTrust never runs
Root cause trace
Curl_ssl_easy_config_complete()(line 258):!custom_capath && !custom_cafile && !custom_cablob→native_ca_store = TRUE. Does NOT modifyssl_options.CURL_CA_BUNDLEauto-fill (line 269): setsSTRING_SSL_CAFILE→primary.CAfile= bundle path.- Transfer A explicitly sets
CURLOPT_CAINFOto the same path →custom_cafile=TRUE, auto-setting prevented,native_ca_store=FALSE. Sameprimary.CAfile, samessl_options=0. match_ssl_primary_configmatches all fields → connection reused.native_ca_storenot compared.
Remediation
Move native_ca_store into ssl_primary_config so match_ssl_primary_config() compares it. Or add an explicit check in Curl_ssl_conn_config_match().
Impact
A transfer expecting SecTrust verification silently inherits an OpenSSL-only verified connection (or vice versa). Certificates trusted by one policy but not the other pass without re-verification.