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 "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 #ifdef 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 THREADING_SUPPORT
589 mbedtls_ctr_drbg_init(&backend->ctr_drbg);
590
591 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
592 &ts_entropy, NULL, 0);
593 if(ret) {
594 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
595 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
596 -ret, errorbuf);
597 return CURLE_FAILED_INIT;
598 }
599 #else
600 mbedtls_entropy_init(&backend->entropy);
601 mbedtls_ctr_drbg_init(&backend->ctr_drbg);
602
603 ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
604 &backend->entropy, NULL, 0);
605 if(ret) {
606 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
607 failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
608 -ret, errorbuf);
609 return CURLE_FAILED_INIT;
610 }
611 #endif /* THREADING_SUPPORT */
612
613 /* Load the trusted CA */
614 mbedtls_x509_crt_init(&backend->cacert);
615
616 if(ca_info_blob && verifypeer) {
617 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
618 terminated even when provided the exact length, forcing us to waste
619 extra memory here. */
620 unsigned char *newblob = Curl_memdup0(ca_info_blob->data,
621 ca_info_blob->len);
622 if(!newblob)
623 return CURLE_OUT_OF_MEMORY;
624 ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
625 ca_info_blob->len + 1);
626 free(newblob);
627 if(ret < 0) {
628 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
629 failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
630 -ret, errorbuf);
631 return CURLE_SSL_CERTPROBLEM;
632 }
633 }
634
635 if(ssl_cafile && verifypeer) {
636 #ifdef MBEDTLS_FS_IO
637 ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
638
639 if(ret < 0) {
640 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
641 failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
642 ssl_cafile, -ret, errorbuf);
643 return CURLE_SSL_CACERT_BADFILE;
644 }
645 #else
646 failf(data, "mbedtls: functions that use the filesystem not built in");
647 return CURLE_NOT_BUILT_IN;
648 #endif
649 }
650
651 if(ssl_capath) {
652 #ifdef MBEDTLS_FS_IO
653 ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath);
654
655 if(ret < 0) {
656 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
657 failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
658 ssl_capath, -ret, errorbuf);
659
660 if(verifypeer)
661 return CURLE_SSL_CACERT_BADFILE;
662 }
663 #else
664 failf(data, "mbedtls: functions that use the filesystem not built in");
665 return CURLE_NOT_BUILT_IN;
666 #endif
667 }
668
669 /* Load the client certificate */
670 mbedtls_x509_crt_init(&backend->clicert);
671
672 if(ssl_cert) {
673 #ifdef MBEDTLS_FS_IO
674 ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert);
675
676 if(ret) {
677 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
678 failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
679 ssl_cert, -ret, errorbuf);
680
681 return CURLE_SSL_CERTPROBLEM;
682 }
683 #else
684 failf(data, "mbedtls: functions that use the filesystem not built in");
685 return CURLE_NOT_BUILT_IN;
686 #endif
687 }
688
689 if(ssl_cert_blob) {
690 /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
691 terminated even when provided the exact length, forcing us to waste
692 extra memory here. */
693 unsigned char *newblob = Curl_memdup0(ssl_cert_blob->data,
694 ssl_cert_blob->len);
695 if(!newblob)
696 return CURLE_OUT_OF_MEMORY;
697 ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
698 ssl_cert_blob->len + 1);
699 free(newblob);
700
701 if(ret) {
702 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
703 failf(data, "Error reading client cert data %s - mbedTLS: (-0x%04X) %s",
704 ssl_config->key, -ret, errorbuf);
705 return CURLE_SSL_CERTPROBLEM;
706 }
707 }
708
709 /* Load the client private key */
710 mbedtls_pk_init(&backend->pk);
711
712 if(ssl_config->key || ssl_config->key_blob) {
713 if(ssl_config->key) {
714 #ifdef MBEDTLS_FS_IO
715 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
716 ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
717 ssl_config->key_passwd,
718 mbedtls_ctr_drbg_random,
719 &backend->ctr_drbg);
720 #else
721 ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
722 ssl_config->key_passwd);
723 #endif
724
725 if(ret) {
726 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
727 failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
728 ssl_config->key, -ret, errorbuf);
729 return CURLE_SSL_CERTPROBLEM;
730 }
731 #else
732 failf(data, "mbedtls: functions that use the filesystem not built in");
733 return CURLE_NOT_BUILT_IN;
734 #endif
735 }
736 else {
737 const struct curl_blob *ssl_key_blob = ssl_config->key_blob;
738 const unsigned char *key_data =
739 (const unsigned char *)ssl_key_blob->data;
740 const char *passwd = ssl_config->key_passwd;
741 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
742 ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len,
743 (const unsigned char *)passwd,
744 passwd ? strlen(passwd) : 0,
745 mbedtls_ctr_drbg_random,
746 &backend->ctr_drbg);
747 #else
748 ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len,
749 (const unsigned char *)passwd,
750 passwd ? strlen(passwd) : 0);
751 #endif
752
753 if(ret) {
754 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
755 failf(data, "Error parsing private key - mbedTLS: (-0x%04X) %s",
756 -ret, errorbuf);
757 return CURLE_SSL_CERTPROBLEM;
758 }
759 }
760
761 if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) ||
762 mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY)))
763 ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
764 }
765
766 /* Load the CRL */
767 #ifdef MBEDTLS_X509_CRL_PARSE_C
768 mbedtls_x509_crl_init(&backend->crl);
769
770 if(ssl_crlfile) {
771 #ifdef MBEDTLS_FS_IO
772 ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile);
773
774 if(ret) {
775 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
776 failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
777 ssl_crlfile, -ret, errorbuf);
778
779 return CURLE_SSL_CRL_BADFILE;
780 }
781 #else
782 failf(data, "mbedtls: functions that use the filesystem not built in");
783 return CURLE_NOT_BUILT_IN;
784 #endif
785 }
786 #else
787 if(ssl_crlfile) {
788 failf(data, "mbedtls: crl support not built in");
789 return CURLE_NOT_BUILT_IN;
790 }
791 #endif
792
793 infof(data, "mbedTLS: Connecting to %s:%d", hostname, connssl->peer.port);
794
795 mbedtls_ssl_config_init(&backend->config);
796 ret = mbedtls_ssl_config_defaults(&backend->config,
797 MBEDTLS_SSL_IS_CLIENT,
798 MBEDTLS_SSL_TRANSPORT_STREAM,
799 MBEDTLS_SSL_PRESET_DEFAULT);
800 if(ret) {
801 failf(data, "mbedTLS: ssl_config failed");
802 return CURLE_SSL_CONNECT_ERROR;
803 }
804
805 #ifdef MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED
806 /* New in mbedTLS 3.6.1, need to enable, default is now disabled */
807 mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&backend->config,
808 MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED);
809 #endif
810
811 /* Always let mbedTLS verify certificates, if verifypeer or verifyhost are
812 * disabled we clear the corresponding error flags in the verify callback
813 * function. That is also where we log verification errors. */
814 mbedtls_ssl_conf_verify(&backend->config, mbed_verify_cb, cf);
815 mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_REQUIRED);
816
817 mbedtls_ssl_init(&backend->ssl);
818 backend->initialized = TRUE;
819
820 /* new profile with RSA min key len = 1024 ... */
821 mbedtls_ssl_conf_cert_profile(&backend->config,
822 &mbedtls_x509_crt_profile_fr);
823
824 ret = mbed_set_ssl_version_min_max(data, backend, conn_config);
825 if(ret != CURLE_OK)
826 return ret;
827
828 mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random,
829 &backend->ctr_drbg);
830
831 ret = mbedtls_ssl_setup(&backend->ssl, &backend->config);
832 if(ret) {
833 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
834 failf(data, "ssl_setup failed - mbedTLS: (-0x%04X) %s",
835 -ret, errorbuf);
836 return CURLE_SSL_CONNECT_ERROR;
837 }
838
839 mbedtls_ssl_set_bio(&backend->ssl, cf,
840 mbedtls_bio_cf_write,
841 mbedtls_bio_cf_read,
842 NULL /* rev_timeout() */);
843
844 #ifndef TLS13_SUPPORT
845 if(conn_config->cipher_list) {
846 CURLcode result = mbed_set_selected_ciphers(data, backend,
847 conn_config->cipher_list,
848 NULL);
849 #else
850 if(conn_config->cipher_list || conn_config->cipher_list13) {
851 CURLcode result = mbed_set_selected_ciphers(data, backend,
852 conn_config->cipher_list,
853 conn_config->cipher_list13);
854 #endif
855 if(result != CURLE_OK) {
856 failf(data, "mbedTLS: failed to set cipher suites");
857 return result;
858 }
859 }
860 else {
861 mbedtls_ssl_conf_ciphersuites(&backend->config,
862 mbedtls_ssl_list_ciphersuites());
863 }
864
865
866 #if defined(MBEDTLS_SSL_RENEGOTIATION)
867 mbedtls_ssl_conf_renegotiation(&backend->config,
868 MBEDTLS_SSL_RENEGOTIATION_ENABLED);
869 #endif
870
871 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
872 mbedtls_ssl_conf_session_tickets(&backend->config,
873 MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
874 #endif
875
876 /* Check if there is a cached ID we can/should use here! */
877 if(ssl_config->primary.cache_session) {
878 void *sdata = NULL;
879 size_t slen = 0;
880
881 Curl_ssl_sessionid_lock(data);
882 if(!Curl_ssl_getsessionid(cf, data, &connssl->peer,
883 &sdata, &slen, NULL) && slen) {
884 mbedtls_ssl_session session;
885
886 mbedtls_ssl_session_init(&session);
887 ret = mbedtls_ssl_session_load(&session, sdata, slen);
888 if(ret) {
889 failf(data, "error loading cached session: -0x%x", -ret);
890 }
891 else {
892 ret = mbedtls_ssl_set_session(&backend->ssl, &session);
893 if(ret)
894 failf(data, "error setting session: -0x%x", -ret);
895 else
896 infof(data, "SSL reusing session ID");
897 }
898 mbedtls_ssl_session_free(&session);
899 }
900 Curl_ssl_sessionid_unlock(data);
901 }
902
903 mbedtls_ssl_conf_ca_chain(&backend->config,
904 &backend->cacert,
905 #ifdef MBEDTLS_X509_CRL_PARSE_C
906 &backend->crl);
907 #else
908 NULL);
909 #endif
910
911 if(ssl_config->key || ssl_config->key_blob) {
912 mbedtls_ssl_conf_own_cert(&backend->config,
913 &backend->clicert, &backend->pk);
914 }
915
916 if(mbedtls_ssl_set_hostname(&backend->ssl, connssl->peer.sni ?
917 connssl->peer.sni : connssl->peer.hostname)) {
918 /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and
919 the name to set in the SNI extension. So even if curl connects to a
920 host specified as an IP address, this function must be used. */
921 failf(data, "Failed to set SNI");
922 return CURLE_SSL_CONNECT_ERROR;
923 }
924
925 #ifdef HAS_ALPN
926 if(connssl->alpn) {
927 struct alpn_proto_buf proto;
928 size_t i;
929
930 for(i = 0; i < connssl->alpn->count; ++i) {
931 backend->protocols[i] = connssl->alpn->entries[i];
932 }
933 /* this function does not clone the protocols array, which is why we need
934 to keep it around */
935 if(mbedtls_ssl_conf_alpn_protocols(&backend->config,
936 &backend->protocols[0])) {
937 failf(data, "Failed setting ALPN protocols");
938 return CURLE_SSL_CONNECT_ERROR;
939 }
940 Curl_alpn_to_proto_str(&proto, connssl->alpn);
941 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
942 }
943 #endif
944
945 #ifdef MBEDTLS_DEBUG
946 /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
947 mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data);
948 /* - 0 No debug
949 * - 1 Error
950 * - 2 State change
951 * - 3 Informational
952 * - 4 Verbose
953 */
954 mbedtls_debug_set_threshold(4);
955 #endif
956
957 /* give application a chance to interfere with mbedTLS set up. */
958 if(data->set.ssl.fsslctx) {
959 CURLcode result = (*data->set.ssl.fsslctx)(data, &backend->config,
960 data->set.ssl.fsslctxp);
961 if(result != CURLE_OK) {
962 failf(data, "error signaled by ssl ctx callback");
963 return result;
964 }
965 }
966
967 connssl->connecting_state = ssl_connect_2;
968
969 return CURLE_OK;
970 }
971
972 static CURLcode
973 mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
974 {
975 int ret;
976 struct ssl_connect_data *connssl = cf->ctx;
977 struct mbed_ssl_backend_data *backend =
978 (struct mbed_ssl_backend_data *)connssl->backend;
979 #ifndef CURL_DISABLE_PROXY
980 const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf) ?
981 data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
982 data->set.str[STRING_SSL_PINNEDPUBLICKEY];
983 #else
984 const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
985 #endif
986
987 DEBUGASSERT(backend);
988
989 ret = mbedtls_ssl_handshake(&backend->ssl);
990
991 if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
992 connssl->io_need = CURL_SSL_IO_NEED_RECV;
993 return CURLE_OK;
994 }
995 else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
996 connssl->io_need = CURL_SSL_IO_NEED_SEND;
997 return CURLE_OK;
998 }
999 else if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
1000 failf(data, "peer certificate could not be verified");
1001 return CURLE_PEER_FAILED_VERIFICATION;
1002 }
1003 else if(ret) {
1004 char errorbuf[128];
1005 #if MBEDTLS_VERSION_NUMBER >= 0x03020000
1006 CURL_TRC_CF(data, cf, "TLS version %04X",
1007 mbedtls_ssl_get_version_number(&backend->ssl));
1008 #endif
1009 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
1010 failf(data, "ssl_handshake returned: (-0x%04X) %s",
1011 -ret, errorbuf);
1012 return CURLE_SSL_CONNECT_ERROR;
1013 }
1014
1015 #if MBEDTLS_VERSION_NUMBER >= 0x03020000
1016 {
1017 char cipher_str[64];
1018 uint16_t cipher_id;
1019 cipher_id = (uint16_t)
1020 mbedtls_ssl_get_ciphersuite_id_from_ssl(&backend->ssl);
1021 mbed_cipher_suite_get_str(cipher_id, cipher_str, sizeof(cipher_str), TRUE);
1022 infof(data, "mbedTLS: %s Handshake complete, cipher is %s",
1023 mbedtls_ssl_get_version(&backend->ssl), cipher_str);
1024 }
1025 #else
1026 infof(data, "mbedTLS: %s Handshake complete",
1027 mbedtls_ssl_get_version(&backend->ssl));
1028 #endif
1029
1030 if(pinnedpubkey) {
1031 int size;
1032 CURLcode result;
1033 const mbedtls_x509_crt *peercert;
1034 mbedtls_x509_crt *p = NULL;
1035 unsigned char *pubkey = NULL;
1036
1037 peercert = mbedtls_ssl_get_peer_cert(&backend->ssl);
1038 #if MBEDTLS_VERSION_NUMBER == 0x03000000
1039 if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) ||
1040 !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) {
1041 #else
1042 if(!peercert || !peercert->raw.p || !peercert->raw.len) {
1043 #endif
1044 failf(data, "Failed due to missing peer certificate");
1045 return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1046 }
1047
1048 p = calloc(1, sizeof(*p));
1049
1050 if(!p)
1051 return CURLE_OUT_OF_MEMORY;
1052
1053 pubkey = malloc(PUB_DER_MAX_BYTES);
1054
1055 if(!pubkey) {
1056 result = CURLE_OUT_OF_MEMORY;
1057 goto pinnedpubkey_error;
1058 }
1059
1060 mbedtls_x509_crt_init(p);
1061
1062 /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
1063 needs a non-const key, for now.
1064 https://github.com/Mbed-TLS/mbedtls/issues/396 */
1065 #if MBEDTLS_VERSION_NUMBER == 0x03000000
1066 if(mbedtls_x509_crt_parse_der(p,
1067 peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
1068 peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) {
1069 #else
1070 if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
1071 #endif
1072 failf(data, "Failed copying peer certificate");
1073 result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1074 goto pinnedpubkey_error;
1075 }
1076
1077 #if MBEDTLS_VERSION_NUMBER == 0x03000000
1078 size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey,
1079 PUB_DER_MAX_BYTES);
1080 #else
1081 size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
1082 #endif
1083
1084 if(size <= 0) {
1085 failf(data, "Failed copying public key from peer certificate");
1086 result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1087 goto pinnedpubkey_error;
1088 }
1089
1090 /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
1091 result = Curl_pin_peer_pubkey(data,
1092 pinnedpubkey,
1093 &pubkey[PUB_DER_MAX_BYTES - size], size);
1094 pinnedpubkey_error:
1095 mbedtls_x509_crt_free(p);
1096 free(p);
1097 free(pubkey);
1098 if(result) {
1099 return result;
1100 }
1101 }
1102
1103 #ifdef HAS_ALPN
1104 if(connssl->alpn) {
1105 const char *proto = mbedtls_ssl_get_alpn_protocol(&backend->ssl);
1106
1107 Curl_alpn_set_negotiated(cf, data, connssl, (const unsigned char *)proto,
1108 proto ? strlen(proto) : 0);
1109 }
1110 #endif
1111
1112 connssl->connecting_state = ssl_connect_3;
1113 infof(data, "SSL connected");
1114
1115 return CURLE_OK;
1116 }
1117
1118 static void mbedtls_session_free(void *session, size_t slen)
1119 {
1120 (void)slen;
1121 free(session);
1122 }
1123
1124 static CURLcode
1125 mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
1126 {
1127 struct ssl_connect_data *connssl = cf->ctx;
1128 struct mbed_ssl_backend_data *backend =
1129 (struct mbed_ssl_backend_data *)connssl->backend;
1130 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
1131 CURLcode result = CURLE_OK;
1132
1133 DEBUGASSERT(backend);
1134 if(ssl_config->primary.cache_session) {
1135 int ret;
1136 mbedtls_ssl_session session;
1137 unsigned char *sdata = NULL;
1138 size_t slen = 0;
1139
1140 mbedtls_ssl_session_init(&session);
1141 ret = mbedtls_ssl_get_session(&backend->ssl, &session);
1142 if(ret) {
1143 if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED)
1144 mbedtls_ssl_session_free(&session);
1145 failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
1146 return CURLE_SSL_CONNECT_ERROR;
1147 }
1148
1149 mbedtls_ssl_session_save(&session, NULL, 0, &slen);
1150 if(!slen) {
1151 failf(data, "failed to serialize session: length is 0");
1152 }
1153 else {
1154 sdata = malloc(slen);
1155 if(sdata) {
1156 ret = mbedtls_ssl_session_save(&session, sdata, slen, &slen);
1157 if(ret) {
1158 failf(data, "failed to serialize session: -0x%x", -ret);
1159 }
1160 else {
1161 Curl_ssl_sessionid_lock(data);
1162 result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
1163 sdata, slen, mbedtls_session_free);
1164 Curl_ssl_sessionid_unlock(data);
1165 if(!result)
1166 sdata = NULL;
1167 }
1168 }
1169 }
1170 mbedtls_ssl_session_free(&session);
1171 free(sdata);
1172 }
1173 return result;
1174 }
1175
1176 static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
1177 const void *mem, size_t len,
1178 CURLcode *curlcode)
1179 {
1180 struct ssl_connect_data *connssl = cf->ctx;
1181 struct mbed_ssl_backend_data *backend =
1182 (struct mbed_ssl_backend_data *)connssl->backend;
1183 int ret = -1;
1184
1185 (void)data;
1186 DEBUGASSERT(backend);
1187 ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len);
1188
1189 if(ret < 0) {
1190 CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X",
1191 len, -ret);
1192 *curlcode = ((ret == MBEDTLS_ERR_SSL_WANT_WRITE)
1193 #ifdef TLS13_SUPPORT
1194 || (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
1195 #endif
1196 ) ? CURLE_AGAIN : CURLE_SEND_ERROR;
1197 ret = -1;
1198 }
1199
1200 return ret;
1201 }
1202
1203 static void mbedtls_close_all(struct Curl_easy *data)
1204 {
1205 (void)data;
1206 }
1207
1208 static CURLcode mbedtls_shutdown(struct Curl_cfilter *cf,
1209 struct Curl_easy *data,
1210 bool send_shutdown, bool *done)
1211 {
1212 struct ssl_connect_data *connssl = cf->ctx;
1213 struct mbed_ssl_backend_data *backend =
1214 (struct mbed_ssl_backend_data *)connssl->backend;
1215 unsigned char buf[1024];
1216 CURLcode result = CURLE_OK;
1217 int ret;
1218 size_t i;
1219
1220 DEBUGASSERT(backend);
1221
1222 if(!backend->initialized || cf->shutdown) {
1223 *done = TRUE;
1224 return CURLE_OK;
1225 }
1226
1227 connssl->io_need = CURL_SSL_IO_NEED_NONE;
1228 *done = FALSE;
1229
1230 if(!backend->sent_shutdown) {
1231 /* do this only once */
1232 backend->sent_shutdown = TRUE;
1233 if(send_shutdown) {
1234 ret = mbedtls_ssl_close_notify(&backend->ssl);
1235 switch(ret) {
1236 case 0: /* we sent it, receive from the server */
1237 break;
1238 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: /* server also closed */
1239 *done = TRUE;
1240 goto out;
1241 case MBEDTLS_ERR_SSL_WANT_READ:
1242 connssl->io_need = CURL_SSL_IO_NEED_RECV;
1243 goto out;
1244 case MBEDTLS_ERR_SSL_WANT_WRITE:
1245 connssl->io_need = CURL_SSL_IO_NEED_SEND;
1246 goto out;
1247 default:
1248 CURL_TRC_CF(data, cf, "mbedtls_shutdown error -0x%04X", -ret);
1249 result = CURLE_RECV_ERROR;
1250 goto out;
1251 }
1252 }
1253 }
1254
1255 /* SSL should now have started the shutdown from our side. Since it
1256 * was not complete, we are lacking the close notify from the server. */
1257 for(i = 0; i < 10; ++i) {
1258 ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf));
1259 /* This seems to be a bug in mbedTLS TLSv1.3 where it reports
1260 * WANT_READ, but has not encountered an EAGAIN. */
1261 if(ret == MBEDTLS_ERR_SSL_WANT_READ)
1262 ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf));
1263 #ifdef TLS13_SUPPORT
1264 if(ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
1265 continue;
1266 #endif
1267 if(ret <= 0)
1268 break;
1269 }
1270
1271 if(ret > 0) {
1272 /* still data coming in? */
1273 CURL_TRC_CF(data, cf, "mbedtls_shutdown, still getting data");
1274 }
1275 else if(ret == 0 || (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)) {
1276 /* We got the close notify alert and are done. */
1277 CURL_TRC_CF(data, cf, "mbedtls_shutdown done");
1278 *done = TRUE;
1279 }
1280 else if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
1281 CURL_TRC_CF(data, cf, "mbedtls_shutdown, need RECV");
1282 connssl->io_need = CURL_SSL_IO_NEED_RECV;
1283 }
1284 else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
1285 CURL_TRC_CF(data, cf, "mbedtls_shutdown, need SEND");
1286 connssl->io_need = CURL_SSL_IO_NEED_SEND;
1287 }
1288 else {
1289 CURL_TRC_CF(data, cf, "mbedtls_shutdown error -0x%04X", -ret);
1290 result = CURLE_RECV_ERROR;
1291 }
1292
1293 out:
1294 cf->shutdown = (result || *done);
1295 return result;
1296 }
1297
1298 static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
1299 {
1300 struct ssl_connect_data *connssl = cf->ctx;
1301 struct mbed_ssl_backend_data *backend =
1302 (struct mbed_ssl_backend_data *)connssl->backend;
1303
1304 (void)data;
1305 DEBUGASSERT(backend);
1306 if(backend->initialized) {
1307 mbedtls_pk_free(&backend->pk);
1308 mbedtls_x509_crt_free(&backend->clicert);
1309 mbedtls_x509_crt_free(&backend->cacert);
1310 #ifdef MBEDTLS_X509_CRL_PARSE_C
1311 mbedtls_x509_crl_free(&backend->crl);
1312 #endif
1313 Curl_safefree(backend->ciphersuites);
1314 mbedtls_ssl_config_free(&backend->config);
1315 mbedtls_ssl_free(&backend->ssl);
1316 mbedtls_ctr_drbg_free(&backend->ctr_drbg);
1317 #ifndef THREADING_SUPPORT
1318 mbedtls_entropy_free(&backend->entropy);
1319 #endif /* THREADING_SUPPORT */
1320 backend->initialized = FALSE;
1321 }
1322 }
1323
1324 static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
1325 char *buf, size_t buffersize,
1326 CURLcode *curlcode)
1327 {
1328 struct ssl_connect_data *connssl = cf->ctx;
1329 struct mbed_ssl_backend_data *backend =
1330 (struct mbed_ssl_backend_data *)connssl->backend;
1331 int ret = -1;
1332
1333 (void)data;
1334 DEBUGASSERT(backend);
1335
1336 ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
1337 buffersize);
1338 if(ret <= 0) {
1339 CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X",
1340 buffersize, -ret);
1341 switch(ret) {
1342 #ifdef HAS_SESSION_TICKETS
1343 case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
1344 mbed_new_session(cf, data);
1345 FALLTHROUGH();
1346 #endif
1347 case MBEDTLS_ERR_SSL_WANT_READ:
1348 *curlcode = CURLE_AGAIN;
1349 ret = -1;
1350 break;
1351 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
1352 *curlcode = CURLE_OK;
1353 ret = 0;
1354 break;
1355 default: {
1356 char errorbuf[128];
1357 mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
1358 failf(data, "ssl_read returned: (-0x%04X) %s", -ret, errorbuf);
1359 *curlcode = CURLE_RECV_ERROR;
1360 ret = -1;
1361 break;
1362 }
1363 }
1364 }
1365 return (ssize_t)ret;
1366 }
1367
1368 static size_t mbedtls_version(char *buffer, size_t size)
1369 {
1370 #ifdef MBEDTLS_VERSION_C
1371 /* if mbedtls_version_get_number() is available it is better */
1372 unsigned int version = mbedtls_version_get_number();
1373 return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version >> 24,
1374 (version >> 16) & 0xff, (version >> 8) & 0xff);
1375 #else
1376 return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING);
1377 #endif
1378 }
1379
1380 /* 'data' might be NULL */
1381 static CURLcode mbedtls_random(struct Curl_easy *data,
1382 unsigned char *entropy, size_t length)
1383 {
1384 #if defined(MBEDTLS_CTR_DRBG_C)
1385 int ret;
1386 mbedtls_entropy_context ctr_entropy;
1387 mbedtls_ctr_drbg_context ctr_drbg;
1388 mbedtls_entropy_init(&ctr_entropy);
1389 mbedtls_ctr_drbg_init(&ctr_drbg);
1390 (void)data;
1391
1392 ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
1393 &ctr_entropy, NULL, 0);
1394
1395 if(!ret)
1396 ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
1397
1398 mbedtls_ctr_drbg_free(&ctr_drbg);
1399 mbedtls_entropy_free(&ctr_entropy);
1400
1401 return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
1402 #elif defined(MBEDTLS_HAVEGE_C)
1403 mbedtls_havege_state hs;
1404 mbedtls_havege_init(&hs);
1405 mbedtls_havege_random(&hs, entropy, length);
1406 mbedtls_havege_free(&hs);
1407 return CURLE_OK;
1408 #else
1409 return CURLE_NOT_BUILT_IN;
1410 #endif
1411 }
1412
1413 static CURLcode
1414 mbed_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
1415 bool nonblocking,
1416 bool *done)
1417 {
1418 CURLcode retcode;
1419 struct ssl_connect_data *connssl = cf->ctx;
1420 curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
1421 timediff_t timeout_ms;
1422 int what;
1423
1424 /* check if the connection has already been established */
1425 if(ssl_connection_complete == connssl->state) {
1426 *done = TRUE;
1427 return CURLE_OK;
1428 }
1429
1430 if(ssl_connect_1 == connssl->connecting_state) {
1431 /* Find out how much more time we are allowed */
1432 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1433
1434 if(timeout_ms < 0) {
1435 /* no need to continue if time already is up */
1436 failf(data, "SSL connection timeout");
1437 return CURLE_OPERATION_TIMEDOUT;
1438 }
1439 retcode = mbed_connect_step1(cf, data);
1440 if(retcode)
1441 return retcode;
1442 }
1443
1444 while(ssl_connect_2 == connssl->connecting_state) {
1445
1446 /* check allowed time left */
1447 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1448
1449 if(timeout_ms < 0) {
1450 /* no need to continue if time already is up */
1451 failf(data, "SSL connection timeout");
1452 return CURLE_OPERATION_TIMEDOUT;
1453 }
1454
1455 /* if ssl is expecting something, check if it is available. */
1456 if(connssl->io_need) {
1457 curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
1458 sockfd : CURL_SOCKET_BAD;
1459 curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
1460 sockfd : CURL_SOCKET_BAD;
1461
1462 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
1463 nonblocking ? 0 : timeout_ms);
1464 if(what < 0) {
1465 /* fatal error */
1466 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1467 return CURLE_SSL_CONNECT_ERROR;
1468 }
1469 else if(0 == what) {
1470 if(nonblocking) {
1471 *done = FALSE;
1472 return CURLE_OK;
1473 }
1474 else {
1475 /* timeout */
1476 failf(data, "SSL connection timeout");
1477 return CURLE_OPERATION_TIMEDOUT;
1478 }
1479 }
1480 /* socket is readable or writable */
1481 }
1482
1483 /* Run transaction, and return to the caller if it failed or if
1484 * this connection is part of a multi handle and this loop would
1485 * execute again. This permits the owner of a multi handle to
1486 * abort a connection attempt before step2 has completed while
1487 * ensuring that a client using select() or epoll() will always
1488 * have a valid fdset to wait on.
1489 */
1490 connssl->io_need = CURL_SSL_IO_NEED_NONE;
1491 retcode = mbed_connect_step2(cf, data);
1492 if(retcode ||
1493 (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
1494 return retcode;
1495
1496 } /* repeat step2 until all transactions are done. */
1497
1498 if(ssl_connect_3 == connssl->connecting_state) {
1499 /* For tls1.3 we get notified about new sessions */
1500 #if MBEDTLS_VERSION_NUMBER >= 0x03020000
1501 struct ssl_connect_data *ctx = cf->ctx;
1502 struct mbed_ssl_backend_data *backend =
1503 (struct mbed_ssl_backend_data *)ctx->backend;
1504
1505 if(mbedtls_ssl_get_version_number(&backend->ssl) <=
1506 MBEDTLS_SSL_VERSION_TLS1_2) {
1507 #else
1508 { /* no TLSv1.3 supported here */
1509 #endif
1510 retcode = mbed_new_session(cf, data);
1511 if(retcode)
1512 return retcode;
1513 }
1514 connssl->connecting_state = ssl_connect_done;
1515 }
1516
1517 if(ssl_connect_done == connssl->connecting_state) {
1518 connssl->state = ssl_connection_complete;
1519 *done = TRUE;
1520 }
1521 else
1522 *done = FALSE;
1523
1524 /* Reset our connect state machine */
1525 connssl->connecting_state = ssl_connect_1;
1526
1527 return CURLE_OK;
1528 }
1529
1530 static CURLcode mbedtls_connect_nonblocking(struct Curl_cfilter *cf,
1531 struct Curl_easy *data,
1532 bool *done)
1533 {
1534 return mbed_connect_common(cf, data, TRUE, done);
1535 }
1536
1537
1538 static CURLcode mbedtls_connect(struct Curl_cfilter *cf,
1539 struct Curl_easy *data)
1540 {
1541 CURLcode retcode;
1542 bool done = FALSE;
1543
1544 retcode = mbed_connect_common(cf, data, FALSE, &done);
1545 if(retcode)
1546 return retcode;
1547
1548 DEBUGASSERT(done);
1549
1550 return CURLE_OK;
1551 }
1552
1553 /*
1554 * return 0 error initializing SSL
1555 * return 1 SSL initialized successfully
1556 */
1557 static int mbedtls_init(void)
1558 {
1559 if(!Curl_mbedtlsthreadlock_thread_setup())
1560 return 0;
1561 #ifdef THREADING_SUPPORT
1562 entropy_init_mutex(&ts_entropy);
1563 #endif
1564 #ifdef TLS13_SUPPORT
1565 {
1566 int ret;
1567 #ifdef THREADING_SUPPORT
1568 Curl_mbedtlsthreadlock_lock_function(0);
1569 #endif
1570 ret = psa_crypto_init();
1571 #ifdef THREADING_SUPPORT
1572 Curl_mbedtlsthreadlock_unlock_function(0);
1573 #endif
1574 if(ret != PSA_SUCCESS)
1575 return 0;
1576 }
1577 #endif /* TLS13_SUPPORT */
1578 return 1;
1579 }
1580
1581 static void mbedtls_cleanup(void)
1582 {
1583 #ifdef THREADING_SUPPORT
1584 entropy_cleanup_mutex(&ts_entropy);
1585 #endif
1586 (void)Curl_mbedtlsthreadlock_thread_cleanup();
1587 }
1588
1589 static bool mbedtls_data_pending(struct Curl_cfilter *cf,
1590 const struct Curl_easy *data)
1591 {
1592 struct ssl_connect_data *ctx = cf->ctx;
1593 struct mbed_ssl_backend_data *backend;
1594
1595 (void)data;
1596 DEBUGASSERT(ctx && ctx->backend);
1597 backend = (struct mbed_ssl_backend_data *)ctx->backend;
1598 return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
1599 }
1600
1601 static CURLcode mbedtls_sha256sum(const unsigned char *input,
1602 size_t inputlen,
1603 unsigned char *sha256sum,
1604 size_t sha256len UNUSED_PARAM)
1605 {
1606 /* TODO: explain this for different mbedtls 2.x vs 3 version */
1607 (void)sha256len;
1608 #if MBEDTLS_VERSION_NUMBER < 0x02070000
1609 mbedtls_sha256(input, inputlen, sha256sum, 0);
1610 #else
1611 /* returns 0 on success, otherwise failure */
1612 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
1613 if(mbedtls_sha256(input, inputlen, sha256sum, 0) != 0)
1614 #else
1615 if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0)
1616 #endif
1617 return CURLE_BAD_FUNCTION_ARGUMENT;
1618 #endif
1619 return CURLE_OK;
1620 }
1621
1622 static void *mbedtls_get_internals(struct ssl_connect_data *connssl,
1623 CURLINFO info UNUSED_PARAM)
1624 {
1625 struct mbed_ssl_backend_data *backend =
1626 (struct mbed_ssl_backend_data *)connssl->backend;
1627 (void)info;
1628 DEBUGASSERT(backend);
1629 return &backend->ssl;
1630 }
1631
1632 const struct Curl_ssl Curl_ssl_mbedtls = {
1633 { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */
1634
1635 SSLSUPP_CA_PATH |
1636 SSLSUPP_CAINFO_BLOB |
1637 SSLSUPP_CERTINFO |
1638 SSLSUPP_PINNEDPUBKEY |
1639 SSLSUPP_SSL_CTX |
1640 #ifdef TLS13_SUPPORT
1641 SSLSUPP_TLS13_CIPHERSUITES |
1642 #endif
1643 SSLSUPP_HTTPS_PROXY |
1644 SSLSUPP_CIPHER_LIST,
1645
1646 sizeof(struct mbed_ssl_backend_data),
1647
1648 mbedtls_init, /* init */
1649 mbedtls_cleanup, /* cleanup */
1650 mbedtls_version, /* version */
1651 Curl_none_check_cxn, /* check_cxn */
1652 mbedtls_shutdown, /* shutdown */
1653 mbedtls_data_pending, /* data_pending */
1654 mbedtls_random, /* random */
1655 Curl_none_cert_status_request, /* cert_status_request */
1656 mbedtls_connect, /* connect */
1657 mbedtls_connect_nonblocking, /* connect_nonblocking */
1658 Curl_ssl_adjust_pollset, /* adjust_pollset */
1659 mbedtls_get_internals, /* get_internals */
1660 mbedtls_close, /* close_one */
1661 mbedtls_close_all, /* close_all */
1662 Curl_none_set_engine, /* set_engine */
1663 Curl_none_set_engine_default, /* set_engine_default */
1664 Curl_none_engines_list, /* engines_list */
1665 Curl_none_false_start, /* false_start */
1666 mbedtls_sha256sum, /* sha256sum */
1667 NULL, /* associate_connection */
1668 NULL, /* disassociate_connection */
1669 mbed_recv, /* recv decrypted data */
1670 mbed_send, /* send data to encrypt */
1671 NULL, /* get_channel_binding */
1672 };
1673
1674 #endif /* USE_MBEDTLS */
1675