mbedtls.c (50115B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * Copyright (C) Hoi-Ho Chan, <hoiho.chan@gmail.com> 10 * 11 * This software is licensed as described in the file COPYING, which 12 * you should have received as part of this distribution. The terms 13 * are also available at https://curl.se/docs/copyright.html. 14 * 15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 16 * copies of the Software, and permit persons to whom the Software is 17 * furnished to do so, under the terms of the COPYING file. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 * SPDX-License-Identifier: curl 23 * 24 ***************************************************************************/ 25 26 /* 27 * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code 28 * but vtls.c should ever call or use these functions. 29 * 30 */ 31 32 #include "../curl_setup.h" 33 34 #ifdef USE_MBEDTLS 35 36 /* Define this to enable lots of debugging for mbedTLS */ 37 /* #define MBEDTLS_DEBUG */ 38 39 #include <mbedtls/version.h> 40 #if MBEDTLS_VERSION_NUMBER >= 0x02040000 41 #include <mbedtls/net_sockets.h> 42 #else 43 #include <mbedtls/net.h> 44 #endif 45 #include <mbedtls/ssl.h> 46 #include <mbedtls/x509.h> 47 48 #include <mbedtls/error.h> 49 #include <mbedtls/entropy.h> 50 #include <mbedtls/ctr_drbg.h> 51 #include <mbedtls/sha256.h> 52 53 #if MBEDTLS_VERSION_MAJOR >= 2 54 # ifdef MBEDTLS_DEBUG 55 # include <mbedtls/debug.h> 56 # endif 57 #endif /* MBEDTLS_VERSION_MAJOR >= 2 */ 58 59 #include "cipher_suite.h" 60 #include "../urldata.h" 61 #include "../sendf.h" 62 #include "../curlx/inet_pton.h" 63 #include "mbedtls.h" 64 #include "vtls.h" 65 #include "vtls_int.h" 66 #include "vtls_scache.h" 67 #include "x509asn1.h" 68 #include "../parsedate.h" 69 #include "../connect.h" /* for the connect timeout */ 70 #include "../select.h" 71 #include "../multiif.h" 72 #include "mbedtls_threadlock.h" 73 #include "../strdup.h" 74 75 /* The last 3 #include files should be in this order */ 76 #include "../curl_printf.h" 77 #include "../curl_memory.h" 78 #include "../memdebug.h" 79 80 /* ALPN for http2 */ 81 #if defined(USE_HTTP2) && defined(MBEDTLS_SSL_ALPN) 82 # define HAS_ALPN_MBEDTLS 83 #endif 84 85 struct mbed_ssl_backend_data { 86 mbedtls_ctr_drbg_context ctr_drbg; 87 mbedtls_entropy_context entropy; 88 mbedtls_ssl_context ssl; 89 mbedtls_x509_crt cacert; 90 mbedtls_x509_crt clicert; 91 #ifdef MBEDTLS_X509_CRL_PARSE_C 92 mbedtls_x509_crl crl; 93 #endif 94 mbedtls_pk_context pk; 95 mbedtls_ssl_config config; 96 #ifdef HAS_ALPN_MBEDTLS 97 const char *protocols[3]; 98 #endif 99 int *ciphersuites; 100 size_t send_blocked_len; 101 BIT(initialized); /* mbedtls_ssl_context is initialized */ 102 BIT(sent_shutdown); 103 BIT(send_blocked); 104 }; 105 106 /* apply threading? */ 107 #if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ 108 defined(_WIN32) 109 #define HAS_THREADING_SUPPORT 110 #endif 111 112 #ifndef MBEDTLS_ERROR_C 113 #define mbedtls_strerror(a,b,c) b[0] = 0 114 #endif 115 116 /* PSA can be used independently of TLS 1.3 */ 117 #if defined(MBEDTLS_USE_PSA_CRYPTO) && MBEDTLS_VERSION_NUMBER >= 0x03060000 118 #define HAS_PSA_SUPPORT 119 #endif 120 121 #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && MBEDTLS_VERSION_NUMBER >= 0x03060000 122 #define HAS_TLS13_SUPPORT 123 #endif 124 125 #if defined(HAS_TLS13_SUPPORT) && defined(MBEDTLS_SSL_SESSION_TICKETS) 126 #define HAS_SESSION_TICKETS 127 #endif 128 129 #ifdef HAS_THREADING_SUPPORT 130 static mbedtls_entropy_context ts_entropy; 131 132 static int entropy_init_initialized = 0; 133 134 static void entropy_init_mutex(mbedtls_entropy_context *ctx) 135 { 136 /* lock 0 = entropy_init_mutex() */ 137 Curl_mbedtlsthreadlock_lock_function(0); 138 if(entropy_init_initialized == 0) { 139 mbedtls_entropy_init(ctx); 140 entropy_init_initialized = 1; 141 } 142 Curl_mbedtlsthreadlock_unlock_function(0); 143 } 144 145 static void entropy_cleanup_mutex(mbedtls_entropy_context *ctx) 146 { 147 /* lock 0 = use same lock as init */ 148 Curl_mbedtlsthreadlock_lock_function(0); 149 if(entropy_init_initialized == 1) { 150 mbedtls_entropy_free(ctx); 151 entropy_init_initialized = 0; 152 } 153 Curl_mbedtlsthreadlock_unlock_function(0); 154 } 155 156 static int entropy_func_mutex(void *data, unsigned char *output, size_t len) 157 { 158 int ret; 159 /* lock 1 = entropy_func_mutex() */ 160 Curl_mbedtlsthreadlock_lock_function(1); 161 ret = mbedtls_entropy_func(data, output, len); 162 Curl_mbedtlsthreadlock_unlock_function(1); 163 164 return ret; 165 } 166 167 #endif /* HAS_THREADING_SUPPORT */ 168 169 #ifdef MBEDTLS_DEBUG 170 static void mbed_debug(void *context, int level, const char *f_name, 171 int line_nb, const char *line) 172 { 173 struct Curl_easy *data = (struct Curl_easy *)context; 174 (void) level; 175 (void) line_nb; 176 (void) f_name; 177 178 if(data) { 179 size_t len = strlen(line); 180 if(len && (line[len - 1] == '\n')) 181 /* discount any trailing newline */ 182 len--; 183 infof(data, "%.*s", (int)len, line); 184 } 185 } 186 #endif 187 188 static int mbedtls_bio_cf_write(void *bio, 189 const unsigned char *buf, size_t blen) 190 { 191 struct Curl_cfilter *cf = bio; 192 struct Curl_easy *data = CF_DATA_CURRENT(cf); 193 size_t nwritten; 194 CURLcode result; 195 196 DEBUGASSERT(data); 197 if(!data) 198 return 0; 199 200 result = Curl_conn_cf_send(cf->next, data, (const char *)buf, blen, FALSE, 201 &nwritten); 202 CURL_TRC_CF(data, cf, "mbedtls_bio_cf_out_write(len=%zu) -> %d, %zu", 203 blen, result, nwritten); 204 if(CURLE_AGAIN == result) 205 return MBEDTLS_ERR_SSL_WANT_WRITE; 206 return result ? -1 : (int)nwritten; 207 } 208 209 static int mbedtls_bio_cf_read(void *bio, unsigned char *buf, size_t blen) 210 { 211 struct Curl_cfilter *cf = bio; 212 struct Curl_easy *data = CF_DATA_CURRENT(cf); 213 size_t nread; 214 CURLcode result; 215 216 DEBUGASSERT(data); 217 if(!data) 218 return 0; 219 /* OpenSSL catches this case, so should we. */ 220 if(!buf) 221 return 0; 222 223 result = Curl_conn_cf_recv(cf->next, data, (char *)buf, blen, &nread); 224 CURL_TRC_CF(data, cf, "mbedtls_bio_cf_in_read(len=%zu) -> %d, %zu", 225 blen, result, nread); 226 if(CURLE_AGAIN == result) 227 return MBEDTLS_ERR_SSL_WANT_READ; 228 return result ? -1 : (int)nread; 229 } 230 231 /* 232 * profile 233 */ 234 static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr = 235 { 236 /* Hashes from SHA-1 and above */ 237 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | 238 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) | 239 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) | 240 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | 241 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | 242 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), 243 0xFFFFFFF, /* Any PK alg */ 244 0xFFFFFFF, /* Any curve */ 245 1024, /* RSA min key len */ 246 }; 247 248 /* See https://web.archive.org/web/20200921194007/tls.mbed.org/discussions/ 249 generic/howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der 250 */ 251 #define RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE) 252 #define ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES) 253 254 #define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ 255 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) 256 257 static CURLcode 258 mbed_set_ssl_version_min_max(struct Curl_easy *data, 259 struct mbed_ssl_backend_data *backend, 260 struct ssl_primary_config *conn_config) 261 { 262 /* TLS 1.0 and TLS 1.1 were dropped with mbedTLS 3.0.0 (2021). So, since 263 * then, and before the introduction of TLS 1.3 in 3.6.0 (2024), this 264 * function basically always sets TLS 1.2 as min/max, unless given 265 * unsupported option values. */ 266 267 #if MBEDTLS_VERSION_NUMBER < 0x03020000 268 int ver_min = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ 269 int ver_max = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ 270 #else 271 /* mbedTLS 3.2.0 (2022) introduced new methods for setting TLS version */ 272 mbedtls_ssl_protocol_version ver_min = MBEDTLS_SSL_VERSION_TLS1_2; 273 mbedtls_ssl_protocol_version ver_max = 274 #ifdef HAS_TLS13_SUPPORT 275 MBEDTLS_SSL_VERSION_TLS1_3 276 #else 277 MBEDTLS_SSL_VERSION_TLS1_2 278 #endif 279 ; 280 #endif 281 282 switch(conn_config->version) { 283 case CURL_SSLVERSION_DEFAULT: 284 #if MBEDTLS_VERSION_NUMBER < 0x03000000 285 case CURL_SSLVERSION_TLSv1: 286 case CURL_SSLVERSION_TLSv1_0: 287 ver_min = MBEDTLS_SSL_MINOR_VERSION_1; 288 break; 289 case CURL_SSLVERSION_TLSv1_1: 290 ver_min = MBEDTLS_SSL_MINOR_VERSION_2; 291 break; 292 #else 293 case CURL_SSLVERSION_TLSv1: 294 case CURL_SSLVERSION_TLSv1_0: 295 case CURL_SSLVERSION_TLSv1_1: 296 #endif 297 case CURL_SSLVERSION_TLSv1_2: 298 #if MBEDTLS_VERSION_NUMBER < 0x03020000 299 ver_min = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ 300 #else 301 ver_min = MBEDTLS_SSL_VERSION_TLS1_2; 302 #endif 303 break; 304 case CURL_SSLVERSION_TLSv1_3: 305 #ifdef HAS_TLS13_SUPPORT 306 ver_min = MBEDTLS_SSL_VERSION_TLS1_3; 307 break; 308 #endif 309 default: 310 failf(data, "mbedTLS: unsupported minimum TLS version value: %x", 311 conn_config->version); 312 return CURLE_SSL_CONNECT_ERROR; 313 } 314 315 switch(conn_config->version_max) { 316 case CURL_SSLVERSION_MAX_DEFAULT: 317 case CURL_SSLVERSION_MAX_NONE: 318 case CURL_SSLVERSION_MAX_TLSv1_3: 319 #ifdef HAS_TLS13_SUPPORT 320 ver_max = MBEDTLS_SSL_VERSION_TLS1_3; 321 break; 322 #endif 323 case CURL_SSLVERSION_MAX_TLSv1_2: 324 #if MBEDTLS_VERSION_NUMBER < 0x03020000 325 ver_max = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ 326 #else 327 ver_max = MBEDTLS_SSL_VERSION_TLS1_2; 328 #endif 329 break; 330 #if MBEDTLS_VERSION_NUMBER < 0x03000000 331 case CURL_SSLVERSION_MAX_TLSv1_1: 332 ver_max = MBEDTLS_SSL_MINOR_VERSION_2; 333 break; 334 case CURL_SSLVERSION_MAX_TLSv1_0: 335 ver_max = MBEDTLS_SSL_MINOR_VERSION_1; 336 break; 337 #else 338 case CURL_SSLVERSION_MAX_TLSv1_1: 339 case CURL_SSLVERSION_MAX_TLSv1_0: 340 #endif 341 default: 342 failf(data, "mbedTLS: unsupported maximum TLS version value"); 343 return CURLE_SSL_CONNECT_ERROR; 344 } 345 346 #if MBEDTLS_VERSION_NUMBER < 0x03020000 347 mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, 348 ver_min); 349 mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, 350 ver_max); 351 #else 352 mbedtls_ssl_conf_min_tls_version(&backend->config, ver_min); 353 mbedtls_ssl_conf_max_tls_version(&backend->config, ver_max); 354 #endif 355 356 return CURLE_OK; 357 } 358 359 /* TLS_ECJPAKE_WITH_AES_128_CCM_8 (0xC0FF) is marked experimental 360 in mbedTLS. The number is not reserved by IANA nor is the 361 cipher suite present in other SSL implementations. Provide 362 provisional support for specifying the cipher suite here. */ 363 #ifdef MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 364 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 365 static int 366 mbed_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, 367 bool prefer_rfc) 368 { 369 if(id == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) 370 msnprintf(buf, buf_size, "%s", "TLS_ECJPAKE_WITH_AES_128_CCM_8"); 371 else 372 return Curl_cipher_suite_get_str(id, buf, buf_size, prefer_rfc); 373 return 0; 374 } 375 #endif 376 377 static uint16_t 378 mbed_cipher_suite_walk_str(const char **str, const char **end) 379 { 380 uint16_t id = Curl_cipher_suite_walk_str(str, end); 381 size_t len = *end - *str; 382 383 if(!id) { 384 if(curl_strnequal("TLS_ECJPAKE_WITH_AES_128_CCM_8", *str, len)) 385 id = MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8; 386 } 387 return id; 388 } 389 #else 390 #define mbed_cipher_suite_get_str Curl_cipher_suite_get_str 391 #define mbed_cipher_suite_walk_str Curl_cipher_suite_walk_str 392 #endif 393 394 static CURLcode 395 mbed_set_selected_ciphers(struct Curl_easy *data, 396 struct mbed_ssl_backend_data *backend, 397 const char *ciphers12, 398 const char *ciphers13) 399 { 400 const char *ciphers = ciphers12; 401 const int *supported; 402 int *selected; 403 size_t supported_len, count = 0, default13_count = 0, i, j; 404 const char *ptr, *end; 405 406 supported = mbedtls_ssl_list_ciphersuites(); 407 for(i = 0; supported[i] != 0; i++); 408 supported_len = i; 409 410 selected = malloc(sizeof(int) * (supported_len + 1)); 411 if(!selected) 412 return CURLE_OUT_OF_MEMORY; 413 414 #ifndef HAS_TLS13_SUPPORT 415 (void) ciphers13, (void) j; 416 #else 417 if(!ciphers13) { 418 /* Add default TLSv1.3 ciphers to selection */ 419 for(j = 0; j < supported_len; j++) { 420 uint16_t id = (uint16_t) supported[j]; 421 if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) != 0) 422 continue; 423 424 selected[count++] = id; 425 } 426 427 default13_count = count; 428 } 429 else 430 ciphers = ciphers13; 431 432 add_ciphers: 433 #endif 434 for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { 435 uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end); 436 437 /* Check if cipher is supported */ 438 if(id) { 439 for(i = 0; i < supported_len && supported[i] != id; i++); 440 if(i == supported_len) 441 id = 0; 442 } 443 if(!id) { 444 if(ptr[0] != '\0') 445 infof(data, "mbedTLS: unknown cipher in list: \"%.*s\"", 446 (int) (end - ptr), ptr); 447 continue; 448 } 449 450 /* No duplicates allowed (so selected cannot overflow) */ 451 for(i = 0; i < count && selected[i] != id; i++); 452 if(i < count) { 453 if(i >= default13_count) 454 infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", 455 (int) (end - ptr), ptr); 456 continue; 457 } 458 459 selected[count++] = id; 460 } 461 462 #ifdef HAS_TLS13_SUPPORT 463 if(ciphers == ciphers13 && ciphers12) { 464 ciphers = ciphers12; 465 goto add_ciphers; 466 } 467 468 if(!ciphers12) { 469 /* Add default TLSv1.2 ciphers to selection */ 470 for(j = 0; j < supported_len; j++) { 471 uint16_t id = (uint16_t) supported[j]; 472 if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) == 0) 473 continue; 474 475 /* No duplicates allowed (so selected cannot overflow) */ 476 for(i = 0; i < count && selected[i] != id; i++); 477 if(i < count) 478 continue; 479 480 selected[count++] = id; 481 } 482 } 483 #endif 484 485 selected[count] = 0; 486 487 if(count == 0) { 488 free(selected); 489 failf(data, "mbedTLS: no supported cipher in list"); 490 return CURLE_SSL_CIPHER; 491 } 492 493 /* mbedtls_ssl_conf_ciphersuites(): The ciphersuites array is not copied. 494 It must remain valid for the lifetime of the SSL configuration */ 495 backend->ciphersuites = selected; 496 mbedtls_ssl_conf_ciphersuites(&backend->config, backend->ciphersuites); 497 return CURLE_OK; 498 } 499 500 static void 501 mbed_dump_cert_info(struct Curl_easy *data, const mbedtls_x509_crt *crt) 502 { 503 #if defined(CURL_DISABLE_VERBOSE_STRINGS) || \ 504 (MBEDTLS_VERSION_NUMBER >= 0x03000000 && defined(MBEDTLS_X509_REMOVE_INFO)) 505 (void) data, (void) crt; 506 #else 507 const size_t bufsize = 16384; 508 char *p, *buffer = malloc(bufsize); 509 510 if(buffer && mbedtls_x509_crt_info(buffer, bufsize, " ", crt) > 0) { 511 infof(data, "Server certificate:"); 512 for(p = buffer; *p; p += *p != '\0') { 513 size_t s = strcspn(p, "\n"); 514 infof(data, "%.*s", (int) s, p); 515 p += s; 516 } 517 } 518 else 519 infof(data, "Unable to dump certificate information"); 520 521 free(buffer); 522 #endif 523 } 524 525 static void 526 mbed_extract_certinfo(struct Curl_easy *data, const mbedtls_x509_crt *crt) 527 { 528 CURLcode result; 529 const mbedtls_x509_crt *cur; 530 int i; 531 532 for(i = 0, cur = crt; cur; ++i, cur = cur->next); 533 result = Curl_ssl_init_certinfo(data, i); 534 535 for(i = 0, cur = crt; result == CURLE_OK && cur; ++i, cur = cur->next) { 536 const char *beg = (const char *) cur->raw.p; 537 const char *end = beg + cur->raw.len; 538 result = Curl_extract_certinfo(data, i, beg, end); 539 } 540 } 541 542 static int mbed_verify_cb(void *ptr, mbedtls_x509_crt *crt, 543 int depth, uint32_t *flags) 544 { 545 struct Curl_cfilter *cf = (struct Curl_cfilter *) ptr; 546 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 547 struct Curl_easy *data = CF_DATA_CURRENT(cf); 548 549 if(depth == 0) { 550 if(data->set.verbose) 551 mbed_dump_cert_info(data, crt); 552 if(data->set.ssl.certinfo) 553 mbed_extract_certinfo(data, crt); 554 } 555 556 if(!conn_config->verifypeer) 557 *flags = 0; 558 else if(!conn_config->verifyhost) 559 *flags &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; 560 561 if(*flags) { 562 #if MBEDTLS_VERSION_NUMBER < 0x03000000 || !defined(MBEDTLS_X509_REMOVE_INFO) 563 char buf[128]; 564 mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", *flags); 565 failf(data, "mbedTLS: %s", buf); 566 #else 567 failf(data, "mbedTLS: certificate verification error 0x%08x", *flags); 568 #endif 569 } 570 571 return 0; 572 } 573 574 static CURLcode 575 mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) 576 { 577 struct ssl_connect_data *connssl = cf->ctx; 578 struct mbed_ssl_backend_data *backend = 579 (struct mbed_ssl_backend_data *)connssl->backend; 580 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); 581 const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; 582 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 583 const char * const ssl_cafile = 584 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ 585 (ca_info_blob ? NULL : conn_config->CAfile); 586 const bool verifypeer = conn_config->verifypeer; 587 const char * const ssl_capath = conn_config->CApath; 588 char * const ssl_cert = ssl_config->primary.clientcert; 589 const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; 590 const char * const ssl_crlfile = ssl_config->primary.CRLfile; 591 const char *hostname = connssl->peer.hostname; 592 int ret = -1; 593 char errorbuf[128]; 594 595 DEBUGASSERT(backend); 596 DEBUGASSERT(!backend->initialized); 597 598 if((conn_config->version == CURL_SSLVERSION_SSLv2) || 599 (conn_config->version == CURL_SSLVERSION_SSLv3)) { 600 failf(data, "Not supported SSL version"); 601 return CURLE_NOT_BUILT_IN; 602 } 603 604 #ifdef HAS_THREADING_SUPPORT 605 mbedtls_ctr_drbg_init(&backend->ctr_drbg); 606 607 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex, 608 &ts_entropy, NULL, 0); 609 if(ret) { 610 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 611 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s", 612 -ret, errorbuf); 613 return CURLE_FAILED_INIT; 614 } 615 #else 616 mbedtls_entropy_init(&backend->entropy); 617 mbedtls_ctr_drbg_init(&backend->ctr_drbg); 618 619 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func, 620 &backend->entropy, NULL, 0); 621 if(ret) { 622 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 623 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s", 624 -ret, errorbuf); 625 return CURLE_FAILED_INIT; 626 } 627 #endif /* HAS_THREADING_SUPPORT */ 628 629 /* Load the trusted CA */ 630 mbedtls_x509_crt_init(&backend->cacert); 631 632 if(ca_info_blob && verifypeer) { 633 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null 634 terminated even when provided the exact length, forcing us to waste 635 extra memory here. */ 636 unsigned char *newblob = Curl_memdup0(ca_info_blob->data, 637 ca_info_blob->len); 638 if(!newblob) 639 return CURLE_OUT_OF_MEMORY; 640 ret = mbedtls_x509_crt_parse(&backend->cacert, newblob, 641 ca_info_blob->len + 1); 642 free(newblob); 643 if(ret < 0) { 644 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 645 failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s", 646 -ret, errorbuf); 647 return CURLE_SSL_CERTPROBLEM; 648 } 649 } 650 651 if(ssl_cafile && verifypeer) { 652 #ifdef MBEDTLS_FS_IO 653 ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile); 654 655 if(ret < 0) { 656 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 657 failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", 658 ssl_cafile, -ret, errorbuf); 659 return CURLE_SSL_CACERT_BADFILE; 660 } 661 #else 662 failf(data, "mbedtls: functions that use the filesystem not built in"); 663 return CURLE_NOT_BUILT_IN; 664 #endif 665 } 666 667 if(ssl_capath) { 668 #ifdef MBEDTLS_FS_IO 669 ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath); 670 671 if(ret < 0) { 672 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 673 failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", 674 ssl_capath, -ret, errorbuf); 675 676 if(verifypeer) 677 return CURLE_SSL_CACERT_BADFILE; 678 } 679 #else 680 failf(data, "mbedtls: functions that use the filesystem not built in"); 681 return CURLE_NOT_BUILT_IN; 682 #endif 683 } 684 685 /* Load the client certificate */ 686 mbedtls_x509_crt_init(&backend->clicert); 687 688 if(ssl_cert) { 689 #ifdef MBEDTLS_FS_IO 690 ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert); 691 692 if(ret) { 693 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 694 failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", 695 ssl_cert, -ret, errorbuf); 696 697 return CURLE_SSL_CERTPROBLEM; 698 } 699 #else 700 failf(data, "mbedtls: functions that use the filesystem not built in"); 701 return CURLE_NOT_BUILT_IN; 702 #endif 703 } 704 705 if(ssl_cert_blob) { 706 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null 707 terminated even when provided the exact length, forcing us to waste 708 extra memory here. */ 709 unsigned char *newblob = Curl_memdup0(ssl_cert_blob->data, 710 ssl_cert_blob->len); 711 if(!newblob) 712 return CURLE_OUT_OF_MEMORY; 713 ret = mbedtls_x509_crt_parse(&backend->clicert, newblob, 714 ssl_cert_blob->len + 1); 715 free(newblob); 716 717 if(ret) { 718 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 719 failf(data, "Error reading client cert data %s - mbedTLS: (-0x%04X) %s", 720 ssl_config->key, -ret, errorbuf); 721 return CURLE_SSL_CERTPROBLEM; 722 } 723 } 724 725 /* Load the client private key */ 726 mbedtls_pk_init(&backend->pk); 727 728 if(ssl_config->key || ssl_config->key_blob) { 729 if(ssl_config->key) { 730 #ifdef MBEDTLS_FS_IO 731 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 732 ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key, 733 ssl_config->key_passwd, 734 mbedtls_ctr_drbg_random, 735 &backend->ctr_drbg); 736 #else 737 ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key, 738 ssl_config->key_passwd); 739 #endif 740 if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || 741 mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) 742 ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; 743 744 if(ret) { 745 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 746 failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", 747 ssl_config->key, -ret, errorbuf); 748 return CURLE_SSL_CERTPROBLEM; 749 } 750 #else 751 failf(data, "mbedtls: functions that use the filesystem not built in"); 752 return CURLE_NOT_BUILT_IN; 753 #endif 754 } 755 else { 756 const struct curl_blob *ssl_key_blob = ssl_config->key_blob; 757 const unsigned char *key_data = 758 (const unsigned char *)ssl_key_blob->data; 759 const char *passwd = ssl_config->key_passwd; 760 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 761 ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, 762 (const unsigned char *)passwd, 763 passwd ? strlen(passwd) : 0, 764 mbedtls_ctr_drbg_random, 765 &backend->ctr_drbg); 766 #else 767 ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, 768 (const unsigned char *)passwd, 769 passwd ? strlen(passwd) : 0); 770 #endif 771 if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || 772 mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) 773 ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; 774 775 if(ret) { 776 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 777 failf(data, "Error parsing private key - mbedTLS: (-0x%04X) %s", 778 -ret, errorbuf); 779 return CURLE_SSL_CERTPROBLEM; 780 } 781 } 782 } 783 784 /* Load the CRL */ 785 #ifdef MBEDTLS_X509_CRL_PARSE_C 786 mbedtls_x509_crl_init(&backend->crl); 787 788 if(ssl_crlfile) { 789 #ifdef MBEDTLS_FS_IO 790 ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile); 791 792 if(ret) { 793 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 794 failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", 795 ssl_crlfile, -ret, errorbuf); 796 797 return CURLE_SSL_CRL_BADFILE; 798 } 799 #else 800 failf(data, "mbedtls: functions that use the filesystem not built in"); 801 return CURLE_NOT_BUILT_IN; 802 #endif 803 } 804 #else 805 if(ssl_crlfile) { 806 failf(data, "mbedtls: crl support not built in"); 807 return CURLE_NOT_BUILT_IN; 808 } 809 #endif 810 811 infof(data, "mbedTLS: Connecting to %s:%d", hostname, connssl->peer.port); 812 813 mbedtls_ssl_config_init(&backend->config); 814 ret = mbedtls_ssl_config_defaults(&backend->config, 815 MBEDTLS_SSL_IS_CLIENT, 816 MBEDTLS_SSL_TRANSPORT_STREAM, 817 MBEDTLS_SSL_PRESET_DEFAULT); 818 if(ret) { 819 failf(data, "mbedTLS: ssl_config failed"); 820 return CURLE_SSL_CONNECT_ERROR; 821 } 822 823 #if defined(HAS_SESSION_TICKETS) && MBEDTLS_VERSION_NUMBER >= 0x03060100 824 /* New in mbedTLS 3.6.1, need to enable, default is now disabled */ 825 mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&backend->config, 826 MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED); 827 #endif 828 829 /* Always let mbedTLS verify certificates, if verifypeer or verifyhost are 830 * disabled we clear the corresponding error flags in the verify callback 831 * function. That is also where we log verification errors. */ 832 mbedtls_ssl_conf_verify(&backend->config, mbed_verify_cb, cf); 833 mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_REQUIRED); 834 835 mbedtls_ssl_init(&backend->ssl); 836 backend->initialized = TRUE; 837 838 /* new profile with RSA min key len = 1024 ... */ 839 mbedtls_ssl_conf_cert_profile(&backend->config, 840 &mbedtls_x509_crt_profile_fr); 841 842 ret = mbed_set_ssl_version_min_max(data, backend, conn_config); 843 if(ret != CURLE_OK) 844 return ret; 845 846 mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random, 847 &backend->ctr_drbg); 848 849 ret = mbedtls_ssl_setup(&backend->ssl, &backend->config); 850 if(ret) { 851 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 852 failf(data, "ssl_setup failed - mbedTLS: (-0x%04X) %s", 853 -ret, errorbuf); 854 return CURLE_SSL_CONNECT_ERROR; 855 } 856 857 mbedtls_ssl_set_bio(&backend->ssl, cf, 858 mbedtls_bio_cf_write, 859 mbedtls_bio_cf_read, 860 NULL /* rev_timeout() */); 861 862 #ifndef HAS_TLS13_SUPPORT 863 if(conn_config->cipher_list) { 864 CURLcode result = mbed_set_selected_ciphers(data, backend, 865 conn_config->cipher_list, 866 NULL); 867 #else 868 if(conn_config->cipher_list || conn_config->cipher_list13) { 869 CURLcode result = mbed_set_selected_ciphers(data, backend, 870 conn_config->cipher_list, 871 conn_config->cipher_list13); 872 #endif 873 if(result != CURLE_OK) { 874 failf(data, "mbedTLS: failed to set cipher suites"); 875 return result; 876 } 877 } 878 else { 879 mbedtls_ssl_conf_ciphersuites(&backend->config, 880 mbedtls_ssl_list_ciphersuites()); 881 } 882 883 884 #if defined(MBEDTLS_SSL_RENEGOTIATION) 885 mbedtls_ssl_conf_renegotiation(&backend->config, 886 MBEDTLS_SSL_RENEGOTIATION_ENABLED); 887 #endif 888 889 #if defined(MBEDTLS_SSL_SESSION_TICKETS) 890 mbedtls_ssl_conf_session_tickets(&backend->config, 891 MBEDTLS_SSL_SESSION_TICKETS_DISABLED); 892 #endif 893 894 /* Check if there is a cached ID we can/should use here! */ 895 if(ssl_config->primary.cache_session) { 896 struct Curl_ssl_session *sc_session = NULL; 897 CURLcode result; 898 899 result = Curl_ssl_scache_take(cf, data, connssl->peer.scache_key, 900 &sc_session); 901 if(!result && sc_session && sc_session->sdata && sc_session->sdata_len) { 902 mbedtls_ssl_session session; 903 904 mbedtls_ssl_session_init(&session); 905 ret = mbedtls_ssl_session_load(&session, sc_session->sdata, 906 sc_session->sdata_len); 907 if(ret) { 908 failf(data, "SSL session error loading: -0x%x", -ret); 909 } 910 else { 911 ret = mbedtls_ssl_set_session(&backend->ssl, &session); 912 if(ret) 913 failf(data, "SSL session error setting: -0x%x", -ret); 914 else 915 infof(data, "SSL reusing session ID"); 916 } 917 mbedtls_ssl_session_free(&session); 918 } 919 Curl_ssl_scache_return(cf, data, connssl->peer.scache_key, sc_session); 920 } 921 922 mbedtls_ssl_conf_ca_chain(&backend->config, 923 &backend->cacert, 924 #ifdef MBEDTLS_X509_CRL_PARSE_C 925 &backend->crl); 926 #else 927 NULL); 928 #endif 929 930 if(ssl_config->key || ssl_config->key_blob) { 931 mbedtls_ssl_conf_own_cert(&backend->config, 932 &backend->clicert, &backend->pk); 933 } 934 935 if(mbedtls_ssl_set_hostname(&backend->ssl, connssl->peer.sni ? 936 connssl->peer.sni : connssl->peer.hostname)) { 937 /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and 938 the name to set in the SNI extension. So even if curl connects to a 939 host specified as an IP address, this function must be used. */ 940 failf(data, "Failed to set SNI"); 941 return CURLE_SSL_CONNECT_ERROR; 942 } 943 944 #ifdef HAS_ALPN_MBEDTLS 945 if(connssl->alpn) { 946 struct alpn_proto_buf proto; 947 size_t i; 948 949 for(i = 0; i < connssl->alpn->count; ++i) { 950 backend->protocols[i] = connssl->alpn->entries[i]; 951 } 952 /* this function does not clone the protocols array, which is why we need 953 to keep it around */ 954 if(mbedtls_ssl_conf_alpn_protocols(&backend->config, 955 &backend->protocols[0])) { 956 failf(data, "Failed setting ALPN protocols"); 957 return CURLE_SSL_CONNECT_ERROR; 958 } 959 Curl_alpn_to_proto_str(&proto, connssl->alpn); 960 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); 961 } 962 #endif 963 964 #ifdef MBEDTLS_DEBUG 965 /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */ 966 mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data); 967 /* - 0 No debug 968 * - 1 Error 969 * - 2 State change 970 * - 3 Informational 971 * - 4 Verbose 972 */ 973 mbedtls_debug_set_threshold(4); 974 #endif 975 976 /* give application a chance to interfere with mbedTLS set up. */ 977 if(data->set.ssl.fsslctx) { 978 CURLcode result = (*data->set.ssl.fsslctx)(data, &backend->config, 979 data->set.ssl.fsslctxp); 980 if(result != CURLE_OK) { 981 failf(data, "error signaled by ssl ctx callback"); 982 return result; 983 } 984 } 985 986 connssl->connecting_state = ssl_connect_2; 987 988 return CURLE_OK; 989 } 990 991 static CURLcode 992 mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) 993 { 994 int ret; 995 struct ssl_connect_data *connssl = cf->ctx; 996 struct mbed_ssl_backend_data *backend = 997 (struct mbed_ssl_backend_data *)connssl->backend; 998 #ifndef CURL_DISABLE_PROXY 999 const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf) ? 1000 data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : 1001 data->set.str[STRING_SSL_PINNEDPUBLICKEY]; 1002 #else 1003 const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; 1004 #endif 1005 1006 DEBUGASSERT(backend); 1007 1008 ret = mbedtls_ssl_handshake(&backend->ssl); 1009 1010 if(ret == MBEDTLS_ERR_SSL_WANT_READ) { 1011 connssl->io_need = CURL_SSL_IO_NEED_RECV; 1012 return CURLE_OK; 1013 } 1014 else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { 1015 connssl->io_need = CURL_SSL_IO_NEED_SEND; 1016 return CURLE_OK; 1017 } 1018 else if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { 1019 failf(data, "peer certificate could not be verified"); 1020 return CURLE_PEER_FAILED_VERIFICATION; 1021 } 1022 else if(ret) { 1023 char errorbuf[128]; 1024 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 1025 CURL_TRC_CF(data, cf, "TLS version %04X", 1026 mbedtls_ssl_get_version_number(&backend->ssl)); 1027 #endif 1028 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); 1029 failf(data, "ssl_handshake returned: (-0x%04X) %s", 1030 -ret, errorbuf); 1031 return CURLE_SSL_CONNECT_ERROR; 1032 } 1033 1034 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 1035 { 1036 char cipher_str[64]; 1037 uint16_t cipher_id; 1038 cipher_id = (uint16_t) 1039 mbedtls_ssl_get_ciphersuite_id_from_ssl(&backend->ssl); 1040 mbed_cipher_suite_get_str(cipher_id, cipher_str, sizeof(cipher_str), TRUE); 1041 infof(data, "mbedTLS: %s Handshake complete, cipher is %s", 1042 mbedtls_ssl_get_version(&backend->ssl), cipher_str); 1043 } 1044 #else 1045 infof(data, "mbedTLS: %s Handshake complete", 1046 mbedtls_ssl_get_version(&backend->ssl)); 1047 #endif 1048 1049 if(pinnedpubkey) { 1050 int size; 1051 CURLcode result; 1052 const mbedtls_x509_crt *peercert; 1053 mbedtls_x509_crt *p = NULL; 1054 unsigned char *pubkey = NULL; 1055 1056 peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); 1057 #if MBEDTLS_VERSION_NUMBER == 0x03000000 1058 if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) || 1059 !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) { 1060 #else 1061 if(!peercert || !peercert->raw.p || !peercert->raw.len) { 1062 #endif 1063 failf(data, "Failed due to missing peer certificate"); 1064 return CURLE_SSL_PINNEDPUBKEYNOTMATCH; 1065 } 1066 1067 p = calloc(1, sizeof(*p)); 1068 1069 if(!p) 1070 return CURLE_OUT_OF_MEMORY; 1071 1072 pubkey = malloc(PUB_DER_MAX_BYTES); 1073 1074 if(!pubkey) { 1075 result = CURLE_OUT_OF_MEMORY; 1076 goto pinnedpubkey_error; 1077 } 1078 1079 mbedtls_x509_crt_init(p); 1080 1081 /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der 1082 needs a non-const key, for now. 1083 https://github.com/Mbed-TLS/mbedtls/issues/396 */ 1084 #if MBEDTLS_VERSION_NUMBER == 0x03000000 1085 if(mbedtls_x509_crt_parse_der(p, 1086 peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p), 1087 peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) { 1088 #else 1089 if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { 1090 #endif 1091 failf(data, "Failed copying peer certificate"); 1092 result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; 1093 goto pinnedpubkey_error; 1094 } 1095 1096 #if MBEDTLS_VERSION_NUMBER == 0x03000000 1097 size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey, 1098 PUB_DER_MAX_BYTES); 1099 #else 1100 size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); 1101 #endif 1102 1103 if(size <= 0) { 1104 failf(data, "Failed copying public key from peer certificate"); 1105 result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; 1106 goto pinnedpubkey_error; 1107 } 1108 1109 /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ 1110 result = Curl_pin_peer_pubkey(data, 1111 pinnedpubkey, 1112 &pubkey[PUB_DER_MAX_BYTES - size], size); 1113 pinnedpubkey_error: 1114 mbedtls_x509_crt_free(p); 1115 free(p); 1116 free(pubkey); 1117 if(result) { 1118 return result; 1119 } 1120 } 1121 1122 #ifdef HAS_ALPN_MBEDTLS 1123 if(connssl->alpn) { 1124 const char *proto = mbedtls_ssl_get_alpn_protocol(&backend->ssl); 1125 1126 Curl_alpn_set_negotiated(cf, data, connssl, (const unsigned char *)proto, 1127 proto ? strlen(proto) : 0); 1128 } 1129 #endif 1130 1131 connssl->connecting_state = ssl_connect_3; 1132 infof(data, "SSL connected"); 1133 1134 return CURLE_OK; 1135 } 1136 1137 static CURLcode 1138 mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data) 1139 { 1140 struct ssl_connect_data *connssl = cf->ctx; 1141 struct mbed_ssl_backend_data *backend = 1142 (struct mbed_ssl_backend_data *)connssl->backend; 1143 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); 1144 mbedtls_ssl_session session; 1145 bool msession_alloced = FALSE; 1146 struct Curl_ssl_session *sc_session = NULL; 1147 unsigned char *sdata = NULL; 1148 size_t slen = 0; 1149 int ietf_tls_id; 1150 CURLcode result = CURLE_OK; 1151 int ret; 1152 1153 DEBUGASSERT(backend); 1154 if(!ssl_config->primary.cache_session) 1155 return CURLE_OK; 1156 1157 mbedtls_ssl_session_init(&session); 1158 ret = mbedtls_ssl_get_session(&backend->ssl, &session); 1159 msession_alloced = (ret != MBEDTLS_ERR_SSL_ALLOC_FAILED); 1160 if(ret) { 1161 failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); 1162 result = CURLE_SSL_CONNECT_ERROR; 1163 goto out; 1164 } 1165 1166 mbedtls_ssl_session_save(&session, NULL, 0, &slen); 1167 if(!slen) { 1168 failf(data, "failed to serialize session: length is 0"); 1169 goto out; 1170 } 1171 1172 sdata = malloc(slen); 1173 if(!sdata) { 1174 result = CURLE_OUT_OF_MEMORY; 1175 goto out; 1176 } 1177 1178 ret = mbedtls_ssl_session_save(&session, sdata, slen, &slen); 1179 if(ret) { 1180 failf(data, "failed to serialize session: -0x%x", -ret); 1181 goto out; 1182 } 1183 1184 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 1185 ietf_tls_id = mbedtls_ssl_get_version_number(&backend->ssl); 1186 #else 1187 ietf_tls_id = CURL_IETF_PROTO_UNKNOWN; 1188 #endif 1189 result = Curl_ssl_session_create(sdata, slen, 1190 ietf_tls_id, 1191 connssl->negotiated.alpn, 0, 0, 1192 &sc_session); 1193 sdata = NULL; /* call took ownership */ 1194 if(!result) 1195 result = Curl_ssl_scache_put(cf, data, connssl->peer.scache_key, 1196 sc_session); 1197 1198 out: 1199 if(msession_alloced) 1200 mbedtls_ssl_session_free(&session); 1201 free(sdata); 1202 return result; 1203 } 1204 1205 static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, 1206 const void *mem, size_t len, 1207 size_t *pnwritten) 1208 { 1209 struct ssl_connect_data *connssl = cf->ctx; 1210 struct mbed_ssl_backend_data *backend = 1211 (struct mbed_ssl_backend_data *)connssl->backend; 1212 CURLcode result = CURLE_OK; 1213 int nwritten; 1214 1215 (void)data; 1216 *pnwritten = 0; 1217 DEBUGASSERT(backend); 1218 /* mbedtls is picky when a mbedtls_ssl_write) was previously blocked. 1219 * It requires to be called with the same amount of bytes again, or it 1220 * will lose bytes, e.g. reporting all was sent but they were not. 1221 * Remember the blocked length and use that when set. */ 1222 if(backend->send_blocked) { 1223 DEBUGASSERT(backend->send_blocked_len <= len); 1224 CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> previously blocked " 1225 "on %zu bytes", len, backend->send_blocked_len); 1226 len = backend->send_blocked_len; 1227 } 1228 1229 nwritten = mbedtls_ssl_write(&backend->ssl, (const unsigned char *)mem, len); 1230 1231 if(nwritten >= 0) { 1232 *pnwritten = (size_t)nwritten; 1233 backend->send_blocked = FALSE; 1234 } 1235 else { 1236 CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X", 1237 len, -nwritten); 1238 result = ((nwritten == MBEDTLS_ERR_SSL_WANT_WRITE) 1239 #ifdef HAS_TLS13_SUPPORT 1240 || (nwritten == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) 1241 #endif 1242 ) ? CURLE_AGAIN : CURLE_SEND_ERROR; 1243 if((result == CURLE_AGAIN) && !backend->send_blocked) { 1244 backend->send_blocked = TRUE; 1245 backend->send_blocked_len = len; 1246 } 1247 } 1248 1249 CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d, %zu", 1250 len, result, *pnwritten); 1251 return result; 1252 } 1253 1254 static CURLcode mbedtls_shutdown(struct Curl_cfilter *cf, 1255 struct Curl_easy *data, 1256 bool send_shutdown, bool *done) 1257 { 1258 struct ssl_connect_data *connssl = cf->ctx; 1259 struct mbed_ssl_backend_data *backend = 1260 (struct mbed_ssl_backend_data *)connssl->backend; 1261 unsigned char buf[1024]; 1262 CURLcode result = CURLE_OK; 1263 int ret; 1264 size_t i; 1265 1266 DEBUGASSERT(backend); 1267 1268 if(!backend->initialized || cf->shutdown) { 1269 *done = TRUE; 1270 return CURLE_OK; 1271 } 1272 1273 connssl->io_need = CURL_SSL_IO_NEED_NONE; 1274 *done = FALSE; 1275 1276 if(!backend->sent_shutdown) { 1277 /* do this only once */ 1278 backend->sent_shutdown = TRUE; 1279 if(send_shutdown) { 1280 ret = mbedtls_ssl_close_notify(&backend->ssl); 1281 switch(ret) { 1282 case 0: /* we sent it, receive from the server */ 1283 break; 1284 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: /* server also closed */ 1285 *done = TRUE; 1286 goto out; 1287 case MBEDTLS_ERR_SSL_WANT_READ: 1288 connssl->io_need = CURL_SSL_IO_NEED_RECV; 1289 goto out; 1290 case MBEDTLS_ERR_SSL_WANT_WRITE: 1291 connssl->io_need = CURL_SSL_IO_NEED_SEND; 1292 goto out; 1293 default: 1294 CURL_TRC_CF(data, cf, "mbedtls_shutdown error -0x%04X", -ret); 1295 result = CURLE_RECV_ERROR; 1296 goto out; 1297 } 1298 } 1299 } 1300 1301 /* SSL should now have started the shutdown from our side. Since it 1302 * was not complete, we are lacking the close notify from the server. */ 1303 for(i = 0; i < 10; ++i) { 1304 ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf)); 1305 /* This seems to be a bug in mbedTLS TLSv1.3 where it reports 1306 * WANT_READ, but has not encountered an EAGAIN. */ 1307 if(ret == MBEDTLS_ERR_SSL_WANT_READ) 1308 ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf)); 1309 #ifdef HAS_TLS13_SUPPORT 1310 if(ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) 1311 continue; 1312 #endif 1313 if(ret <= 0) 1314 break; 1315 } 1316 1317 if(ret > 0) { 1318 /* still data coming in? */ 1319 CURL_TRC_CF(data, cf, "mbedtls_shutdown, still getting data"); 1320 } 1321 else if(ret == 0 || (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)) { 1322 /* We got the close notify alert and are done. */ 1323 CURL_TRC_CF(data, cf, "mbedtls_shutdown done"); 1324 *done = TRUE; 1325 } 1326 else if(ret == MBEDTLS_ERR_SSL_WANT_READ) { 1327 CURL_TRC_CF(data, cf, "mbedtls_shutdown, need RECV"); 1328 connssl->io_need = CURL_SSL_IO_NEED_RECV; 1329 } 1330 else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { 1331 CURL_TRC_CF(data, cf, "mbedtls_shutdown, need SEND"); 1332 connssl->io_need = CURL_SSL_IO_NEED_SEND; 1333 } 1334 else { 1335 CURL_TRC_CF(data, cf, "mbedtls_shutdown error -0x%04X", -ret); 1336 result = CURLE_RECV_ERROR; 1337 } 1338 1339 out: 1340 cf->shutdown = (result || *done); 1341 return result; 1342 } 1343 1344 static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data) 1345 { 1346 struct ssl_connect_data *connssl = cf->ctx; 1347 struct mbed_ssl_backend_data *backend = 1348 (struct mbed_ssl_backend_data *)connssl->backend; 1349 1350 (void)data; 1351 DEBUGASSERT(backend); 1352 if(backend->initialized) { 1353 mbedtls_pk_free(&backend->pk); 1354 mbedtls_x509_crt_free(&backend->clicert); 1355 mbedtls_x509_crt_free(&backend->cacert); 1356 #ifdef MBEDTLS_X509_CRL_PARSE_C 1357 mbedtls_x509_crl_free(&backend->crl); 1358 #endif 1359 Curl_safefree(backend->ciphersuites); 1360 mbedtls_ssl_config_free(&backend->config); 1361 mbedtls_ssl_free(&backend->ssl); 1362 mbedtls_ctr_drbg_free(&backend->ctr_drbg); 1363 #ifndef HAS_THREADING_SUPPORT 1364 mbedtls_entropy_free(&backend->entropy); 1365 #endif /* HAS_THREADING_SUPPORT */ 1366 backend->initialized = FALSE; 1367 } 1368 } 1369 1370 static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data, 1371 char *buf, size_t buffersize, 1372 size_t *pnread) 1373 { 1374 struct ssl_connect_data *connssl = cf->ctx; 1375 struct mbed_ssl_backend_data *backend = 1376 (struct mbed_ssl_backend_data *)connssl->backend; 1377 CURLcode result = CURLE_OK; 1378 int nread; 1379 1380 (void)data; 1381 DEBUGASSERT(backend); 1382 *pnread = 0; 1383 1384 nread = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, buffersize); 1385 if(nread > 0) 1386 *pnread = (size_t)nread; 1387 else { 1388 CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X", 1389 buffersize, -nread); 1390 switch(nread) { 1391 #ifdef HAS_SESSION_TICKETS 1392 case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET: 1393 mbed_new_session(cf, data); 1394 FALLTHROUGH(); 1395 #endif 1396 case MBEDTLS_ERR_SSL_WANT_READ: 1397 result = CURLE_AGAIN; 1398 break; 1399 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 1400 result = CURLE_OK; 1401 break; 1402 default: { 1403 char errorbuf[128]; 1404 mbedtls_strerror(nread, errorbuf, sizeof(errorbuf)); 1405 failf(data, "ssl_read returned: (-0x%04X) %s", -nread, errorbuf); 1406 result = CURLE_RECV_ERROR; 1407 break; 1408 } 1409 } 1410 } 1411 return result; 1412 } 1413 1414 static size_t mbedtls_version(char *buffer, size_t size) 1415 { 1416 #ifdef MBEDTLS_VERSION_C 1417 /* if mbedtls_version_get_number() is available it is better */ 1418 unsigned int version = mbedtls_version_get_number(); 1419 return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version >> 24, 1420 (version >> 16) & 0xff, (version >> 8) & 0xff); 1421 #else 1422 return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING); 1423 #endif 1424 } 1425 1426 /* 'data' might be NULL */ 1427 static CURLcode mbedtls_random(struct Curl_easy *data, 1428 unsigned char *entropy, size_t length) 1429 { 1430 #if defined(MBEDTLS_CTR_DRBG_C) 1431 int ret; 1432 mbedtls_entropy_context ctr_entropy; 1433 mbedtls_ctr_drbg_context ctr_drbg; 1434 mbedtls_entropy_init(&ctr_entropy); 1435 mbedtls_ctr_drbg_init(&ctr_drbg); 1436 (void)data; 1437 1438 ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, 1439 &ctr_entropy, NULL, 0); 1440 1441 if(!ret) 1442 ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length); 1443 1444 mbedtls_ctr_drbg_free(&ctr_drbg); 1445 mbedtls_entropy_free(&ctr_entropy); 1446 1447 return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT; 1448 #elif defined(MBEDTLS_HAVEGE_C) 1449 mbedtls_havege_state hs; 1450 mbedtls_havege_init(&hs); 1451 mbedtls_havege_random(&hs, entropy, length); 1452 mbedtls_havege_free(&hs); 1453 return CURLE_OK; 1454 #else 1455 return CURLE_NOT_BUILT_IN; 1456 #endif 1457 } 1458 1459 static CURLcode mbedtls_connect(struct Curl_cfilter *cf, 1460 struct Curl_easy *data, 1461 bool *done) 1462 { 1463 CURLcode retcode; 1464 struct ssl_connect_data *connssl = cf->ctx; 1465 1466 /* check if the connection has already been established */ 1467 if(ssl_connection_complete == connssl->state) { 1468 *done = TRUE; 1469 return CURLE_OK; 1470 } 1471 1472 *done = FALSE; 1473 connssl->io_need = CURL_SSL_IO_NEED_NONE; 1474 1475 if(ssl_connect_1 == connssl->connecting_state) { 1476 retcode = mbed_connect_step1(cf, data); 1477 if(retcode) 1478 return retcode; 1479 } 1480 1481 if(ssl_connect_2 == connssl->connecting_state) { 1482 retcode = mbed_connect_step2(cf, data); 1483 if(retcode) 1484 return retcode; 1485 } 1486 1487 if(ssl_connect_3 == connssl->connecting_state) { 1488 /* For tls1.3 we get notified about new sessions */ 1489 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 1490 struct ssl_connect_data *ctx = cf->ctx; 1491 struct mbed_ssl_backend_data *backend = 1492 (struct mbed_ssl_backend_data *)ctx->backend; 1493 1494 if(mbedtls_ssl_get_version_number(&backend->ssl) <= 1495 MBEDTLS_SSL_VERSION_TLS1_2) { 1496 #else 1497 { /* no TLSv1.3 supported here */ 1498 #endif 1499 retcode = mbed_new_session(cf, data); 1500 if(retcode) 1501 return retcode; 1502 } 1503 connssl->connecting_state = ssl_connect_done; 1504 } 1505 1506 if(ssl_connect_done == connssl->connecting_state) { 1507 connssl->state = ssl_connection_complete; 1508 *done = TRUE; 1509 } 1510 1511 return CURLE_OK; 1512 } 1513 1514 /* 1515 * return 0 error initializing SSL 1516 * return 1 SSL initialized successfully 1517 */ 1518 static int mbedtls_init(void) 1519 { 1520 if(!Curl_mbedtlsthreadlock_thread_setup()) 1521 return 0; 1522 #ifdef HAS_THREADING_SUPPORT 1523 entropy_init_mutex(&ts_entropy); 1524 #endif 1525 #ifdef HAS_PSA_SUPPORT 1526 { 1527 int ret; 1528 #ifdef HAS_THREADING_SUPPORT 1529 Curl_mbedtlsthreadlock_lock_function(0); 1530 #endif 1531 ret = psa_crypto_init(); 1532 #ifdef HAS_THREADING_SUPPORT 1533 Curl_mbedtlsthreadlock_unlock_function(0); 1534 #endif 1535 if(ret != PSA_SUCCESS) 1536 return 0; 1537 } 1538 #endif /* HAS_PSA_SUPPORT */ 1539 return 1; 1540 } 1541 1542 static void mbedtls_cleanup(void) 1543 { 1544 #ifdef HAS_THREADING_SUPPORT 1545 entropy_cleanup_mutex(&ts_entropy); 1546 #endif 1547 (void)Curl_mbedtlsthreadlock_thread_cleanup(); 1548 } 1549 1550 static bool mbedtls_data_pending(struct Curl_cfilter *cf, 1551 const struct Curl_easy *data) 1552 { 1553 struct ssl_connect_data *ctx = cf->ctx; 1554 struct mbed_ssl_backend_data *backend; 1555 1556 (void)data; 1557 DEBUGASSERT(ctx && ctx->backend); 1558 backend = (struct mbed_ssl_backend_data *)ctx->backend; 1559 return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0; 1560 } 1561 1562 static CURLcode mbedtls_sha256sum(const unsigned char *input, 1563 size_t inputlen, 1564 unsigned char *sha256sum, 1565 size_t sha256len UNUSED_PARAM) 1566 { 1567 (void)sha256len; 1568 #if MBEDTLS_VERSION_NUMBER < 0x02070000 1569 mbedtls_sha256(input, inputlen, sha256sum, 0); 1570 #else 1571 /* returns 0 on success, otherwise failure */ 1572 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 1573 if(mbedtls_sha256(input, inputlen, sha256sum, 0) != 0) 1574 #else 1575 if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0) 1576 #endif 1577 return CURLE_BAD_FUNCTION_ARGUMENT; 1578 #endif 1579 return CURLE_OK; 1580 } 1581 1582 static void *mbedtls_get_internals(struct ssl_connect_data *connssl, 1583 CURLINFO info UNUSED_PARAM) 1584 { 1585 struct mbed_ssl_backend_data *backend = 1586 (struct mbed_ssl_backend_data *)connssl->backend; 1587 (void)info; 1588 DEBUGASSERT(backend); 1589 return &backend->ssl; 1590 } 1591 1592 const struct Curl_ssl Curl_ssl_mbedtls = { 1593 { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */ 1594 1595 SSLSUPP_CA_PATH | 1596 SSLSUPP_CAINFO_BLOB | 1597 SSLSUPP_CERTINFO | 1598 SSLSUPP_PINNEDPUBKEY | 1599 SSLSUPP_SSL_CTX | 1600 #ifdef HAS_TLS13_SUPPORT 1601 SSLSUPP_TLS13_CIPHERSUITES | 1602 #endif 1603 SSLSUPP_HTTPS_PROXY | 1604 SSLSUPP_CIPHER_LIST, 1605 1606 sizeof(struct mbed_ssl_backend_data), 1607 1608 mbedtls_init, /* init */ 1609 mbedtls_cleanup, /* cleanup */ 1610 mbedtls_version, /* version */ 1611 mbedtls_shutdown, /* shutdown */ 1612 mbedtls_data_pending, /* data_pending */ 1613 mbedtls_random, /* random */ 1614 NULL, /* cert_status_request */ 1615 mbedtls_connect, /* connect */ 1616 Curl_ssl_adjust_pollset, /* adjust_pollset */ 1617 mbedtls_get_internals, /* get_internals */ 1618 mbedtls_close, /* close_one */ 1619 NULL, /* close_all */ 1620 NULL, /* set_engine */ 1621 NULL, /* set_engine_default */ 1622 NULL, /* engines_list */ 1623 mbedtls_sha256sum, /* sha256sum */ 1624 mbed_recv, /* recv decrypted data */ 1625 mbed_send, /* send data to encrypt */ 1626 NULL, /* get_channel_binding */ 1627 }; 1628 1629 #endif /* USE_MBEDTLS */