1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2019 - 2022, Michael Forney, <mforney@mforney.org>
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 * SPDX-License-Identifier: curl
23 ***************************************************************************/
24 #include "curl_setup.h"
33 #include "inet_pton.h"
38 #include "curl_printf.h"
39 #include "curl_memory.h"
43 const br_x509_class *vtable;
44 br_x509_minimal_context minimal;
45 br_x509_decoder_context decoder;
51 struct ssl_backend_data {
52 br_ssl_client_context ctx;
53 struct x509_context x509;
54 unsigned char buf[BR_SSL_BUFSIZE_BIDI];
55 br_x509_trust_anchor *anchors;
57 const char *protocols[2];
58 /* SSL client context is active */
60 /* size of pending write, yet to be flushed */
64 struct cafile_parser {
67 br_x509_decoder_context xc;
68 /* array of trust anchors loaded from CAfile */
69 br_x509_trust_anchor *anchors;
71 /* buffer for DN data */
72 unsigned char dn[1024];
76 #define CAFILE_SOURCE_PATH 1
77 #define CAFILE_SOURCE_BLOB 2
78 struct cafile_source {
84 static void append_dn(void *ctx, const void *buf, size_t len)
86 struct cafile_parser *ca = ctx;
88 if(ca->err != CURLE_OK || !ca->in_cert)
90 if(sizeof(ca->dn) - ca->dn_len < len) {
91 ca->err = CURLE_FAILED_INIT;
94 memcpy(ca->dn + ca->dn_len, buf, len);
98 static void x509_push(void *ctx, const void *buf, size_t len)
100 struct cafile_parser *ca = ctx;
103 br_x509_decoder_push(&ca->xc, buf, len);
106 static CURLcode load_cafile(struct cafile_source *source,
107 br_x509_trust_anchor **anchors,
110 struct cafile_parser ca;
111 br_pem_decoder_context pc;
112 br_x509_trust_anchor *ta;
114 br_x509_trust_anchor *new_anchors;
115 size_t new_anchors_len;
118 unsigned char buf[BUFSIZ];
119 const unsigned char *p;
123 DEBUGASSERT(source->type == CAFILE_SOURCE_PATH
124 || source->type == CAFILE_SOURCE_BLOB);
126 if(source->type == CAFILE_SOURCE_PATH) {
127 fp = fopen(source->data, "rb");
129 return CURLE_SSL_CACERT_BADFILE;
132 if(source->type == CAFILE_SOURCE_BLOB && source->len > (size_t)INT_MAX)
133 return CURLE_SSL_CACERT_BADFILE;
139 br_pem_decoder_init(&pc);
140 br_pem_decoder_setdest(&pc, x509_push, &ca);
142 if(source->type == CAFILE_SOURCE_PATH) {
143 n = fread(buf, 1, sizeof(buf), fp);
148 else if(source->type == CAFILE_SOURCE_BLOB) {
150 p = (unsigned char *) source->data;
153 pushed = br_pem_decoder_push(&pc, p, n);
159 switch(br_pem_decoder_event(&pc)) {
162 case BR_PEM_BEGIN_OBJ:
163 name = br_pem_decoder_name(&pc);
164 if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE"))
166 br_x509_decoder_init(&ca.xc, append_dn, &ca);
174 if(br_x509_decoder_last_error(&ca.xc)) {
175 ca.err = CURLE_SSL_CACERT_BADFILE;
178 /* add trust anchor */
179 if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) {
180 ca.err = CURLE_OUT_OF_MEMORY;
183 new_anchors_len = ca.anchors_len + 1;
184 new_anchors = realloc(ca.anchors,
185 new_anchors_len * sizeof(ca.anchors[0]));
187 ca.err = CURLE_OUT_OF_MEMORY;
190 ca.anchors = new_anchors;
191 ca.anchors_len = new_anchors_len;
192 ta = &ca.anchors[ca.anchors_len - 1];
195 if(br_x509_decoder_isCA(&ca.xc))
196 ta->flags |= BR_X509_TA_CA;
197 pkey = br_x509_decoder_get_pkey(&ca.xc);
199 ca.err = CURLE_SSL_CACERT_BADFILE;
204 /* calculate space needed for trust anchor data */
206 switch(pkey->key_type) {
208 ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen;
211 ta_size += pkey->key.ec.qlen;
214 ca.err = CURLE_FAILED_INIT;
218 /* fill in trust anchor DN and public key data */
219 ta->dn.data = malloc(ta_size);
221 ca.err = CURLE_OUT_OF_MEMORY;
224 memcpy(ta->dn.data, ca.dn, ca.dn_len);
225 ta->dn.len = ca.dn_len;
226 switch(pkey->key_type) {
228 ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len;
229 memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen);
230 ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen;
231 memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen);
234 ta->pkey.key.ec.q = ta->dn.data + ta->dn.len;
235 memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen);
240 ca.err = CURLE_SSL_CACERT_BADFILE;
244 } while(source->type != CAFILE_SOURCE_BLOB);
246 ca.err = CURLE_READ_ERROR;
248 ca.err = CURLE_SSL_CACERT_BADFILE;
253 if(ca.err == CURLE_OK) {
254 *anchors = ca.anchors;
255 *anchors_len = ca.anchors_len;
258 for(i = 0; i < ca.anchors_len; ++i)
259 free(ca.anchors[i].dn.data);
266 static void x509_start_chain(const br_x509_class **ctx,
267 const char *server_name)
269 struct x509_context *x509 = (struct x509_context *)ctx;
271 if(!x509->verifypeer) {
276 if(!x509->verifyhost)
278 x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name);
281 static void x509_start_cert(const br_x509_class **ctx, uint32_t length)
283 struct x509_context *x509 = (struct x509_context *)ctx;
285 if(!x509->verifypeer) {
286 /* Only decode the first cert in the chain to obtain the public key */
287 if(x509->cert_num == 0)
288 br_x509_decoder_init(&x509->decoder, NULL, NULL);
292 x509->minimal.vtable->start_cert(&x509->minimal.vtable, length);
295 static void x509_append(const br_x509_class **ctx, const unsigned char *buf,
298 struct x509_context *x509 = (struct x509_context *)ctx;
300 if(!x509->verifypeer) {
301 if(x509->cert_num == 0)
302 br_x509_decoder_push(&x509->decoder, buf, len);
306 x509->minimal.vtable->append(&x509->minimal.vtable, buf, len);
309 static void x509_end_cert(const br_x509_class **ctx)
311 struct x509_context *x509 = (struct x509_context *)ctx;
313 if(!x509->verifypeer) {
318 x509->minimal.vtable->end_cert(&x509->minimal.vtable);
321 static unsigned x509_end_chain(const br_x509_class **ctx)
323 struct x509_context *x509 = (struct x509_context *)ctx;
325 if(!x509->verifypeer) {
326 return br_x509_decoder_last_error(&x509->decoder);
329 return x509->minimal.vtable->end_chain(&x509->minimal.vtable);
332 static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx,
335 struct x509_context *x509 = (struct x509_context *)ctx;
337 if(!x509->verifypeer) {
338 /* Nothing in the chain is verified, just return the public key of the
339 first certificate and allow its usage for both TLS_RSA_* and
342 *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN;
343 return br_x509_decoder_get_pkey(&x509->decoder);
346 return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages);
349 static const br_x509_class x509_vtable = {
350 sizeof(struct x509_context),
360 const char *name; /* Cipher suite IANA name. It starts with "TLS_" prefix */
361 const char *alias_name; /* Alias name is the same as OpenSSL cipher name */
362 uint16_t num; /* BearSSL cipher suite */
365 /* Macro to initialize st_cipher data structure */
366 #define CIPHER_DEF(num, alias) { #num, alias, BR_##num }
368 static const struct st_cipher ciphertable[] = {
369 /* RFC 2246 TLS 1.0 */
370 CIPHER_DEF(TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */
373 /* RFC 3268 TLS 1.0 AES */
374 CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */
376 CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */
379 /* RFC 5246 TLS 1.2 */
380 CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */
382 CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */
385 /* RFC 5288 TLS 1.2 AES GCM */
386 CIPHER_DEF(TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */
387 "AES128-GCM-SHA256"),
388 CIPHER_DEF(TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */
389 "AES256-GCM-SHA384"),
391 /* RFC 4492 TLS 1.0 ECC */
392 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */
393 "ECDH-ECDSA-DES-CBC3-SHA"),
394 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */
395 "ECDH-ECDSA-AES128-SHA"),
396 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */
397 "ECDH-ECDSA-AES256-SHA"),
398 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */
399 "ECDHE-ECDSA-DES-CBC3-SHA"),
400 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */
401 "ECDHE-ECDSA-AES128-SHA"),
402 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */
403 "ECDHE-ECDSA-AES256-SHA"),
404 CIPHER_DEF(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */
405 "ECDH-RSA-DES-CBC3-SHA"),
406 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */
407 "ECDH-RSA-AES128-SHA"),
408 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */
409 "ECDH-RSA-AES256-SHA"),
410 CIPHER_DEF(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */
411 "ECDHE-RSA-DES-CBC3-SHA"),
412 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */
413 "ECDHE-RSA-AES128-SHA"),
414 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */
415 "ECDHE-RSA-AES256-SHA"),
417 /* RFC 5289 TLS 1.2 ECC HMAC SHA256/384 */
418 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */
419 "ECDHE-ECDSA-AES128-SHA256"),
420 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */
421 "ECDHE-ECDSA-AES256-SHA384"),
422 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */
423 "ECDH-ECDSA-AES128-SHA256"),
424 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */
425 "ECDH-ECDSA-AES256-SHA384"),
426 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */
427 "ECDHE-RSA-AES128-SHA256"),
428 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */
429 "ECDHE-RSA-AES256-SHA384"),
430 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */
431 "ECDH-RSA-AES128-SHA256"),
432 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */
433 "ECDH-RSA-AES256-SHA384"),
435 /* RFC 5289 TLS 1.2 GCM */
436 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */
437 "ECDHE-ECDSA-AES128-GCM-SHA256"),
438 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */
439 "ECDHE-ECDSA-AES256-GCM-SHA384"),
440 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */
441 "ECDH-ECDSA-AES128-GCM-SHA256"),
442 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */
443 "ECDH-ECDSA-AES256-GCM-SHA384"),
444 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */
445 "ECDHE-RSA-AES128-GCM-SHA256"),
446 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */
447 "ECDHE-RSA-AES256-GCM-SHA384"),
448 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */
449 "ECDH-RSA-AES128-GCM-SHA256"),
450 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */
451 "ECDH-RSA-AES256-GCM-SHA384"),
452 #ifdef BR_TLS_RSA_WITH_AES_128_CCM
454 /* RFC 6655 TLS 1.2 CCM
455 Supported since BearSSL 0.6 */
456 CIPHER_DEF(TLS_RSA_WITH_AES_128_CCM, /* 0xC09C */
458 CIPHER_DEF(TLS_RSA_WITH_AES_256_CCM, /* 0xC09D */
460 CIPHER_DEF(TLS_RSA_WITH_AES_128_CCM_8, /* 0xC0A0 */
462 CIPHER_DEF(TLS_RSA_WITH_AES_256_CCM_8, /* 0xC0A1 */
465 /* RFC 7251 TLS 1.2 ECC CCM
466 Supported since BearSSL 0.6 */
467 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CCM, /* 0xC0AC */
468 "ECDHE-ECDSA-AES128-CCM"),
469 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CCM, /* 0xC0AD */
470 "ECDHE-ECDSA-AES256-CCM"),
471 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, /* 0xC0AE */
472 "ECDHE-ECDSA-AES128-CCM8"),
473 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, /* 0xC0AF */
474 "ECDHE-ECDSA-AES256-CCM8"),
477 /* RFC 7905 TLS 1.2 ChaCha20-Poly1305
478 Supported since BearSSL 0.2 */
479 CIPHER_DEF(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */
480 "ECDHE-RSA-CHACHA20-POLY1305"),
481 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */
482 "ECDHE-ECDSA-CHACHA20-POLY1305"),
485 #define NUM_OF_CIPHERS (sizeof(ciphertable) / sizeof(ciphertable[0]))
486 #define CIPHER_NAME_BUF_LEN 64
488 static bool is_separator(char c)
490 /* Return whether character is a cipher list separator. */
502 static CURLcode bearssl_set_selected_ciphers(struct Curl_easy *data,
503 br_ssl_engine_context *ssl_eng,
506 uint16_t selected_ciphers[NUM_OF_CIPHERS];
507 size_t selected_count = 0;
508 char cipher_name[CIPHER_NAME_BUF_LEN];
509 const char *cipher_start = ciphers;
510 const char *cipher_end;
514 return CURLE_SSL_CIPHER;
517 /* Extract the next cipher name from the ciphers string */
518 while(is_separator(*cipher_start))
520 if(*cipher_start == '\0')
522 cipher_end = cipher_start;
523 while(*cipher_end != '\0' && !is_separator(*cipher_end))
525 j = cipher_end - cipher_start < CIPHER_NAME_BUF_LEN - 1 ?
526 cipher_end - cipher_start : CIPHER_NAME_BUF_LEN - 1;
527 strncpy(cipher_name, cipher_start, j);
528 cipher_name[j] = '\0';
529 cipher_start = cipher_end;
531 /* Lookup the cipher name in the table of available ciphers. If the cipher
532 name starts with "TLS_" we do the lookup by IANA name. Otherwise, we try
533 to match cipher name by an (OpenSSL) alias. */
534 if(strncasecompare(cipher_name, "TLS_", 4)) {
535 for(i = 0; i < NUM_OF_CIPHERS &&
536 !strcasecompare(cipher_name, ciphertable[i].name); ++i);
539 for(i = 0; i < NUM_OF_CIPHERS &&
540 !strcasecompare(cipher_name, ciphertable[i].alias_name); ++i);
542 if(i == NUM_OF_CIPHERS) {
543 infof(data, "BearSSL: unknown cipher in list: %s", cipher_name);
547 /* No duplicates allowed */
548 for(j = 0; j < selected_count &&
549 selected_ciphers[j] != ciphertable[i].num; j++);
550 if(j < selected_count) {
551 infof(data, "BearSSL: duplicate cipher in list: %s", cipher_name);
555 DEBUGASSERT(selected_count < NUM_OF_CIPHERS);
556 selected_ciphers[selected_count] = ciphertable[i].num;
560 if(selected_count == 0) {
561 failf(data, "BearSSL: no supported cipher in list");
562 return CURLE_SSL_CIPHER;
565 br_ssl_engine_set_suites(ssl_eng, selected_ciphers, selected_count);
569 static CURLcode bearssl_connect_step1(struct Curl_easy *data,
570 struct connectdata *conn, int sockindex)
572 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
573 struct ssl_backend_data *backend = connssl->backend;
574 const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
575 const char * const ssl_cafile =
576 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
577 (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
578 const char *hostname = SSL_HOST_NAME();
579 const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
580 const bool verifyhost = SSL_CONN_CONFIG(verifyhost);
582 unsigned version_min, version_max;
584 struct in6_addr addr;
589 DEBUGASSERT(backend);
591 switch(SSL_CONN_CONFIG(version)) {
592 case CURL_SSLVERSION_SSLv2:
593 failf(data, "BearSSL does not support SSLv2");
594 return CURLE_SSL_CONNECT_ERROR;
595 case CURL_SSLVERSION_SSLv3:
596 failf(data, "BearSSL does not support SSLv3");
597 return CURLE_SSL_CONNECT_ERROR;
598 case CURL_SSLVERSION_TLSv1_0:
599 version_min = BR_TLS10;
600 version_max = BR_TLS10;
602 case CURL_SSLVERSION_TLSv1_1:
603 version_min = BR_TLS11;
604 version_max = BR_TLS11;
606 case CURL_SSLVERSION_TLSv1_2:
607 version_min = BR_TLS12;
608 version_max = BR_TLS12;
610 case CURL_SSLVERSION_DEFAULT:
611 case CURL_SSLVERSION_TLSv1:
612 version_min = BR_TLS10;
613 version_max = BR_TLS12;
616 failf(data, "BearSSL: unknown CURLOPT_SSLVERSION");
617 return CURLE_SSL_CONNECT_ERROR;
621 struct cafile_source source;
622 source.type = CAFILE_SOURCE_BLOB;
623 source.data = ca_info_blob->data;
624 source.len = ca_info_blob->len;
626 ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
627 if(ret != CURLE_OK) {
629 failf(data, "error importing CA certificate blob");
632 /* Only warn if no certificate verification is required. */
633 infof(data, "error importing CA certificate blob, continuing anyway");
638 struct cafile_source source;
639 source.type = CAFILE_SOURCE_PATH;
640 source.data = ssl_cafile;
643 ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
644 if(ret != CURLE_OK) {
646 failf(data, "error setting certificate verify locations."
647 " CAfile: %s", ssl_cafile);
650 infof(data, "error setting certificate verify locations,"
651 " continuing anyway:");
655 /* initialize SSL context */
656 br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal,
657 backend->anchors, backend->anchors_len);
658 br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max);
659 br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf,
660 sizeof(backend->buf), 1);
662 if(SSL_CONN_CONFIG(cipher_list)) {
663 /* Override the ciphers as specified. For the default cipher list see the
664 BearSSL source code of br_ssl_client_init_full() */
665 ret = bearssl_set_selected_ciphers(data, &backend->ctx.eng,
666 SSL_CONN_CONFIG(cipher_list));
671 /* initialize X.509 context */
672 backend->x509.vtable = &x509_vtable;
673 backend->x509.verifypeer = verifypeer;
674 backend->x509.verifyhost = verifyhost;
675 br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable);
677 if(SSL_SET_OPTION(primary.sessionid)) {
680 Curl_ssl_sessionid_lock(data);
681 if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
682 &session, NULL, sockindex)) {
683 br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
684 infof(data, "BearSSL: re-using session ID");
686 Curl_ssl_sessionid_unlock(data);
689 if(conn->bits.tls_enable_alpn) {
692 /* NOTE: when adding more protocols here, increase the size of the
693 * protocols array in `struct ssl_backend_data`.
697 if(data->state.httpwant >= CURL_HTTP_VERSION_2
698 #ifndef CURL_DISABLE_PROXY
699 && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
702 backend->protocols[cur++] = ALPN_H2;
703 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
707 backend->protocols[cur++] = ALPN_HTTP_1_1;
708 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
710 br_ssl_engine_set_protocol_names(&backend->ctx.eng,
711 backend->protocols, cur);
714 if((1 == Curl_inet_pton(AF_INET, hostname, &addr))
716 || (1 == Curl_inet_pton(AF_INET6, hostname, &addr))
720 failf(data, "BearSSL: "
721 "host verification of IP address is not supported");
722 return CURLE_PEER_FAILED_VERIFICATION;
727 char *snihost = Curl_ssl_snihost(data, hostname, NULL);
729 failf(data, "Failed to set SNI");
730 return CURLE_SSL_CONNECT_ERROR;
735 /* give application a chance to interfere with SSL set up. */
736 if(data->set.ssl.fsslctx) {
737 Curl_set_in_callback(data, true);
738 ret = (*data->set.ssl.fsslctx)(data, &backend->ctx,
739 data->set.ssl.fsslctxp);
740 Curl_set_in_callback(data, false);
742 failf(data, "BearSSL: error signaled by ssl ctx callback");
747 if(!br_ssl_client_reset(&backend->ctx, hostname, 1))
748 return CURLE_FAILED_INIT;
749 backend->active = TRUE;
751 connssl->connecting_state = ssl_connect_2;
756 static CURLcode bearssl_run_until(struct Curl_easy *data,
757 struct connectdata *conn, int sockindex,
760 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
761 struct ssl_backend_data *backend = connssl->backend;
762 curl_socket_t sockfd = conn->sock[sockindex];
769 DEBUGASSERT(backend);
772 state = br_ssl_engine_current_state(&backend->ctx.eng);
773 if(state & BR_SSL_CLOSED) {
774 err = br_ssl_engine_last_error(&backend->ctx.eng);
777 /* TLS close notify */
778 if(connssl->state != ssl_connection_complete) {
779 failf(data, "SSL: connection closed during handshake");
780 return CURLE_SSL_CONNECT_ERROR;
783 case BR_ERR_X509_EXPIRED:
784 failf(data, "SSL: X.509 verification: "
785 "certificate is expired or not yet valid");
786 return CURLE_PEER_FAILED_VERIFICATION;
787 case BR_ERR_X509_BAD_SERVER_NAME:
788 failf(data, "SSL: X.509 verification: "
789 "expected server name was not found in the chain");
790 return CURLE_PEER_FAILED_VERIFICATION;
791 case BR_ERR_X509_NOT_TRUSTED:
792 failf(data, "SSL: X.509 verification: "
793 "chain could not be linked to a trust anchor");
794 return CURLE_PEER_FAILED_VERIFICATION;
796 /* X.509 errors are documented to have the range 32..63 */
797 if(err >= 32 && err < 64)
798 return CURLE_PEER_FAILED_VERIFICATION;
799 return CURLE_SSL_CONNECT_ERROR;
803 if(state & BR_SSL_SENDREC) {
804 buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
805 ret = swrite(sockfd, buf, len);
807 if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
808 if(connssl->state != ssl_connection_complete)
809 connssl->connecting_state = ssl_connect_2_writing;
812 return CURLE_WRITE_ERROR;
814 br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
816 else if(state & BR_SSL_RECVREC) {
817 buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
818 ret = sread(sockfd, buf, len);
820 failf(data, "SSL: EOF without close notify");
821 return CURLE_READ_ERROR;
824 if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
825 if(connssl->state != ssl_connection_complete)
826 connssl->connecting_state = ssl_connect_2_reading;
829 return CURLE_READ_ERROR;
831 br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
836 static CURLcode bearssl_connect_step2(struct Curl_easy *data,
837 struct connectdata *conn, int sockindex)
839 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
840 struct ssl_backend_data *backend = connssl->backend;
843 DEBUGASSERT(backend);
845 ret = bearssl_run_until(data, conn, sockindex,
846 BR_SSL_SENDAPP | BR_SSL_RECVAPP);
847 if(ret == CURLE_AGAIN)
849 if(ret == CURLE_OK) {
850 if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) {
851 failf(data, "SSL: connection closed during handshake");
852 return CURLE_SSL_CONNECT_ERROR;
854 connssl->connecting_state = ssl_connect_3;
859 static CURLcode bearssl_connect_step3(struct Curl_easy *data,
860 struct connectdata *conn, int sockindex)
862 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
863 struct ssl_backend_data *backend = connssl->backend;
866 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
867 DEBUGASSERT(backend);
869 if(conn->bits.tls_enable_alpn) {
870 const char *protocol;
872 protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng);
874 infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, protocol);
877 if(!strcmp(protocol, ALPN_H2))
878 conn->alpn = CURL_HTTP_VERSION_2;
881 if(!strcmp(protocol, ALPN_HTTP_1_1))
882 conn->alpn = CURL_HTTP_VERSION_1_1;
884 infof(data, "ALPN, unrecognized protocol %s", protocol);
885 Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
886 BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
889 infof(data, VTLS_INFOF_NO_ALPN);
892 if(SSL_SET_OPTION(primary.sessionid)) {
896 br_ssl_session_parameters *session;
898 session = malloc(sizeof(*session));
900 return CURLE_OUT_OF_MEMORY;
901 br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
902 Curl_ssl_sessionid_lock(data);
903 incache = !(Curl_ssl_getsessionid(data, conn,
904 SSL_IS_PROXY() ? TRUE : FALSE,
905 &oldsession, NULL, sockindex));
907 Curl_ssl_delsessionid(data, oldsession);
908 ret = Curl_ssl_addsessionid(data, conn,
909 SSL_IS_PROXY() ? TRUE : FALSE,
910 session, 0, sockindex, &added);
911 Curl_ssl_sessionid_unlock(data);
915 return CURLE_OUT_OF_MEMORY;
919 connssl->connecting_state = ssl_connect_done;
924 static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
925 const void *buf, size_t len, CURLcode *err)
927 struct connectdata *conn = data->conn;
928 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
929 struct ssl_backend_data *backend = connssl->backend;
933 DEBUGASSERT(backend);
936 *err = bearssl_run_until(data, conn, sockindex, BR_SSL_SENDAPP);
937 if (*err != CURLE_OK)
939 app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen);
941 failf(data, "SSL: connection closed during write");
942 *err = CURLE_SEND_ERROR;
945 if(backend->pending_write) {
946 applen = backend->pending_write;
947 backend->pending_write = 0;
952 memcpy(app, buf, applen);
953 br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen);
954 br_ssl_engine_flush(&backend->ctx.eng, 0);
955 backend->pending_write = applen;
959 static ssize_t bearssl_recv(struct Curl_easy *data, int sockindex,
960 char *buf, size_t len, CURLcode *err)
962 struct connectdata *conn = data->conn;
963 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
964 struct ssl_backend_data *backend = connssl->backend;
968 DEBUGASSERT(backend);
970 *err = bearssl_run_until(data, conn, sockindex, BR_SSL_RECVAPP);
973 app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen);
978 memcpy(buf, app, applen);
979 br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen);
984 static CURLcode bearssl_connect_common(struct Curl_easy *data,
985 struct connectdata *conn,
991 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
992 curl_socket_t sockfd = conn->sock[sockindex];
993 timediff_t timeout_ms;
996 /* check if the connection has already been established */
997 if(ssl_connection_complete == connssl->state) {
1002 if(ssl_connect_1 == connssl->connecting_state) {
1003 ret = bearssl_connect_step1(data, conn, sockindex);
1008 while(ssl_connect_2 == connssl->connecting_state ||
1009 ssl_connect_2_reading == connssl->connecting_state ||
1010 ssl_connect_2_writing == connssl->connecting_state) {
1011 /* check allowed time left */
1012 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1014 if(timeout_ms < 0) {
1015 /* no need to continue if time already is up */
1016 failf(data, "SSL connection timeout");
1017 return CURLE_OPERATION_TIMEDOUT;
1020 /* if ssl is expecting something, check if it's available. */
1021 if(ssl_connect_2_reading == connssl->connecting_state ||
1022 ssl_connect_2_writing == connssl->connecting_state) {
1024 curl_socket_t writefd = ssl_connect_2_writing ==
1025 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1026 curl_socket_t readfd = ssl_connect_2_reading ==
1027 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1029 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
1030 nonblocking?0:timeout_ms);
1033 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1034 return CURLE_SSL_CONNECT_ERROR;
1036 else if(0 == what) {
1043 failf(data, "SSL connection timeout");
1044 return CURLE_OPERATION_TIMEDOUT;
1047 /* socket is readable or writable */
1050 /* Run transaction, and return to the caller if it failed or if this
1051 * connection is done nonblocking and this loop would execute again. This
1052 * permits the owner of a multi handle to abort a connection attempt
1053 * before step2 has completed while ensuring that a client using select()
1054 * or epoll() will always have a valid fdset to wait on.
1056 ret = bearssl_connect_step2(data, conn, sockindex);
1057 if(ret || (nonblocking &&
1058 (ssl_connect_2 == connssl->connecting_state ||
1059 ssl_connect_2_reading == connssl->connecting_state ||
1060 ssl_connect_2_writing == connssl->connecting_state)))
1064 if(ssl_connect_3 == connssl->connecting_state) {
1065 ret = bearssl_connect_step3(data, conn, sockindex);
1070 if(ssl_connect_done == connssl->connecting_state) {
1071 connssl->state = ssl_connection_complete;
1072 conn->recv[sockindex] = bearssl_recv;
1073 conn->send[sockindex] = bearssl_send;
1079 /* Reset our connect state machine */
1080 connssl->connecting_state = ssl_connect_1;
1085 static size_t bearssl_version(char *buffer, size_t size)
1087 return msnprintf(buffer, size, "BearSSL");
1090 static bool bearssl_data_pending(const struct connectdata *conn,
1093 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
1094 struct ssl_backend_data *backend = connssl->backend;
1095 DEBUGASSERT(backend);
1096 return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
1099 static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
1100 unsigned char *entropy, size_t length)
1102 static br_hmac_drbg_context ctx;
1103 static bool seeded = FALSE;
1106 br_prng_seeder seeder;
1108 br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0);
1109 seeder = br_prng_seeder_system(NULL);
1110 if(!seeder || !seeder(&ctx.vtable))
1111 return CURLE_FAILED_INIT;
1114 br_hmac_drbg_generate(&ctx, entropy, length);
1119 static CURLcode bearssl_connect(struct Curl_easy *data,
1120 struct connectdata *conn, int sockindex)
1125 ret = bearssl_connect_common(data, conn, sockindex, FALSE, &done);
1134 static CURLcode bearssl_connect_nonblocking(struct Curl_easy *data,
1135 struct connectdata *conn,
1136 int sockindex, bool *done)
1138 return bearssl_connect_common(data, conn, sockindex, TRUE, done);
1141 static void *bearssl_get_internals(struct ssl_connect_data *connssl,
1142 CURLINFO info UNUSED_PARAM)
1144 struct ssl_backend_data *backend = connssl->backend;
1145 DEBUGASSERT(backend);
1146 return &backend->ctx;
1149 static void bearssl_close(struct Curl_easy *data,
1150 struct connectdata *conn, int sockindex)
1152 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1153 struct ssl_backend_data *backend = connssl->backend;
1156 DEBUGASSERT(backend);
1158 if(backend->active) {
1159 br_ssl_engine_close(&backend->ctx.eng);
1160 (void)bearssl_run_until(data, conn, sockindex, BR_SSL_CLOSED);
1162 for(i = 0; i < backend->anchors_len; ++i)
1163 free(backend->anchors[i].dn.data);
1164 free(backend->anchors);
1167 static void bearssl_session_free(void *ptr)
1172 static CURLcode bearssl_sha256sum(const unsigned char *input,
1174 unsigned char *sha256sum,
1175 size_t sha256len UNUSED_PARAM)
1177 br_sha256_context ctx;
1179 br_sha256_init(&ctx);
1180 br_sha256_update(&ctx, input, inputlen);
1181 br_sha256_out(&ctx, sha256sum);
1185 const struct Curl_ssl Curl_ssl_bearssl = {
1186 { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
1187 SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX,
1188 sizeof(struct ssl_backend_data),
1190 Curl_none_init, /* init */
1191 Curl_none_cleanup, /* cleanup */
1192 bearssl_version, /* version */
1193 Curl_none_check_cxn, /* check_cxn */
1194 Curl_none_shutdown, /* shutdown */
1195 bearssl_data_pending, /* data_pending */
1196 bearssl_random, /* random */
1197 Curl_none_cert_status_request, /* cert_status_request */
1198 bearssl_connect, /* connect */
1199 bearssl_connect_nonblocking, /* connect_nonblocking */
1200 Curl_ssl_getsock, /* getsock */
1201 bearssl_get_internals, /* get_internals */
1202 bearssl_close, /* close_one */
1203 Curl_none_close_all, /* close_all */
1204 bearssl_session_free, /* session_free */
1205 Curl_none_set_engine, /* set_engine */
1206 Curl_none_set_engine_default, /* set_engine_default */
1207 Curl_none_engines_list, /* engines_list */
1208 Curl_none_false_start, /* false_start */
1209 bearssl_sha256sum, /* sha256sum */
1210 NULL, /* associate_connection */
1211 NULL /* disassociate_connection */
1214 #endif /* USE_BEARSSL */