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