CVE-2026-11564: Native CA trust persist
What the report claims
An easy handle that initially uses default native CA trust can retain the native_ca_store flag after the application switches to custom CA material, causing backends that consult native trust to continue accepting certificates trusted by the platform store even when custom CA options are set.
Compare with curl's recorded outcome
Known vulnerability
A real vulnerability: CVE-2026-11564 Native CA trust persist
Shown for comparison after analysis. The pipeline did not see this label.
ProveIt's finding
The available evidence does not settle the report. A maintainer should investigate.
See the withdrawn model reasoning
The following reasoning failed the citation check and does not support the final finding.
- Curl_ssl_easy_config_complete (lib/vtls/vtls_config.c:247-250) sets native_ca_store=TRUE only when no custom CA options are present, but never resets it to FALSE when custom CA options are present.
- Setopt handlers for CURLOPT_CAINFO, CURLOPT_CAPATH, CURLOPT_CAINFO_BLOB (lib/setopt.c) set custom flags but do not clear native_ca_store.
- Backend code (OpenSSL, Rustls) consults native_ca_store to prefer platform verification over custom CA material, confirmed by grounded symbols and quoted logic.
- The POC demonstrates the stale state: after default config + CURLOPT_CAINFO, both custom_cafile and native_ca_store are true.
- This allows an attacker to present a certificate chaining to the native platform store but not the application's custom bundle, bypassing the intended trust narrowing.
- The issue is not excluded by curl's security policy (not experimental, not debug-only, not a small leak, not API misuse).
How this analysis ran 6 claims · 4 citations verified
Evidence check: judge quoted an external source that does not say that (https://developer.apple.com/documentation/security/trust)
Checked against curl master on 2026-06-08 (9b69cfb93785). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.
Inspect the withdrawn draft reply
This draft belongs to the withdrawn judgment. It may contain unsupported claims.
Thank you for the detailed report. The issue is confirmed: Curl_ssl_easy_config_complete in lib/vtls/vtls_config.c sets native_ca_store=TRUE for default trust but does not recompute it to FALSE when custom CA options (CURLOPT_CAINFO, CURLOPT_CAPATH, CURLOPT_CAINFO_BLOB) are later set via setopt. The setopt handlers only set custom flags without clearing native_ca_store. Backends (OpenSSL, Rustls) then consult the stale flag and may prefer platform verification over the configured custom CA material, defeating the application's trust-narrowing intent. This is a valid TLS authentication policy bypass on native-CA-enabled builds. The fix should recompute native_ca_store from current options in Curl_ssl_easy_config_complete, clearing it when any custom CA file/path/blob is present unless CURLSSLOPT_NATIVE_CA was explicitly requested.
Inspect all claims and source code 6 claims · 9 code excerpts
This model judgment was withdrawn. The claim assessments below are preserved for inspection and may be wrong.
Report claims
The function lib/vtls/vtls_config.c does not reset sslc->native_ca_store before recomputing TLS configuration for a later transfer on the same easy handle.
Read the reasoning
The function unconditionally sets native_ca_store to TRUE only when custom_capath, custom_cafile, and custom_cablob are all false. If native_ca_store was already TRUE from a prior call, it remains TRUE even after custom CA options are set via setopt.
The setters for custom CA material in lib/setopt.c only mark the corresponding custom-CA flag and store the new value without clearing native_ca_store.
Read the reasoning
The deterministic checks confirm 6/6 quoted lines from the report's Figure X.2 appear in curl at the checked revision, showing the setopt cases for CURLOPT_CAINFO, CURLOPT_CAPATH, CURLOPT_CAINFO_BLOB only set custom flags without touching native_ca_store.
When native_ca_store is true, backends such as OpenSSL and Rustls may continue to consult native trust or select platform verification instead of the configured custom CA material.
Read the reasoning
The backend code paths that consume native_ca_store are confirmed to exist in the codebase at the checked revision. The report's quotes of the conditional logic in OpenSSL and Rustls are verified as present in curl.
The stale native_ca_store flag can cause a TLS authentication policy bypass on affected builds where native CA lookup is implemented.
Read the reasoning
The combination of persistent native_ca_store flag and backend logic that prefers platform verification when the flag is set creates a TLS authentication policy bypass: the application's intent to narrow trust to custom CA material is defeated.
The function Curl_ssl_easy_config_complete only auto-enables native trust when no custom CA file, path, or blob is present, leading to history‑dependent trust behavior on reused handles.
Read the reasoning
A fresh handle that sets custom CA before first transfer never gets native_ca_store auto-enabled, while a reused handle that first used default trust retains native_ca_store=TRUE. This history-dependent difference is the trust-policy confusion.
The standalone POC confirms that after setting CURLOPT_CAINFO the native_ca_store flag remains true, demonstrating the persistence issue.
Read the reasoning
The standalone POC exercises the exact sequence: default TLS config (enables native_ca_store), then CURLOPT_CAINFO, then TLS config again, and asserts both custom_cafile and native_ca_store are true.
Deterministic checks that failed
- symbol fail_unless() does not exist in curl at 9b69cfb93785 or in any release since 7.50
- quote only 1/10 quoted lines appear anywhere in curl at 9b69cfb93785
What the report says about other projects
confirmed CURL_CA_NATIVE and Apple SecTrust are documented TLS trust-store features, not debug-only or experimental code.
“SecTrustSetAnchorCertificatesOnly(SecTrust, Bool) -> OSStatus)... Reenables trusting built-in anchor certificates.” source
Read the original report (excerpt)
Source code
| 82 | CURLcode Curl_setstropt(char **charp, const char *s) |
| C2: Curl_setstropt and Curl_setblobopt (lines 82-130) only store the new value and set the corresponding custom_cafile/custom_capath/custom_cablob flags; they do not clear ssl.native_ca_store. | |
| 83 | { |
| 84 | /* Release the previous storage at `charp' and replace by a dynamic storage |
| 85 | copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ |
| 86 | |
| 87 | curlx_safefree(*charp); |
| 88 | |
| 89 | if(s) { |
| 90 | if(strlen(s) > CURL_MAX_INPUT_LENGTH) |
| 91 | return CURLE_BAD_FUNCTION_ARGUMENT; |
| 92 | |
| 93 | *charp = curlx_strdup(s); |
| 94 | if(!*charp) |
| 95 | return CURLE_OUT_OF_MEMORY; |
| 96 | } |
| 97 | |
| 98 | return CURLE_OK; |
| 99 | } |
| 237 | CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data, |
| 238 | struct Curl_peer *origin) |
| 239 | { |
| 240 | struct ssl_config_data *sslc = &data->set.ssl; |
| 241 | #if defined(CURL_CA_PATH) || defined(CURL_CA_BUNDLE) |
| 242 | struct UserDefined *set = &data->set; |
| 243 | CURLcode result; |
| 244 | #endif |
| 245 | |
| 246 | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| 247 | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| C1: Curl_ssl_easy_config_complete only sets native_ca_store = TRUE when no custom CA options are present (lines 247-250); it does not reset it to FALSE when custom CA options exist. | |
| C4: Stale native_ca_store persists (C1, C2) and is consulted by backends (C3), allowing certificates trusted by the native store but not the custom bundle to be accepted. | |
| C5: The auto-enable condition at lines 247-250 only triggers when all three custom CA flags are false; it does not recompute native_ca_store to FALSE when they are true. | |
| 248 | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| 249 | sslc->native_ca_store = TRUE; |
| 250 | #endif |
| 251 | #ifdef CURL_CA_PATH |
| 252 | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH]) { |
| 253 | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); |
| 254 | if(result) |
| 255 | return result; |
| 256 | } |
| 257 | #endif |
| 258 | #ifdef CURL_CA_BUNDLE |
| 259 | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE]) { |
| 260 | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); |
| 261 | if(result) |
| 262 | return result; |
| 263 | } |
| 264 | #endif |
| 265 | } |
| 266 | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE]; |
| 267 | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; |
| 268 | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH]; |
| 269 | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; |
| 270 | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST]; |
| 271 | sslc->primary.signature_algorithms = |
| 272 | data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS]; |
| 273 | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; |
| 274 | sslc->primary.curves = data->set.str[STRING_SSL_EC_CURVES]; |
| 275 | /* Maybe these should not be used for another origin. But for |
| 276 | * backwards compatibility, keep them in. */ |
| 277 | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; |
| 278 | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; |
| 279 | |
| 280 | if(Curl_peer_equal(data->state.initial_origin, origin)) { |
| 281 | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; |
| 282 | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT]; |
| 283 | sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE]; |
| 284 | sslc->primary.key = data->set.str[STRING_KEY]; |
| 285 | sslc->primary.key_type = data->set.str[STRING_KEY_TYPE]; |
| 286 | sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD]; |
| 287 | sslc->primary.clientcert = data->set.str[STRING_CERT]; |
| 288 | sslc->primary.key_blob = data->set.blobs[BLOB_KEY]; |
| 289 | #ifdef USE_TLS_SRP |
| 290 | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; |
| 291 | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; |
| 292 | #endif |
| 293 | } |
| 294 | else { |
| 295 | sslc->primary.pinned_key = NULL; |
| 296 | sslc->primary.cert_blob = NULL; |
| 297 | sslc->primary.cert_type = NULL; |
| 298 | sslc->primary.key = NULL; |
| 299 | sslc->primary.key_type = NULL; |
| 300 | sslc->primary.key_passwd = NULL; |
| 301 | sslc->primary.clientcert = NULL; |
| 302 | sslc->primary.key_blob = NULL; |
| 303 | #ifdef USE_TLS_SRP |
| 304 | sslc->primary.username = NULL; |
| 305 | sslc->primary.password = NULL; |
| 306 | #endif |
| 307 | } |
| 308 | |
| 309 | #ifndef CURL_DISABLE_PROXY |
| 310 | sslc = &data->set.proxy_ssl; |
| 311 | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| 312 | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| 313 | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| 314 | sslc->native_ca_store = TRUE; |
| 315 | #endif |
| 316 | #ifdef CURL_CA_PATH |
| 317 | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH_PROXY]) { |
| 318 | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], |
| 319 | CURL_CA_PATH); |
| 320 | if(result) |
| 321 | return result; |
| 322 | } |
| 323 | #endif |
| 324 | #ifdef CURL_CA_BUNDLE |
| 325 | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE_PROXY]) { |
| 326 | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], |
| 327 | CURL_CA_BUNDLE); |
| 328 | if(result) |
| 329 | return result; |
| 330 | } |
| 331 | #endif |
| 332 | } |
| 333 | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; |
| 334 | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; |
| 335 | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; |
| 336 | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; |
| 337 | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; |
| 338 | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; |
| 339 | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO_PROXY]; |
| 340 | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; |
| 341 | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; |
| 342 | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; |
| 343 | sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; |
| 344 | sslc->primary.key = data->set.str[STRING_KEY_PROXY]; |
| 345 | sslc->primary.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; |
| 346 | sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; |
| 347 | sslc->primary.clientcert = data->set.str[STRING_CERT_PROXY]; |
| 348 | sslc->primary.key_blob = data->set.blobs[BLOB_KEY_PROXY]; |
| 349 | #ifdef USE_TLS_SRP |
| 350 | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; |
| 351 | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; |
| 352 | #endif |
| 353 | #endif /* CURL_DISABLE_PROXY */ |
| 354 | |
| 355 | return CURLE_OK; |
| 356 | } |
Show 1 lines (not cited by the judge)
| 957 | #define CURLSSLOPT_NATIVE_CA (1L << 4) |
Show 30 lines (not cited by the judge)
| 101 | CURLcode Curl_setblobopt(struct curl_blob **blobp, |
| 102 | const struct curl_blob *blob) |
| 103 | { |
| 104 | /* free the previous storage at `blobp' and replace by a dynamic storage |
| 105 | copy of blob. If CURL_BLOB_COPY is set, the data is copied. */ |
| 106 | |
| 107 | curlx_safefree(*blobp); |
| 108 | |
| 109 | if(blob) { |
| 110 | struct curl_blob *nblob; |
| 111 | if(!blob->len || (blob->len > CURL_MAX_INPUT_LENGTH)) |
| 112 | return CURLE_BAD_FUNCTION_ARGUMENT; |
| 113 | nblob = (struct curl_blob *) |
| 114 | curlx_malloc(sizeof(struct curl_blob) + |
| 115 | ((blob->flags & CURL_BLOB_COPY) ? blob->len : 0)); |
| 116 | if(!nblob) |
| 117 | return CURLE_OUT_OF_MEMORY; |
| 118 | *nblob = *blob; |
| 119 | if(blob->flags & CURL_BLOB_COPY) { |
| 120 | /* put the data after the blob struct in memory */ |
| 121 | nblob->data = (char *)nblob + sizeof(struct curl_blob); |
| 122 | memcpy(nblob->data, blob->data, blob->len); |
| 123 | } |
| 124 | |
| 125 | *blobp = nblob; |
| 126 | return CURLE_OK; |
| 127 | } |
| 128 | |
| 129 | return CURLE_OK; |
| 130 | } |
Show 100 lines (not cited by the judge)
| 295 | CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data) |
| 296 | { |
| 297 | struct ssl_config_data *sslc = &data->set.ssl; |
| 298 | #if defined(CURL_CA_PATH) || defined(CURL_CA_BUNDLE) |
| 299 | struct UserDefined *set = &data->set; |
| 300 | CURLcode result; |
| 301 | #endif |
| 302 | |
| 303 | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| 304 | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| 305 | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| 306 | sslc->native_ca_store = TRUE; |
| 307 | #endif |
| 308 | #ifdef CURL_CA_PATH |
| 309 | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH]) { |
| 310 | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); |
| 311 | if(result) |
| 312 | return result; |
| 313 | } |
| 314 | #endif |
| 315 | #ifdef CURL_CA_BUNDLE |
| 316 | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE]) { |
| 317 | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); |
| 318 | if(result) |
| 319 | return result; |
| 320 | } |
| 321 | #endif |
| 322 | } |
| 323 | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE]; |
| 324 | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; |
| 325 | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH]; |
| 326 | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; |
| 327 | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; |
| 328 | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; |
| 329 | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST]; |
| 330 | sslc->primary.signature_algorithms = |
| 331 | data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS]; |
| 332 | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; |
| 333 | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT]; |
| 334 | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; |
| 335 | sslc->primary.curves = data->set.str[STRING_SSL_EC_CURVES]; |
| 336 | #ifdef USE_TLS_SRP |
| 337 | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; |
| 338 | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; |
| 339 | #endif |
| 340 | sslc->cert_type = data->set.str[STRING_CERT_TYPE]; |
| 341 | sslc->key = data->set.str[STRING_KEY]; |
| 342 | sslc->key_type = data->set.str[STRING_KEY_TYPE]; |
| 343 | sslc->key_passwd = data->set.str[STRING_KEY_PASSWD]; |
| 344 | sslc->primary.clientcert = data->set.str[STRING_CERT]; |
| 345 | sslc->key_blob = data->set.blobs[BLOB_KEY]; |
| 346 | |
| 347 | #ifndef CURL_DISABLE_PROXY |
| 348 | sslc = &data->set.proxy_ssl; |
| 349 | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| 350 | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| 351 | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| 352 | sslc->native_ca_store = TRUE; |
| 353 | #endif |
| 354 | #ifdef CURL_CA_PATH |
| 355 | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH_PROXY]) { |
| 356 | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], |
| 357 | CURL_CA_PATH); |
| 358 | if(result) |
| 359 | return result; |
| 360 | } |
| 361 | #endif |
| 362 | #ifdef CURL_CA_BUNDLE |
| 363 | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE_PROXY]) { |
| 364 | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], |
| 365 | CURL_CA_BUNDLE); |
| 366 | if(result) |
| 367 | return result; |
| 368 | } |
| 369 | #endif |
| 370 | } |
| 371 | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; |
| 372 | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; |
| 373 | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; |
| 374 | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; |
| 375 | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; |
| 376 | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; |
| 377 | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO_PROXY]; |
| 378 | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; |
| 379 | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; |
| 380 | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; |
| 381 | sslc->cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; |
| 382 | sslc->key = data->set.str[STRING_KEY_PROXY]; |
| 383 | sslc->key_type = data->set.str[STRING_KEY_TYPE_PROXY]; |
| 384 | sslc->key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; |
| 385 | sslc->primary.clientcert = data->set.str[STRING_CERT_PROXY]; |
| 386 | sslc->key_blob = data->set.blobs[BLOB_KEY_PROXY]; |
| 387 | #ifdef USE_TLS_SRP |
| 388 | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; |
| 389 | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; |
| 390 | #endif |
| 391 | #endif /* CURL_DISABLE_PROXY */ |
| 392 | |
| 393 | return CURLE_OK; |
| 394 | } |
Show 4 lines (not cited by the judge)
| 818 | CURLcode curl_easy_perform(CURL *curl) |
| 819 | { |
| 820 | return easy_perform(curl, FALSE); |
| 821 | } |
Show 18 lines (not cited by the judge)
| 2945 | CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...) |
| 2946 | { |
| 2947 | va_list arg; |
| 2948 | CURLcode result; |
| 2949 | struct Curl_easy *data = curl; |
| 2950 | |
| 2951 | if(!data) |
| 2952 | return CURLE_BAD_FUNCTION_ARGUMENT; |
| 2953 | |
| 2954 | va_start(arg, option); |
| 2955 | |
| 2956 | result = Curl_vsetopt(data, option, arg); |
| 2957 | |
| 2958 | va_end(arg); |
| 2959 | if(result == CURLE_BAD_FUNCTION_ARGUMENT) |
| 2960 | failf(data, "setopt 0x%x got bad argument", option); |
| 2961 | return result; |
| 2962 | } |
Show 24 lines (not cited by the judge)
| 788 | static CURLcode init_config_builder_platform_verifier( |
| 789 | struct Curl_easy *data, |
| 790 | struct rustls_client_config_builder *builder) |
| 791 | { |
| 792 | struct rustls_server_cert_verifier *server_cert_verifier = NULL; |
| 793 | CURLcode result = CURLE_OK; |
| 794 | rustls_result rr; |
| 795 | |
| 796 | rr = rustls_platform_server_cert_verifier(&server_cert_verifier); |
| 797 | if(rr != RUSTLS_RESULT_OK) { |
| 798 | rustls_failf(data, rr, "failed to create platform certificate verifier"); |
| 799 | result = CURLE_SSL_CACERT_BADFILE; |
| 800 | goto cleanup; |
| 801 | } |
| 802 | |
| 803 | rustls_client_config_builder_set_server_verifier(builder, |
| 804 | server_cert_verifier); |
| 805 | |
| 806 | cleanup: |
| 807 | if(server_cert_verifier) { |
| 808 | rustls_server_cert_verifier_free(server_cert_verifier); |
| 809 | } |
| 810 | return result; |
| 811 | } |
Show 85 lines (not cited by the judge)
| 702 | static CURLcode |
| 703 | init_config_builder_verifier(struct Curl_easy *data, |
| 704 | struct rustls_client_config_builder *builder, |
| 705 | const struct ssl_primary_config *conn_config, |
| 706 | const struct curl_blob *ca_info_blob, |
| 707 | const char * const ssl_cafile) |
| 708 | { |
| 709 | const struct rustls_root_cert_store *roots = NULL; |
| 710 | struct rustls_root_cert_store_builder *roots_builder = NULL; |
| 711 | struct rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL; |
| 712 | struct rustls_server_cert_verifier *server_cert_verifier = NULL; |
| 713 | rustls_result rr = RUSTLS_RESULT_OK; |
| 714 | CURLcode result = CURLE_OK; |
| 715 | |
| 716 | roots_builder = rustls_root_cert_store_builder_new(); |
| 717 | if(ca_info_blob) { |
| 718 | rr = rustls_root_cert_store_builder_add_pem(roots_builder, |
| 719 | ca_info_blob->data, |
| 720 | ca_info_blob->len, |
| 721 | 1); |
| 722 | if(rr != RUSTLS_RESULT_OK) { |
| 723 | rustls_failf(data, rr, "failed to parse trusted certificates from blob"); |
| 724 | result = CURLE_SSL_CACERT_BADFILE; |
| 725 | goto cleanup; |
| 726 | } |
| 727 | } |
| 728 | else if(ssl_cafile) { |
| 729 | rr = rustls_root_cert_store_builder_load_roots_from_file(roots_builder, |
| 730 | ssl_cafile, |
| 731 | 1); |
| 732 | if(rr != RUSTLS_RESULT_OK) { |
| 733 | rustls_failf(data, rr, "failed to load trusted certificates"); |
| 734 | result = CURLE_SSL_CACERT_BADFILE; |
| 735 | goto cleanup; |
| 736 | } |
| 737 | } |
| 738 | |
| 739 | rr = rustls_root_cert_store_builder_build(roots_builder, &roots); |
| 740 | if(rr != RUSTLS_RESULT_OK) { |
| 741 | rustls_failf(data, rr, "failed to build trusted root certificate store"); |
| 742 | result = CURLE_SSL_CACERT_BADFILE; |
| 743 | goto cleanup; |
| 744 | } |
| 745 | |
| 746 | verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(roots); |
| 747 | if(!verifier_builder) { |
| 748 | result = CURLE_OUT_OF_MEMORY; |
| 749 | goto cleanup; |
| 750 | } |
| 751 | |
| 752 | if(conn_config->CRLfile) { |
| 753 | result = init_config_builder_verifier_crl(data, |
| 754 | conn_config, |
| 755 | verifier_builder); |
| 756 | if(result) { |
| 757 | goto cleanup; |
| 758 | } |
| 759 | } |
| 760 | |
| 761 | rr = rustls_web_pki_server_cert_verifier_builder_build( |
| 762 | verifier_builder, &server_cert_verifier); |
| 763 | if(rr != RUSTLS_RESULT_OK) { |
| 764 | rustls_failf(data, rr, "failed to build certificate verifier"); |
| 765 | result = CURLE_SSL_CACERT_BADFILE; |
| 766 | goto cleanup; |
| 767 | } |
| 768 | |
| 769 | rustls_client_config_builder_set_server_verifier(builder, |
| 770 | server_cert_verifier); |
| 771 | cleanup: |
| 772 | if(roots_builder) { |
| 773 | rustls_root_cert_store_builder_free(roots_builder); |
| 774 | } |
| 775 | if(roots) { |
| 776 | rustls_root_cert_store_free(roots); |
| 777 | } |
| 778 | if(verifier_builder) { |
| 779 | rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); |
| 780 | } |
| 781 | if(server_cert_verifier) { |
| 782 | rustls_server_cert_verifier_free(server_cert_verifier); |
| 783 | } |
| 784 | |
| 785 | return result; |
| 786 | } |