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