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