✓ProveIt
Examples / Report #2416725 Saved analysis

CVE-2024-2466: TLS certificate check bypass with mbedTLS

curl · 2024-03-1416.6s analysis · $0.029 in model calls

What the report claims

Curl library bypasses TLS certificate name check when connecting via IP address, allowing spoofing attacks.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2024-2466 TLS certificate check bypass with mbedTLS

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Judgment withdrawn. The answer failed the evidence check.
See the withdrawn model reasoning

The following reasoning failed the citation check and does not support the final finding.

  • Curl_ssl_peer_init only sets peer->sni for DNS hostnames (lines 1589-1603 in lib/vtls/vtls.c), leaving it NULL for IP addresses
  • mbed_connect_step1 (per report and grounded symbols) only calls mbedtls_ssl_set_hostname when peer->sni is set
  • mbedTLS documentation explicitly states mbedtls_ssl_set_hostname is required for CN/SAN verification even without SNI
  • This bypasses server certificate host verification, enabling spoofing with valid certificates for other domains (CWE-297)
  • The bug was previously fixed for CVE-2016-3739 but reintroduced by later refactoring per the commit history analysis
How this analysis ran 5 claims · 10 citations verified

Evidence check: judge quoted an external source that does not say that (https://mbed-tls.readthedocs.io/en/latest/kb/attacks/ssl_set_hostname)

Checked against curl master on 2024-03-14 (09f367977af2). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
partially grounded
no model · 29 references checked out, 2 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 5196 tokens · $0.0004
3 · Evidence
9 code snippets
real curl source at 09f367977af2 · 4 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
21696 tokens · 13.9s · $0.0289
5 · Receipts
10 of 14 citations verified
every citation must point at code the judge was shown
Inspect the withdrawn draft reply

This draft belongs to the withdrawn judgment. It may contain unsupported claims.

Thank you for the detailed report and reproduction steps. The issue is confirmed: when connecting via IP address, peer->sni is not set (lib/vtls/vtls.c:1589-1603), so mbedtls_ssl_set_hostname is not called in mbed_connect_step1, bypassing CN/SAN verification. mbedTLS documentation confirms this function must be called for host verification regardless of SNI usage. This reintroduces CVE-2016-3739. We will fix by calling mbedtls_ssl_set_hostname with peer->hostname even when sni is NULL.

Inspect all claims and source code 5 claims · 9 code excerpts

This model judgment was withdrawn. The claim assessments below are preserved for inspection and may be wrong.

Report claims

C1flaw supported

mbedtls_ssl_set_hostname is not called when SNI is not set, causing server certificate name verification to be bypassed

Read the reasoning

Curl_ssl_peer_init only sets peer->sni for DNS hostnames (not IP addresses). The report states mbed_connect_step1 only calls mbedtls_ssl_set_hostname when peer->sni is set. External mbedTLS documentation confirms mbedtls_ssl_set_hostname is required for CN/SAN verification regardless of SNI usage. The deterministic checks confirm the symbols exist and the core quoted lines appear in the codebase.

C2location supported

lib/vtls/mbedtls.c in function mbed_connect_step1

Read the reasoning

The function mbed_connect_step1 exists in lib/vtls/mbedtls.c at the expected location per deterministic checks.

lib/vtls/mbedtls.c:358 09f367977af2:0
C3trigger supported

connecting to a host by its IP address instead of its DNS name

Read the reasoning

The peer type enum values for IP addresses exist and are used in get_peer_type to classify IP hostnames, which then prevents sni from being set.

C4impact supported

SSL handshake completes without verifying the server's certificate against the host name, enabling spoofing

Read the reasoning

External sources confirm that skipping mbedtls_ssl_set_hostname bypasses CN/SAN verification, enabling spoofing/impersonation attacks with valid certificates for different domains.

C5reproduction supported

Use curl with an IP address (e.g., curl https://93.184.216.34) and observe that no certificate verification error is raised

Read the reasoning

The reproduction steps are concrete: connecting via IP address triggers the code path where sni is NULL, so mbedtls_ssl_set_hostname is not called, and the handshake succeeds without host verification.

Deterministic checks that failed

  • quote 4 of 10 quoted lines appear nowhere in curl, e.g. 'char *hostname; /* hostname for verification */'
  • quote 2 of 5 quoted lines appear nowhere in curl, e.g. 'if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) {'

What the report says about other projects

confirmed mbedtls_ssl_set_hostname must be called for server name verification even when SNI is not used, as it also sets the name for CN/SAN checks

“mbedtls_ssl_set_hostname() must be called for server name verification even when SNI is not used, as it also sets the name for CN/SAN checks.” source

confirmed If no server host name was specified, every host name was accepted. This is an example of an insecure default weakness (CWE-1188).

“Historically, Mbed TLS did not require mbedtls_ssl_set_hostname() to be called. If no server host name was specified, every host name was accepted. This is an example of an insecure default weakness (CWE-1188).” source

confirmed The end certificate must be issued for the server that the client is trying to reach. Mbed TLS checks that the certificate content matches the name passed to mbedtls_ssl_set_hostname().

“The end certificate must be issued for the server that the client is trying to reach. Mbed TLS checks that the certificate content matches the name passed to mbedtls_ssl_set_hostname().” source

Read the original report (excerpt)

Full report on HackerOne ↗

## Summary: Curl library has a security vulnerability where the certificate name check is bypassed when connecting to a host via its IP address. This could potentially introduce spoofing attacks or unauthorized access due to unverified server certificate. This issue only affects the Curl with MbedTLS. - Affected versions: from libcurl 8.5.0 to and including 8.6.0 (current master versions at the time of writing) - Not affected versions: libcurl 8.4.0 and earlier This issue affect all kinds of protocol over TLS session, e.g. HTTPS, FTPS, SMTPS, etc. ## Steps To Reproduce: ### (Preparation) Download and build the Curl with MbedTLS: *Skip this step if you already have the Curl (>= 8.5.0) with MbedTLS.* Before building the code, make sure you have environment to build the code in Linux, `sudo apt install build-essential`. 1. Get and extract the code: ```shell wget https://curl.se/download/curl-8.6.0.tar.gz -O curl-8.6.0.tar.gz wget https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v2.28.7.tar.gz -O mbedtls-2.28.7.tar.gz tar zxf curl-8.6.0.tar.gz tar zxf mbedtls-2.28.7.tar.gz ``` 2. Build MbedTLS: ```shell cd mbedtls-2.28.7 make SHARED=1 -j$(nproc) sudo make install DESTDIR=/usr/local/lib ``` 3. Build Curl with MbedTLS: ```shell cd curl-8.6.0 export LD_LIBRARY_PATH=/usr/local/lib export PATH=/usr/local/lib:$PATH ./configure --with-mbedtls=/usr/local --without-libpsl make -j$(nproc) CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" ``` ### Reproduce the issue via Curl CLI: If you build the Curl with MbedTLS from above, you should export the `LD_LIBRARY_PATH` and `PATH` to use the built Curl. ```shell export LD_LIBRARY_PATH=/usr/local/lib export PATH=/usr/local/lib:$PATH ``` 1. Check the version of the Curl: ```shell $ curl --version curl 8.6.0 (x86_64-pc-linux-gnu) libcurl/8.6.0 mbedTLS/2.28.7 zlib/1.2.11 libidn2/2.2.0 Release-Date: 2024-01-31 Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: alt-svc AsynchDNS HSTS HTTPS-proxy IDN IPv6 Largefile libz NTLM SSL threadsafe UnixSockets ``` 2. Get IP from an example https server and use it to connect: ```shell $ host -t A www.example.org www.example.org has address 93.184.216.34 $ curl https://93.184.216.34 <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Trans …

Source code

lib/vtls/mbedtls.clines 358–518 · definition of mbed_connect_step1 (truncated)
358static CURLcode
C2: mbed_connect_step1 function definition starts here
359mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
360{
361 struct ssl_connect_data *connssl = cf->ctx;
362 struct mbed_ssl_backend_data *backend =
363 (struct mbed_ssl_backend_data *)connssl->backend;
364 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
365 const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
366 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
367 const char * const ssl_cafile =
368 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
369 (ca_info_blob ? NULL : conn_config->CAfile);
370 const bool verifypeer = conn_config->verifypeer;
371 const char * const ssl_capath = conn_config->CApath;
372 char * const ssl_cert = ssl_config->primary.clientcert;
373 const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
374 const char * const ssl_crlfile = ssl_config->primary.CRLfile;
375 const char *hostname = connssl->peer.hostname;
376 int ret = -1;
377 char errorbuf[128];
378
379 DEBUGASSERT(backend);
380
381 if((conn_config->version == CURL_SSLVERSION_SSLv2) ||
382 (conn_config->version == CURL_SSLVERSION_SSLv3)) {
383 failf(data, "Not supported SSL version");
384 return CURLE_NOT_BUILT_IN;
385 }
386
387#ifdef THREADING_SUPPORT
388 mbedtls_ctr_drbg_init(&backend->ctr_drbg);
389
390 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
391 &ts_entropy, NULL, 0);
392 if(ret) {
393 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
394 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
395 -ret, errorbuf);
396 return CURLE_FAILED_INIT;
397 }
398#else
399 mbedtls_entropy_init(&backend->entropy);
400 mbedtls_ctr_drbg_init(&backend->ctr_drbg);
401
402 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
403 &backend->entropy, NULL, 0);
404 if(ret) {
405 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
406 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
407 -ret, errorbuf);
408 return CURLE_FAILED_INIT;
409 }
410#endif /* THREADING_SUPPORT */
411
412 /* Load the trusted CA */
413 mbedtls_x509_crt_init(&backend->cacert);
414
415 if(ca_info_blob && verifypeer) {
416 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
417 terminated even when provided the exact length, forcing us to waste
418 extra memory here. */
419 unsigned char *newblob = Curl_memdup0(ca_info_blob->data,
420 ca_info_blob->len);
421 if(!newblob)
422 return CURLE_OUT_OF_MEMORY;
423 ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
424 ca_info_blob->len + 1);
425 free(newblob);
426 if(ret<0) {
427 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
428 failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
429 -ret, errorbuf);
430 return CURLE_SSL_CERTPROBLEM;
431 }
432 }
433
434 if(ssl_cafile && verifypeer) {
435#ifdef MBEDTLS_FS_IO
436 ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
437
438 if(ret<0) {
439 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
440 failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
441 ssl_cafile, -ret, errorbuf);
442 return CURLE_SSL_CACERT_BADFILE;
443 }
444#else
445 failf(data, "mbedtls: functions that use the filesystem not built in");
446 return CURLE_NOT_BUILT_IN;
447#endif
448 }
449
450 if(ssl_capath) {
451#ifdef MBEDTLS_FS_IO
452 ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath);
453
454 if(ret<0) {
455 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
456 failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
457 ssl_capath, -ret, errorbuf);
458
459 if(verifypeer)
460 return CURLE_SSL_CACERT_BADFILE;
461 }
462#else
463 failf(data, "mbedtls: functions that use the filesystem not built in");
464 return CURLE_NOT_BUILT_IN;
465#endif
466 }
467
468 /* Load the client certificate */
469 mbedtls_x509_crt_init(&backend->clicert);
470
471 if(ssl_cert) {
472#ifdef MBEDTLS_FS_IO
473 ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert);
474
475 if(ret) {
476 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
477 failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
478 ssl_cert, -ret, errorbuf);
479
480 return CURLE_SSL_CERTPROBLEM;
481 }
482#else
483 failf(data, "mbedtls: functions that use the filesystem not built in");
484 return CURLE_NOT_BUILT_IN;
485#endif
486 }
487
488 if(ssl_cert_blob) {
489 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
490 terminated even when provided the exact length, forcing us to waste
491 extra memory here. */
492 unsigned char *newblob = Curl_memdup0(ssl_cert_blob->data,
493 ssl_cert_blob->len);
494 if(!newblob)
495 return CURLE_OUT_OF_MEMORY;
496 ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
497 ssl_cert_blob->len + 1);
498 free(newblob);
499
500 if(ret) {
501 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
502 failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
503 ssl_config->key, -ret, errorbuf);
504 return CURLE_SSL_CERTPROBLEM;
505 }
506 }
507
508 /* Load the client private key */
509 mbedtls_pk_init(&backend->pk);
510
511 if(ssl_config->key || ssl_config->key_blob) {
512 if(ssl_config->key) {
513#ifdef MBEDTLS_FS_IO
514#if MBEDTLS_VERSION_NUMBER >= 0x03000000
515 ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
516 ssl_config->key_passwd,
517 mbedtls_ctr_drbg_random,
518 &backend->ctr_drbg);
lib/vtls/vtls.clines 1552–1619 · definition of Curl_ssl_peer_init
1552CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, struct Curl_cfilter *cf)
1553{
1554 struct ssl_connect_data *connssl = cf->ctx;
1555 const char *ehostname, *edispname;
1556 int eport;
1557
1558 /* We need the hostname for SNI negotiation. Once handshaked, this
1559 * remains the SNI hostname for the TLS connection. But when the
1560 * connection is reused, the settings in cf->conn might change.
1561 * So we keep a copy of the hostname we use for SNI.
1562 */
1563#ifndef CURL_DISABLE_PROXY
1564 if(Curl_ssl_cf_is_proxy(cf)) {
1565 ehostname = cf->conn->http_proxy.host.name;
1566 edispname = cf->conn->http_proxy.host.dispname;
1567 eport = cf->conn->http_proxy.port;
1568 }
1569 else
1570#endif
1571 {
1572 ehostname = cf->conn->host.name;
1573 edispname = cf->conn->host.dispname;
1574 eport = cf->conn->remote_port;
1575 }
1576
1577 /* change if ehostname changed */
1578 DEBUGASSERT(!ehostname || ehostname[0]);
1579 if(ehostname && (!peer->hostname
1580 || strcmp(ehostname, peer->hostname))) {
1581 Curl_ssl_peer_cleanup(peer);
1582 peer->hostname = strdup(ehostname);
1583 if(!peer->hostname) {
1584 Curl_ssl_peer_cleanup(peer);
1585 return CURLE_OUT_OF_MEMORY;
1586 }
1587 if(!edispname || !strcmp(ehostname, edispname))
1588 peer->dispname = peer->hostname;
1589 else {
C1: sni only allocated when !peer->is_ip_address
C5: IP address hostnames skip sni allocation, leading to missing mbedtls_ssl_set_hostname call
1590 peer->dispname = strdup(edispname);
1591 if(!peer->dispname) {
1592 Curl_ssl_peer_cleanup(peer);
1593 return CURLE_OUT_OF_MEMORY;
1594 }
1595 }
1596
C1: peer->sni = calloc(...) only for DNS names
1597 peer->sni = NULL;
C1: peer->sni = NULL; initialized to NULL
1598 peer->type = get_peer_type(peer->hostname);
C1: peer->is_ip_address set based on hostname
1599 if(peer->type == CURL_SSL_PEER_DNS && peer->hostname[0]) {
1600 /* not an IP address, normalize according to RCC 6066 ch. 3,
1601 * max len of SNI is 2^16-1, no trailing dot */
1602 size_t len = strlen(peer->hostname);
1603 if(len && (peer->hostname[len-1] == '.'))
1604 len--;
1605 if(len < USHRT_MAX) {
1606 peer->sni = calloc(1, len + 1);
1607 if(!peer->sni) {
1608 Curl_ssl_peer_cleanup(peer);
1609 return CURLE_OUT_OF_MEMORY;
1610 }
1611 Curl_strntolower(peer->sni, peer->hostname, len);
1612 peer->sni[len] = 0;
1613 }
1614 }
1615
1616 }
1617 connssl->port = eport;
1618 return CURLE_OK;
1619}
lib/vtls/vtls.clines 1533–1550 · definition of get_peer_type
1533static ssl_peer_type get_peer_type(const char *hostname)
1534{
1535 if(hostname && hostname[0]) {
1536#ifdef ENABLE_IPV6
1537 struct in6_addr addr;
1538#else
1539 struct in_addr addr;
1540#endif
1541 if(Curl_inet_pton(AF_INET, hostname, &addr))
C3: CURL_SSL_PEER_IPV4 returned for IPv4 addresses
1542 return CURL_SSL_PEER_IPV4;
1543#ifdef ENABLE_IPV6
1544 else if(Curl_inet_pton(AF_INET6, hostname, &addr)) {
1545 return CURL_SSL_PEER_IPV6;
C3: CURL_SSL_PEER_IPV6 returned for IPv6 addresses
1546 }
1547#endif
1548 }
1549 return CURL_SSL_PEER_DNS;
1550}
lib/vtls/mbedtls.c@curl-8_6_0lines 324–484 · definition of mbed_connect_step1 as in release curl-8_6_0; differs from master; commits that changed it since: 942896fdd1 mbedtls: properly cleanup the thread-shared entropy
Show 161 lines (not cited by the judge)
324static CURLcode
325mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
326{
327 struct ssl_connect_data *connssl = cf->ctx;
328 struct mbed_ssl_backend_data *backend =
329 (struct mbed_ssl_backend_data *)connssl->backend;
330 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
331 const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
332 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
333 const char * const ssl_cafile =
334 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
335 (ca_info_blob ? NULL : conn_config->CAfile);
336 const bool verifypeer = conn_config->verifypeer;
337 const char * const ssl_capath = conn_config->CApath;
338 char * const ssl_cert = ssl_config->primary.clientcert;
339 const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
340 const char * const ssl_crlfile = ssl_config->primary.CRLfile;
341 const char *hostname = connssl->peer.hostname;
342 int ret = -1;
343 char errorbuf[128];
344
345 DEBUGASSERT(backend);
346
347 if((conn_config->version == CURL_SSLVERSION_SSLv2) ||
348 (conn_config->version == CURL_SSLVERSION_SSLv3)) {
349 failf(data, "Not supported SSL version");
350 return CURLE_NOT_BUILT_IN;
351 }
352
353#ifdef THREADING_SUPPORT
354 entropy_init_mutex(&ts_entropy);
355 mbedtls_ctr_drbg_init(&backend->ctr_drbg);
356
357 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
358 &ts_entropy, NULL, 0);
359 if(ret) {
360 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
361 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
362 -ret, errorbuf);
363 return CURLE_FAILED_INIT;
364 }
365#else
366 mbedtls_entropy_init(&backend->entropy);
367 mbedtls_ctr_drbg_init(&backend->ctr_drbg);
368
369 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
370 &backend->entropy, NULL, 0);
371 if(ret) {
372 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
373 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
374 -ret, errorbuf);
375 return CURLE_FAILED_INIT;
376 }
377#endif /* THREADING_SUPPORT */
378
379 /* Load the trusted CA */
380 mbedtls_x509_crt_init(&backend->cacert);
381
382 if(ca_info_blob && verifypeer) {
383 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
384 terminated even when provided the exact length, forcing us to waste
385 extra memory here. */
386 unsigned char *newblob = Curl_memdup0(ca_info_blob->data,
387 ca_info_blob->len);
388 if(!newblob)
389 return CURLE_OUT_OF_MEMORY;
390 ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
391 ca_info_blob->len + 1);
392 free(newblob);
393 if(ret<0) {
394 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
395 failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
396 -ret, errorbuf);
397 return CURLE_SSL_CERTPROBLEM;
398 }
399 }
400
401 if(ssl_cafile && verifypeer) {
402#ifdef MBEDTLS_FS_IO
403 ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
404
405 if(ret<0) {
406 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
407 failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
408 ssl_cafile, -ret, errorbuf);
409 return CURLE_SSL_CACERT_BADFILE;
410 }
411#else
412 failf(data, "mbedtls: functions that use the filesystem not built in");
413 return CURLE_NOT_BUILT_IN;
414#endif
415 }
416
417 if(ssl_capath) {
418#ifdef MBEDTLS_FS_IO
419 ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath);
420
421 if(ret<0) {
422 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
423 failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
424 ssl_capath, -ret, errorbuf);
425
426 if(verifypeer)
427 return CURLE_SSL_CACERT_BADFILE;
428 }
429#else
430 failf(data, "mbedtls: functions that use the filesystem not built in");
431 return CURLE_NOT_BUILT_IN;
432#endif
433 }
434
435 /* Load the client certificate */
436 mbedtls_x509_crt_init(&backend->clicert);
437
438 if(ssl_cert) {
439#ifdef MBEDTLS_FS_IO
440 ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert);
441
442 if(ret) {
443 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
444 failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
445 ssl_cert, -ret, errorbuf);
446
447 return CURLE_SSL_CERTPROBLEM;
448 }
449#else
450 failf(data, "mbedtls: functions that use the filesystem not built in");
451 return CURLE_NOT_BUILT_IN;
452#endif
453 }
454
455 if(ssl_cert_blob) {
456 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
457 terminated even when provided the exact length, forcing us to waste
458 extra memory here. */
459 unsigned char *newblob = Curl_memdup0(ssl_cert_blob->data,
460 ssl_cert_blob->len);
461 if(!newblob)
462 return CURLE_OUT_OF_MEMORY;
463 ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
464 ssl_cert_blob->len + 1);
465 free(newblob);
466
467 if(ret) {
468 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
469 failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
470 ssl_config->key, -ret, errorbuf);
471 return CURLE_SSL_CERTPROBLEM;
472 }
473 }
474
475 /* Load the client private key */
476 mbedtls_pk_init(&backend->pk);
477
478 if(ssl_config->key || ssl_config->key_blob) {
479 if(ssl_config->key) {
480#ifdef MBEDTLS_FS_IO
481#if MBEDTLS_VERSION_NUMBER >= 0x03000000
482 ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
483 ssl_config->key_passwd,
484 mbedtls_ctr_drbg_random,
lib/vtls/vtls.clines 1512–1520 · definition of Curl_ssl_peer_cleanup
Show 9 lines (not cited by the judge)
1512void Curl_ssl_peer_cleanup(struct ssl_peer *peer)
1513{
1514 if(peer->dispname != peer->hostname)
1515 free(peer->dispname);
1516 free(peer->sni);
1517 free(peer->hostname);
1518 peer->hostname = peer->sni = peer->dispname = NULL;
1519 peer->type = CURL_SSL_PEER_DNS;
1520}
lib/vtls/vtls.c@curl-8_6_0lines 1508–1516 · definition of Curl_ssl_peer_cleanup as in release curl-8_6_0; differs from master; commits that changed it since: e87751d69a vtls: fix tls proxy peer verification
Show 9 lines (not cited by the judge)
1508void Curl_ssl_peer_cleanup(struct ssl_peer *peer)
1509{
1510 if(peer->dispname != peer->hostname)
1511 free(peer->dispname);
1512 free(peer->sni);
1513 free(peer->hostname);
1514 peer->hostname = peer->sni = peer->dispname = NULL;
1515 peer->is_ip_address = FALSE;
1516}
lib/vtls/vtls.c@curl-8_6_0lines 1543–1609 · definition of Curl_ssl_peer_init as in release curl-8_6_0; differs from master; commits that changed it since: e87751d69a vtls: fix tls proxy peer verification
Show 67 lines (not cited by the judge)
1543CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, struct Curl_cfilter *cf)
1544{
1545 struct ssl_connect_data *connssl = cf->ctx;
1546 const char *ehostname, *edispname;
1547 int eport;
1548
1549 /* We need the hostname for SNI negotiation. Once handshaked, this
1550 * remains the SNI hostname for the TLS connection. But when the
1551 * connection is reused, the settings in cf->conn might change.
1552 * So we keep a copy of the hostname we use for SNI.
1553 */
1554#ifndef CURL_DISABLE_PROXY
1555 if(Curl_ssl_cf_is_proxy(cf)) {
1556 ehostname = cf->conn->http_proxy.host.name;
1557 edispname = cf->conn->http_proxy.host.dispname;
1558 eport = cf->conn->http_proxy.port;
1559 }
1560 else
1561#endif
1562 {
1563 ehostname = cf->conn->host.name;
1564 edispname = cf->conn->host.dispname;
1565 eport = cf->conn->remote_port;
1566 }
1567
1568 /* change if ehostname changed */
1569 if(ehostname && (!peer->hostname
1570 || strcmp(ehostname, peer->hostname))) {
1571 Curl_ssl_peer_cleanup(peer);
1572 peer->hostname = strdup(ehostname);
1573 if(!peer->hostname) {
1574 Curl_ssl_peer_cleanup(peer);
1575 return CURLE_OUT_OF_MEMORY;
1576 }
1577 if(!edispname || !strcmp(ehostname, edispname))
1578 peer->dispname = peer->hostname;
1579 else {
1580 peer->dispname = strdup(edispname);
1581 if(!peer->dispname) {
1582 Curl_ssl_peer_cleanup(peer);
1583 return CURLE_OUT_OF_MEMORY;
1584 }
1585 }
1586
1587 peer->sni = NULL;
1588 peer->is_ip_address = is_ip_address(peer->hostname)? TRUE : FALSE;
1589 if(peer->hostname[0] && !peer->is_ip_address) {
1590 /* not an IP address, normalize according to RCC 6066 ch. 3,
1591 * max len of SNI is 2^16-1, no trailing dot */
1592 size_t len = strlen(peer->hostname);
1593 if(len && (peer->hostname[len-1] == '.'))
1594 len--;
1595 if(len < USHRT_MAX) {
1596 peer->sni = calloc(1, len + 1);
1597 if(!peer->sni) {
1598 Curl_ssl_peer_cleanup(peer);
1599 return CURLE_OUT_OF_MEMORY;
1600 }
1601 Curl_strntolower(peer->sni, peer->hostname, len);
1602 peer->sni[len] = 0;
1603 }
1604 }
1605
1606 }
1607 connssl->port = eport;
1608 return CURLE_OK;
1609}
lib/strcase.clines 164–172 · definition of Curl_strntolower
Show 9 lines (not cited by the judge)
164void Curl_strntolower(char *dest, const char *src, size_t n)
165{
166 if(n < 1)
167 return;
168
169 do {
170 *dest++ = Curl_raw_tolower(*src);
171 } while(*src++ && --n);
172}
lib/curl_trc.hlines 63–63 · definition of failf
Show 1 lines (not cited by the judge)
63#define failf Curl_failf