1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Michael Forney, <mforney@mforney.org>
9 *
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.
13 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24 #include "curl_setup.h"
25
26 #ifdef USE_BEARSSL
27
28 #include <bearssl.h>
29
30 #include "bearssl.h"
31 #include "cipher_suite.h"
32 #include "urldata.h"
33 #include "sendf.h"
34 #include "inet_pton.h"
35 #include "vtls.h"
36 #include "vtls_int.h"
37 #include "connect.h"
38 #include "select.h"
39 #include "multiif.h"
40 #include "curl_printf.h"
41
42 /* The last #include files should be: */
43 #include "curl_memory.h"
44 #include "memdebug.h"
45
46 struct x509_context {
47 const br_x509_class *vtable;
48 br_x509_minimal_context minimal;
49 br_x509_decoder_context decoder;
50 bool verifyhost;
51 bool verifypeer;
52 int cert_num;
53 };
54
55 struct bearssl_ssl_backend_data {
56 br_ssl_client_context ctx;
57 struct x509_context x509;
58 unsigned char buf[BR_SSL_BUFSIZE_BIDI];
59 br_x509_trust_anchor *anchors;
60 size_t anchors_len;
61 const char *protocols[ALPN_ENTRIES_MAX];
62 /* SSL client context is active */
63 bool active;
64 /* size of pending write, yet to be flushed */
65 size_t pending_write;
66 BIT(sent_shutdown);
67 };
68
69 struct cafile_parser {
70 CURLcode err;
71 bool in_cert;
72 br_x509_decoder_context xc;
73 /* array of trust anchors loaded from CAfile */
74 br_x509_trust_anchor *anchors;
75 size_t anchors_len;
76 /* buffer for DN data */
77 unsigned char dn[1024];
78 size_t dn_len;
79 };
80
81 #define CAFILE_SOURCE_PATH 1
82 #define CAFILE_SOURCE_BLOB 2
83 struct cafile_source {
84 int type;
85 const char *data;
86 size_t len;
87 };
88
append_dn(void * ctx,const void * buf,size_t len)89 static void append_dn(void *ctx, const void *buf, size_t len)
90 {
91 struct cafile_parser *ca = ctx;
92
93 if(ca->err != CURLE_OK || !ca->in_cert)
94 return;
95 if(sizeof(ca->dn) - ca->dn_len < len) {
96 ca->err = CURLE_FAILED_INIT;
97 return;
98 }
99 memcpy(ca->dn + ca->dn_len, buf, len);
100 ca->dn_len += len;
101 }
102
x509_push(void * ctx,const void * buf,size_t len)103 static void x509_push(void *ctx, const void *buf, size_t len)
104 {
105 struct cafile_parser *ca = ctx;
106
107 if(ca->in_cert)
108 br_x509_decoder_push(&ca->xc, buf, len);
109 }
110
load_cafile(struct cafile_source * source,br_x509_trust_anchor ** anchors,size_t * anchors_len)111 static CURLcode load_cafile(struct cafile_source *source,
112 br_x509_trust_anchor **anchors,
113 size_t *anchors_len)
114 {
115 struct cafile_parser ca;
116 br_pem_decoder_context pc;
117 br_x509_trust_anchor *ta;
118 size_t ta_size;
119 br_x509_trust_anchor *new_anchors;
120 size_t new_anchors_len;
121 br_x509_pkey *pkey;
122 FILE *fp = 0;
123 unsigned char buf[BUFSIZ];
124 const unsigned char *p = NULL;
125 const char *name;
126 size_t n = 0, i, pushed;
127
128 DEBUGASSERT(source->type == CAFILE_SOURCE_PATH
129 || source->type == CAFILE_SOURCE_BLOB);
130
131 if(source->type == CAFILE_SOURCE_PATH) {
132 fp = fopen(source->data, "rb");
133 if(!fp)
134 return CURLE_SSL_CACERT_BADFILE;
135 }
136
137 if(source->type == CAFILE_SOURCE_BLOB && source->len > (size_t)INT_MAX)
138 return CURLE_SSL_CACERT_BADFILE;
139
140 ca.err = CURLE_OK;
141 ca.in_cert = FALSE;
142 ca.anchors = NULL;
143 ca.anchors_len = 0;
144 br_pem_decoder_init(&pc);
145 br_pem_decoder_setdest(&pc, x509_push, &ca);
146 do {
147 if(source->type == CAFILE_SOURCE_PATH) {
148 n = fread(buf, 1, sizeof(buf), fp);
149 if(n == 0)
150 break;
151 p = buf;
152 }
153 else if(source->type == CAFILE_SOURCE_BLOB) {
154 n = source->len;
155 p = (unsigned char *) source->data;
156 }
157 while(n) {
158 pushed = br_pem_decoder_push(&pc, p, n);
159 if(ca.err)
160 goto fail;
161 p += pushed;
162 n -= pushed;
163
164 switch(br_pem_decoder_event(&pc)) {
165 case 0:
166 break;
167 case BR_PEM_BEGIN_OBJ:
168 name = br_pem_decoder_name(&pc);
169 if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE"))
170 break;
171 br_x509_decoder_init(&ca.xc, append_dn, &ca);
172 ca.in_cert = TRUE;
173 ca.dn_len = 0;
174 break;
175 case BR_PEM_END_OBJ:
176 if(!ca.in_cert)
177 break;
178 ca.in_cert = FALSE;
179 if(br_x509_decoder_last_error(&ca.xc)) {
180 ca.err = CURLE_SSL_CACERT_BADFILE;
181 goto fail;
182 }
183 /* add trust anchor */
184 if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) {
185 ca.err = CURLE_OUT_OF_MEMORY;
186 goto fail;
187 }
188 new_anchors_len = ca.anchors_len + 1;
189 new_anchors = realloc(ca.anchors,
190 new_anchors_len * sizeof(ca.anchors[0]));
191 if(!new_anchors) {
192 ca.err = CURLE_OUT_OF_MEMORY;
193 goto fail;
194 }
195 ca.anchors = new_anchors;
196 ca.anchors_len = new_anchors_len;
197 ta = &ca.anchors[ca.anchors_len - 1];
198 ta->dn.data = NULL;
199 ta->flags = 0;
200 if(br_x509_decoder_isCA(&ca.xc))
201 ta->flags |= BR_X509_TA_CA;
202 pkey = br_x509_decoder_get_pkey(&ca.xc);
203 if(!pkey) {
204 ca.err = CURLE_SSL_CACERT_BADFILE;
205 goto fail;
206 }
207 ta->pkey = *pkey;
208
209 /* calculate space needed for trust anchor data */
210 ta_size = ca.dn_len;
211 switch(pkey->key_type) {
212 case BR_KEYTYPE_RSA:
213 ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen;
214 break;
215 case BR_KEYTYPE_EC:
216 ta_size += pkey->key.ec.qlen;
217 break;
218 default:
219 ca.err = CURLE_FAILED_INIT;
220 goto fail;
221 }
222
223 /* fill in trust anchor DN and public key data */
224 ta->dn.data = malloc(ta_size);
225 if(!ta->dn.data) {
226 ca.err = CURLE_OUT_OF_MEMORY;
227 goto fail;
228 }
229 memcpy(ta->dn.data, ca.dn, ca.dn_len);
230 ta->dn.len = ca.dn_len;
231 switch(pkey->key_type) {
232 case BR_KEYTYPE_RSA:
233 ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len;
234 memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen);
235 ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen;
236 memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen);
237 break;
238 case BR_KEYTYPE_EC:
239 ta->pkey.key.ec.q = ta->dn.data + ta->dn.len;
240 memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen);
241 break;
242 }
243 break;
244 default:
245 ca.err = CURLE_SSL_CACERT_BADFILE;
246 goto fail;
247 }
248 }
249 } while(source->type != CAFILE_SOURCE_BLOB);
250 if(fp && ferror(fp))
251 ca.err = CURLE_READ_ERROR;
252 else if(ca.in_cert)
253 ca.err = CURLE_SSL_CACERT_BADFILE;
254
255 fail:
256 if(fp)
257 fclose(fp);
258 if(ca.err == CURLE_OK) {
259 *anchors = ca.anchors;
260 *anchors_len = ca.anchors_len;
261 }
262 else {
263 for(i = 0; i < ca.anchors_len; ++i)
264 free(ca.anchors[i].dn.data);
265 free(ca.anchors);
266 }
267
268 return ca.err;
269 }
270
x509_start_chain(const br_x509_class ** ctx,const char * server_name)271 static void x509_start_chain(const br_x509_class **ctx,
272 const char *server_name)
273 {
274 struct x509_context *x509 = (struct x509_context *)ctx;
275
276 if(!x509->verifypeer) {
277 x509->cert_num = 0;
278 return;
279 }
280
281 if(!x509->verifyhost)
282 server_name = NULL;
283 x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name);
284 }
285
x509_start_cert(const br_x509_class ** ctx,uint32_t length)286 static void x509_start_cert(const br_x509_class **ctx, uint32_t length)
287 {
288 struct x509_context *x509 = (struct x509_context *)ctx;
289
290 if(!x509->verifypeer) {
291 /* Only decode the first cert in the chain to obtain the public key */
292 if(x509->cert_num == 0)
293 br_x509_decoder_init(&x509->decoder, NULL, NULL);
294 return;
295 }
296
297 x509->minimal.vtable->start_cert(&x509->minimal.vtable, length);
298 }
299
x509_append(const br_x509_class ** ctx,const unsigned char * buf,size_t len)300 static void x509_append(const br_x509_class **ctx, const unsigned char *buf,
301 size_t len)
302 {
303 struct x509_context *x509 = (struct x509_context *)ctx;
304
305 if(!x509->verifypeer) {
306 if(x509->cert_num == 0)
307 br_x509_decoder_push(&x509->decoder, buf, len);
308 return;
309 }
310
311 x509->minimal.vtable->append(&x509->minimal.vtable, buf, len);
312 }
313
x509_end_cert(const br_x509_class ** ctx)314 static void x509_end_cert(const br_x509_class **ctx)
315 {
316 struct x509_context *x509 = (struct x509_context *)ctx;
317
318 if(!x509->verifypeer) {
319 x509->cert_num++;
320 return;
321 }
322
323 x509->minimal.vtable->end_cert(&x509->minimal.vtable);
324 }
325
x509_end_chain(const br_x509_class ** ctx)326 static unsigned x509_end_chain(const br_x509_class **ctx)
327 {
328 struct x509_context *x509 = (struct x509_context *)ctx;
329
330 if(!x509->verifypeer) {
331 return (unsigned)br_x509_decoder_last_error(&x509->decoder);
332 }
333
334 return x509->minimal.vtable->end_chain(&x509->minimal.vtable);
335 }
336
x509_get_pkey(const br_x509_class * const * ctx,unsigned * usages)337 static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx,
338 unsigned *usages)
339 {
340 struct x509_context *x509 = (struct x509_context *)ctx;
341
342 if(!x509->verifypeer) {
343 /* Nothing in the chain is verified, just return the public key of the
344 first certificate and allow its usage for both TLS_RSA_* and
345 TLS_ECDHE_* */
346 if(usages)
347 *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN;
348 return br_x509_decoder_get_pkey(&x509->decoder);
349 }
350
351 return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages);
352 }
353
354 static const br_x509_class x509_vtable = {
355 sizeof(struct x509_context),
356 x509_start_chain,
357 x509_start_cert,
358 x509_append,
359 x509_end_cert,
360 x509_end_chain,
361 x509_get_pkey
362 };
363
364 static CURLcode
bearssl_set_ssl_version_min_max(struct Curl_easy * data,br_ssl_engine_context * ssl_eng,struct ssl_primary_config * conn_config)365 bearssl_set_ssl_version_min_max(struct Curl_easy *data,
366 br_ssl_engine_context *ssl_eng,
367 struct ssl_primary_config *conn_config)
368 {
369 unsigned version_min, version_max;
370
371 switch(conn_config->version) {
372 case CURL_SSLVERSION_DEFAULT:
373 case CURL_SSLVERSION_TLSv1:
374 case CURL_SSLVERSION_TLSv1_0:
375 version_min = BR_TLS10;
376 break;
377 case CURL_SSLVERSION_TLSv1_1:
378 version_min = BR_TLS11;
379 break;
380 case CURL_SSLVERSION_TLSv1_2:
381 version_min = BR_TLS12;
382 break;
383 case CURL_SSLVERSION_TLSv1_3:
384 failf(data, "BearSSL: does not support TLS 1.3");
385 return CURLE_SSL_CONNECT_ERROR;
386 default:
387 failf(data, "BearSSL: unsupported minimum TLS version value");
388 return CURLE_SSL_CONNECT_ERROR;
389 }
390
391 switch(conn_config->version_max) {
392 case CURL_SSLVERSION_MAX_DEFAULT:
393 case CURL_SSLVERSION_MAX_NONE:
394 case CURL_SSLVERSION_MAX_TLSv1_3:
395 case CURL_SSLVERSION_MAX_TLSv1_2:
396 version_max = BR_TLS12;
397 break;
398 case CURL_SSLVERSION_MAX_TLSv1_1:
399 version_max = BR_TLS11;
400 break;
401 case CURL_SSLVERSION_MAX_TLSv1_0:
402 version_max = BR_TLS10;
403 break;
404 default:
405 failf(data, "BearSSL: unsupported maximum TLS version value");
406 return CURLE_SSL_CONNECT_ERROR;
407 }
408
409 br_ssl_engine_set_versions(ssl_eng, version_min, version_max);
410
411 return CURLE_OK;
412 }
413
414 static const uint16_t ciphertable[] = {
415 /* RFC 2246 TLS 1.0 */
416 BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */
417
418 /* RFC 3268 TLS 1.0 AES */
419 BR_TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */
420 BR_TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */
421
422 /* RFC 5246 TLS 1.2 */
423 BR_TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */
424 BR_TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */
425
426 /* RFC 5288 TLS 1.2 AES GCM */
427 BR_TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */
428 BR_TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */
429
430 /* RFC 4492 TLS 1.0 ECC */
431 BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */
432 BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */
433 BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */
434 BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */
435 BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */
436 BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */
437 BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */
438 BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */
439 BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */
440 BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */
441 BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */
442 BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */
443
444 /* RFC 5289 TLS 1.2 ECC HMAC SHA256/384 */
445 BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */
446 BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */
447 BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */
448 BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */
449 BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */
450 BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */
451 BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */
452 BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */
453
454 /* RFC 5289 TLS 1.2 GCM */
455 BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */
456 BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */
457 BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */
458 BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */
459 BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */
460 BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */
461 BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */
462 BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */
463
464 #ifdef BR_TLS_RSA_WITH_AES_128_CCM
465 /* RFC 6655 TLS 1.2 CCM
466 Supported since BearSSL 0.6 */
467 BR_TLS_RSA_WITH_AES_128_CCM, /* 0xC09C */
468 BR_TLS_RSA_WITH_AES_256_CCM, /* 0xC09D */
469 BR_TLS_RSA_WITH_AES_128_CCM_8, /* 0xC0A0 */
470 BR_TLS_RSA_WITH_AES_256_CCM_8, /* 0xC0A1 */
471
472 /* RFC 7251 TLS 1.2 ECC CCM
473 Supported since BearSSL 0.6 */
474 BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, /* 0xC0AC */
475 BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, /* 0xC0AD */
476 BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, /* 0xC0AE */
477 BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, /* 0xC0AF */
478 #endif
479
480 /* RFC 7905 TLS 1.2 ChaCha20-Poly1305
481 Supported since BearSSL 0.2 */
482 BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */
483 BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */
484 };
485
486 #define NUM_OF_CIPHERS (sizeof(ciphertable) / sizeof(ciphertable[0]))
487
bearssl_set_selected_ciphers(struct Curl_easy * data,br_ssl_engine_context * ssl_eng,const char * ciphers)488 static CURLcode bearssl_set_selected_ciphers(struct Curl_easy *data,
489 br_ssl_engine_context *ssl_eng,
490 const char *ciphers)
491 {
492 uint16_t selected[NUM_OF_CIPHERS];
493 size_t count = 0, i;
494 const char *ptr, *end;
495
496 for(ptr = ciphers; ptr[0] != '\0' && count < NUM_OF_CIPHERS; ptr = end) {
497 uint16_t id = Curl_cipher_suite_walk_str(&ptr, &end);
498
499 /* Check if cipher is supported */
500 if(id) {
501 for(i = 0; i < NUM_OF_CIPHERS && ciphertable[i] != id; i++);
502 if(i == NUM_OF_CIPHERS)
503 id = 0;
504 }
505 if(!id) {
506 if(ptr[0] != '\0')
507 infof(data, "BearSSL: unknown cipher in list: \"%.*s\"",
508 (int) (end - ptr), ptr);
509 continue;
510 }
511
512 /* No duplicates allowed */
513 for(i = 0; i < count && selected[i] != id; i++);
514 if(i < count) {
515 infof(data, "BearSSL: duplicate cipher in list: \"%.*s\"",
516 (int) (end - ptr), ptr);
517 continue;
518 }
519
520 selected[count++] = id;
521 }
522
523 if(count == 0) {
524 failf(data, "BearSSL: no supported cipher in list");
525 return CURLE_SSL_CIPHER;
526 }
527
528 br_ssl_engine_set_suites(ssl_eng, selected, count);
529 return CURLE_OK;
530 }
531
bearssl_connect_step1(struct Curl_cfilter * cf,struct Curl_easy * data)532 static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
533 struct Curl_easy *data)
534 {
535 struct ssl_connect_data *connssl = cf->ctx;
536 struct bearssl_ssl_backend_data *backend =
537 (struct bearssl_ssl_backend_data *)connssl->backend;
538 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
539 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
540 const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
541 const char * const ssl_cafile =
542 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
543 (ca_info_blob ? NULL : conn_config->CAfile);
544 const char *hostname = connssl->peer.hostname;
545 const bool verifypeer = conn_config->verifypeer;
546 const bool verifyhost = conn_config->verifyhost;
547 CURLcode ret;
548 int session_set = 0;
549
550 DEBUGASSERT(backend);
551 CURL_TRC_CF(data, cf, "connect_step1");
552
553 if(verifypeer) {
554 if(ca_info_blob) {
555 struct cafile_source source;
556 source.type = CAFILE_SOURCE_BLOB;
557 source.data = ca_info_blob->data;
558 source.len = ca_info_blob->len;
559
560 CURL_TRC_CF(data, cf, "connect_step1, load ca_info_blob");
561 ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
562 if(ret != CURLE_OK) {
563 failf(data, "error importing CA certificate blob");
564 return ret;
565 }
566 }
567
568 if(ssl_cafile) {
569 struct cafile_source source;
570 source.type = CAFILE_SOURCE_PATH;
571 source.data = ssl_cafile;
572 source.len = 0;
573
574 CURL_TRC_CF(data, cf, "connect_step1, load cafile");
575 ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
576 if(ret != CURLE_OK) {
577 failf(data, "error setting certificate verify locations."
578 " CAfile: %s", ssl_cafile);
579 return ret;
580 }
581 }
582 }
583
584 /* initialize SSL context */
585 br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal,
586 backend->anchors, backend->anchors_len);
587
588 ret = bearssl_set_ssl_version_min_max(data, &backend->ctx.eng, conn_config);
589 if(ret != CURLE_OK)
590 return ret;
591
592 br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf,
593 sizeof(backend->buf), 1);
594
595 if(conn_config->cipher_list) {
596 /* Override the ciphers as specified. For the default cipher list see the
597 BearSSL source code of br_ssl_client_init_full() */
598 CURL_TRC_CF(data, cf, "connect_step1, set ciphers");
599 ret = bearssl_set_selected_ciphers(data, &backend->ctx.eng,
600 conn_config->cipher_list);
601 if(ret)
602 return ret;
603 }
604
605 /* initialize X.509 context */
606 backend->x509.vtable = &x509_vtable;
607 backend->x509.verifypeer = verifypeer;
608 backend->x509.verifyhost = verifyhost;
609 br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable);
610
611 if(ssl_config->primary.cache_session) {
612 void *sdata;
613 size_t slen;
614 const br_ssl_session_parameters *session;
615
616 CURL_TRC_CF(data, cf, "connect_step1, check session cache");
617 Curl_ssl_sessionid_lock(data);
618 if(!Curl_ssl_getsessionid(cf, data, &connssl->peer, &sdata, &slen, NULL) &&
619 slen == sizeof(*session)) {
620 session = sdata;
621 br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
622 session_set = 1;
623 infof(data, "BearSSL: reusing session ID");
624 }
625 Curl_ssl_sessionid_unlock(data);
626 }
627
628 if(connssl->alpn) {
629 struct alpn_proto_buf proto;
630 size_t i;
631
632 for(i = 0; i < connssl->alpn->count; ++i) {
633 backend->protocols[i] = connssl->alpn->entries[i];
634 }
635 br_ssl_engine_set_protocol_names(&backend->ctx.eng, backend->protocols,
636 connssl->alpn->count);
637 Curl_alpn_to_proto_str(&proto, connssl->alpn);
638 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
639 }
640
641 if(connssl->peer.type != CURL_SSL_PEER_DNS) {
642 if(verifyhost) {
643 failf(data, "BearSSL: "
644 "host verification of IP address is not supported");
645 return CURLE_PEER_FAILED_VERIFICATION;
646 }
647 hostname = NULL;
648 }
649 else {
650 if(!connssl->peer.sni) {
651 failf(data, "Failed to set SNI");
652 return CURLE_SSL_CONNECT_ERROR;
653 }
654 hostname = connssl->peer.sni;
655 CURL_TRC_CF(data, cf, "connect_step1, SNI set");
656 }
657
658 /* give application a chance to interfere with SSL set up. */
659 if(data->set.ssl.fsslctx) {
660 Curl_set_in_callback(data, TRUE);
661 ret = (*data->set.ssl.fsslctx)(data, &backend->ctx,
662 data->set.ssl.fsslctxp);
663 Curl_set_in_callback(data, FALSE);
664 if(ret) {
665 failf(data, "BearSSL: error signaled by ssl ctx callback");
666 return ret;
667 }
668 }
669
670 if(!br_ssl_client_reset(&backend->ctx, hostname, session_set))
671 return CURLE_FAILED_INIT;
672 backend->active = TRUE;
673
674 connssl->connecting_state = ssl_connect_2;
675
676 return CURLE_OK;
677 }
678
bearssl_run_until(struct Curl_cfilter * cf,struct Curl_easy * data,unsigned target)679 static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
680 struct Curl_easy *data,
681 unsigned target)
682 {
683 struct ssl_connect_data *connssl = cf->ctx;
684 struct bearssl_ssl_backend_data *backend =
685 (struct bearssl_ssl_backend_data *)connssl->backend;
686 unsigned state;
687 unsigned char *buf;
688 size_t len;
689 ssize_t ret;
690 CURLcode result;
691 int err;
692
693 DEBUGASSERT(backend);
694
695 connssl->io_need = CURL_SSL_IO_NEED_NONE;
696 for(;;) {
697 state = br_ssl_engine_current_state(&backend->ctx.eng);
698 if(state & BR_SSL_CLOSED) {
699 err = br_ssl_engine_last_error(&backend->ctx.eng);
700 switch(err) {
701 case BR_ERR_OK:
702 /* TLS close notify */
703 if(connssl->state != ssl_connection_complete) {
704 failf(data, "SSL: connection closed during handshake");
705 return CURLE_SSL_CONNECT_ERROR;
706 }
707 return CURLE_OK;
708 case BR_ERR_X509_EXPIRED:
709 failf(data, "SSL: X.509 verification: "
710 "certificate is expired or not yet valid");
711 return CURLE_PEER_FAILED_VERIFICATION;
712 case BR_ERR_X509_BAD_SERVER_NAME:
713 failf(data, "SSL: X.509 verification: "
714 "expected server name was not found in the chain");
715 return CURLE_PEER_FAILED_VERIFICATION;
716 case BR_ERR_X509_NOT_TRUSTED:
717 failf(data, "SSL: X.509 verification: "
718 "chain could not be linked to a trust anchor");
719 return CURLE_PEER_FAILED_VERIFICATION;
720 default:;
721 }
722 failf(data, "BearSSL: connection error 0x%04x", err);
723 /* X.509 errors are documented to have the range 32..63 */
724 if(err >= 32 && err < 64)
725 return CURLE_PEER_FAILED_VERIFICATION;
726 return CURLE_SSL_CONNECT_ERROR;
727 }
728 if(state & target)
729 return CURLE_OK;
730 if(state & BR_SSL_SENDREC) {
731 buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
732 ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, FALSE,
733 &result);
734 CURL_TRC_CF(data, cf, "ssl_send(len=%zu) -> %zd, %d", len, ret, result);
735 if(ret <= 0) {
736 if(result == CURLE_AGAIN)
737 connssl->io_need |= CURL_SSL_IO_NEED_SEND;
738 return result;
739 }
740 br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
741 }
742 else if(state & BR_SSL_RECVREC) {
743 buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
744 ret = Curl_conn_cf_recv(cf->next, data, (char *)buf, len, &result);
745 CURL_TRC_CF(data, cf, "ssl_recv(len=%zu) -> %zd, %d", len, ret, result);
746 if(ret == 0) {
747 failf(data, "SSL: EOF without close notify");
748 return CURLE_RECV_ERROR;
749 }
750 if(ret <= 0) {
751 if(result == CURLE_AGAIN)
752 connssl->io_need |= CURL_SSL_IO_NEED_RECV;
753 return result;
754 }
755 br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
756 }
757 }
758 }
759
bearssl_connect_step2(struct Curl_cfilter * cf,struct Curl_easy * data)760 static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
761 struct Curl_easy *data)
762 {
763 struct ssl_connect_data *connssl = cf->ctx;
764 struct bearssl_ssl_backend_data *backend =
765 (struct bearssl_ssl_backend_data *)connssl->backend;
766 br_ssl_session_parameters session;
767 char cipher_str[64];
768 CURLcode ret;
769
770 DEBUGASSERT(backend);
771 CURL_TRC_CF(data, cf, "connect_step2");
772
773 ret = bearssl_run_until(cf, data, BR_SSL_SENDAPP | BR_SSL_RECVAPP);
774 if(ret == CURLE_AGAIN)
775 return CURLE_OK;
776 if(ret == CURLE_OK) {
777 unsigned int tver;
778 int subver = 0;
779
780 if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) {
781 failf(data, "SSL: connection closed during handshake");
782 return CURLE_SSL_CONNECT_ERROR;
783 }
784 connssl->connecting_state = ssl_connect_3;
785 /* Informational message */
786 tver = br_ssl_engine_get_version(&backend->ctx.eng);
787 switch(tver) {
788 case BR_TLS12:
789 subver = 2; /* 1.2 */
790 break;
791 case BR_TLS11:
792 subver = 1; /* 1.1 */
793 break;
794 case BR_TLS10: /* 1.0 */
795 default: /* unknown, leave it at zero */
796 break;
797 }
798 br_ssl_engine_get_session_parameters(&backend->ctx.eng, &session);
799 Curl_cipher_suite_get_str(session.cipher_suite, cipher_str,
800 sizeof(cipher_str), TRUE);
801 infof(data, "BearSSL: TLS v1.%d connection using %s", subver,
802 cipher_str);
803 }
804 return ret;
805 }
806
bearssl_session_free(void * sessionid,size_t idsize)807 static void bearssl_session_free(void *sessionid, size_t idsize)
808 {
809 (void)idsize;
810 free(sessionid);
811 }
812
bearssl_connect_step3(struct Curl_cfilter * cf,struct Curl_easy * data)813 static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
814 struct Curl_easy *data)
815 {
816 struct ssl_connect_data *connssl = cf->ctx;
817 struct bearssl_ssl_backend_data *backend =
818 (struct bearssl_ssl_backend_data *)connssl->backend;
819 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
820 CURLcode ret;
821
822 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
823 DEBUGASSERT(backend);
824 CURL_TRC_CF(data, cf, "connect_step3");
825
826 if(connssl->alpn) {
827 const char *proto;
828
829 proto = br_ssl_engine_get_selected_protocol(&backend->ctx.eng);
830 Curl_alpn_set_negotiated(cf, data, connssl, (const unsigned char *)proto,
831 proto ? strlen(proto) : 0);
832 }
833
834 if(ssl_config->primary.cache_session) {
835 br_ssl_session_parameters *session;
836
837 session = malloc(sizeof(*session));
838 if(!session)
839 return CURLE_OUT_OF_MEMORY;
840 br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
841 Curl_ssl_sessionid_lock(data);
842 ret = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
843 session, sizeof(*session),
844 bearssl_session_free);
845 Curl_ssl_sessionid_unlock(data);
846 if(ret)
847 return ret;
848 }
849
850 connssl->connecting_state = ssl_connect_done;
851
852 return CURLE_OK;
853 }
854
bearssl_send(struct Curl_cfilter * cf,struct Curl_easy * data,const void * buf,size_t len,CURLcode * err)855 static ssize_t bearssl_send(struct Curl_cfilter *cf, struct Curl_easy *data,
856 const void *buf, size_t len, CURLcode *err)
857 {
858 struct ssl_connect_data *connssl = cf->ctx;
859 struct bearssl_ssl_backend_data *backend =
860 (struct bearssl_ssl_backend_data *)connssl->backend;
861 unsigned char *app;
862 size_t applen;
863
864 DEBUGASSERT(backend);
865
866 for(;;) {
867 *err = bearssl_run_until(cf, data, BR_SSL_SENDAPP);
868 if(*err)
869 return -1;
870 app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen);
871 if(!app) {
872 failf(data, "SSL: connection closed during write");
873 *err = CURLE_SEND_ERROR;
874 return -1;
875 }
876 if(backend->pending_write) {
877 applen = backend->pending_write;
878 backend->pending_write = 0;
879 return applen;
880 }
881 if(applen > len)
882 applen = len;
883 memcpy(app, buf, applen);
884 br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen);
885 br_ssl_engine_flush(&backend->ctx.eng, 0);
886 backend->pending_write = applen;
887 }
888 }
889
bearssl_recv(struct Curl_cfilter * cf,struct Curl_easy * data,char * buf,size_t len,CURLcode * err)890 static ssize_t bearssl_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
891 char *buf, size_t len, CURLcode *err)
892 {
893 struct ssl_connect_data *connssl = cf->ctx;
894 struct bearssl_ssl_backend_data *backend =
895 (struct bearssl_ssl_backend_data *)connssl->backend;
896 unsigned char *app;
897 size_t applen;
898
899 DEBUGASSERT(backend);
900
901 *err = bearssl_run_until(cf, data, BR_SSL_RECVAPP);
902 if(*err != CURLE_OK)
903 return -1;
904 app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen);
905 if(!app)
906 return 0;
907 if(applen > len)
908 applen = len;
909 memcpy(buf, app, applen);
910 br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen);
911
912 return applen;
913 }
914
bearssl_connect_common(struct Curl_cfilter * cf,struct Curl_easy * data,bool nonblocking,bool * done)915 static CURLcode bearssl_connect_common(struct Curl_cfilter *cf,
916 struct Curl_easy *data,
917 bool nonblocking,
918 bool *done)
919 {
920 CURLcode ret;
921 struct ssl_connect_data *connssl = cf->ctx;
922 curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
923 timediff_t timeout_ms;
924 int what;
925
926 CURL_TRC_CF(data, cf, "connect_common(blocking=%d)", !nonblocking);
927 /* check if the connection has already been established */
928 if(ssl_connection_complete == connssl->state) {
929 CURL_TRC_CF(data, cf, "connect_common, connected");
930 *done = TRUE;
931 return CURLE_OK;
932 }
933
934 if(ssl_connect_1 == connssl->connecting_state) {
935 ret = bearssl_connect_step1(cf, data);
936 if(ret)
937 return ret;
938 }
939
940 while(ssl_connect_2 == connssl->connecting_state) {
941 /* check allowed time left */
942 timeout_ms = Curl_timeleft(data, NULL, TRUE);
943
944 if(timeout_ms < 0) {
945 /* no need to continue if time already is up */
946 failf(data, "SSL connection timeout");
947 return CURLE_OPERATION_TIMEDOUT;
948 }
949
950 /* if ssl is expecting something, check if it is available. */
951 if(connssl->io_need) {
952 curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
953 sockfd : CURL_SOCKET_BAD;
954 curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
955 sockfd : CURL_SOCKET_BAD;
956
957 CURL_TRC_CF(data, cf, "connect_common, check socket");
958 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
959 nonblocking ? 0 : timeout_ms);
960 CURL_TRC_CF(data, cf, "connect_common, check socket -> %d", what);
961 if(what < 0) {
962 /* fatal error */
963 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
964 return CURLE_SSL_CONNECT_ERROR;
965 }
966 else if(0 == what) {
967 if(nonblocking) {
968 *done = FALSE;
969 return CURLE_OK;
970 }
971 else {
972 /* timeout */
973 failf(data, "SSL connection timeout");
974 return CURLE_OPERATION_TIMEDOUT;
975 }
976 }
977 /* socket is readable or writable */
978 }
979
980 /* Run transaction, and return to the caller if it failed or if this
981 * connection is done nonblocking and this loop would execute again. This
982 * permits the owner of a multi handle to abort a connection attempt
983 * before step2 has completed while ensuring that a client using select()
984 * or epoll() will always have a valid fdset to wait on.
985 */
986 connssl->io_need = CURL_SSL_IO_NEED_NONE;
987 ret = bearssl_connect_step2(cf, data);
988 if(ret || (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
989 return ret;
990 }
991
992 if(ssl_connect_3 == connssl->connecting_state) {
993 ret = bearssl_connect_step3(cf, data);
994 if(ret)
995 return ret;
996 }
997
998 if(ssl_connect_done == connssl->connecting_state) {
999 connssl->state = ssl_connection_complete;
1000 *done = TRUE;
1001 }
1002 else
1003 *done = FALSE;
1004
1005 /* Reset our connect state machine */
1006 connssl->connecting_state = ssl_connect_1;
1007
1008 return CURLE_OK;
1009 }
1010
bearssl_version(char * buffer,size_t size)1011 static size_t bearssl_version(char *buffer, size_t size)
1012 {
1013 return msnprintf(buffer, size, "BearSSL");
1014 }
1015
bearssl_data_pending(struct Curl_cfilter * cf,const struct Curl_easy * data)1016 static bool bearssl_data_pending(struct Curl_cfilter *cf,
1017 const struct Curl_easy *data)
1018 {
1019 struct ssl_connect_data *ctx = cf->ctx;
1020 struct bearssl_ssl_backend_data *backend;
1021
1022 (void)data;
1023 DEBUGASSERT(ctx && ctx->backend);
1024 backend = (struct bearssl_ssl_backend_data *)ctx->backend;
1025 return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
1026 }
1027
bearssl_random(struct Curl_easy * data UNUSED_PARAM,unsigned char * entropy,size_t length)1028 static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
1029 unsigned char *entropy, size_t length)
1030 {
1031 static br_hmac_drbg_context ctx;
1032 static bool seeded = FALSE;
1033
1034 if(!seeded) {
1035 br_prng_seeder seeder;
1036
1037 br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0);
1038 seeder = br_prng_seeder_system(NULL);
1039 if(!seeder || !seeder(&ctx.vtable))
1040 return CURLE_FAILED_INIT;
1041 seeded = TRUE;
1042 }
1043 br_hmac_drbg_generate(&ctx, entropy, length);
1044
1045 return CURLE_OK;
1046 }
1047
bearssl_connect(struct Curl_cfilter * cf,struct Curl_easy * data)1048 static CURLcode bearssl_connect(struct Curl_cfilter *cf,
1049 struct Curl_easy *data)
1050 {
1051 CURLcode ret;
1052 bool done = FALSE;
1053
1054 ret = bearssl_connect_common(cf, data, FALSE, &done);
1055 if(ret)
1056 return ret;
1057
1058 DEBUGASSERT(done);
1059
1060 return CURLE_OK;
1061 }
1062
bearssl_connect_nonblocking(struct Curl_cfilter * cf,struct Curl_easy * data,bool * done)1063 static CURLcode bearssl_connect_nonblocking(struct Curl_cfilter *cf,
1064 struct Curl_easy *data,
1065 bool *done)
1066 {
1067 return bearssl_connect_common(cf, data, TRUE, done);
1068 }
1069
bearssl_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)1070 static void *bearssl_get_internals(struct ssl_connect_data *connssl,
1071 CURLINFO info UNUSED_PARAM)
1072 {
1073 struct bearssl_ssl_backend_data *backend =
1074 (struct bearssl_ssl_backend_data *)connssl->backend;
1075 DEBUGASSERT(backend);
1076 return &backend->ctx;
1077 }
1078
bearssl_shutdown(struct Curl_cfilter * cf,struct Curl_easy * data,bool send_shutdown,bool * done)1079 static CURLcode bearssl_shutdown(struct Curl_cfilter *cf,
1080 struct Curl_easy *data,
1081 bool send_shutdown, bool *done)
1082 {
1083 struct ssl_connect_data *connssl = cf->ctx;
1084 struct bearssl_ssl_backend_data *backend =
1085 (struct bearssl_ssl_backend_data *)connssl->backend;
1086 CURLcode result;
1087
1088 DEBUGASSERT(backend);
1089 if(!backend->active || cf->shutdown) {
1090 *done = TRUE;
1091 return CURLE_OK;
1092 }
1093
1094 *done = FALSE;
1095 if(!backend->sent_shutdown) {
1096 (void)send_shutdown; /* unknown how to suppress our close notify */
1097 br_ssl_engine_close(&backend->ctx.eng);
1098 backend->sent_shutdown = TRUE;
1099 }
1100
1101 result = bearssl_run_until(cf, data, BR_SSL_CLOSED);
1102 if(result == CURLE_OK) {
1103 *done = TRUE;
1104 }
1105 else if(result == CURLE_AGAIN) {
1106 CURL_TRC_CF(data, cf, "shutdown EAGAIN, io_need=%x", connssl->io_need);
1107 result = CURLE_OK;
1108 }
1109 else
1110 CURL_TRC_CF(data, cf, "shutdown error: %d", result);
1111
1112 cf->shutdown = (result || *done);
1113 return result;
1114 }
1115
bearssl_close(struct Curl_cfilter * cf,struct Curl_easy * data)1116 static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
1117 {
1118 struct ssl_connect_data *connssl = cf->ctx;
1119 struct bearssl_ssl_backend_data *backend =
1120 (struct bearssl_ssl_backend_data *)connssl->backend;
1121 size_t i;
1122
1123 (void)data;
1124 DEBUGASSERT(backend);
1125
1126 backend->active = FALSE;
1127 if(backend->anchors) {
1128 for(i = 0; i < backend->anchors_len; ++i)
1129 free(backend->anchors[i].dn.data);
1130 Curl_safefree(backend->anchors);
1131 }
1132 }
1133
bearssl_sha256sum(const unsigned char * input,size_t inputlen,unsigned char * sha256sum,size_t sha256len UNUSED_PARAM)1134 static CURLcode bearssl_sha256sum(const unsigned char *input,
1135 size_t inputlen,
1136 unsigned char *sha256sum,
1137 size_t sha256len UNUSED_PARAM)
1138 {
1139 br_sha256_context ctx;
1140
1141 br_sha256_init(&ctx);
1142 br_sha256_update(&ctx, input, inputlen);
1143 br_sha256_out(&ctx, sha256sum);
1144 return CURLE_OK;
1145 }
1146
1147 const struct Curl_ssl Curl_ssl_bearssl = {
1148 { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
1149
1150 SSLSUPP_CAINFO_BLOB |
1151 SSLSUPP_SSL_CTX |
1152 SSLSUPP_HTTPS_PROXY |
1153 SSLSUPP_CIPHER_LIST,
1154
1155 sizeof(struct bearssl_ssl_backend_data),
1156
1157 Curl_none_init, /* init */
1158 Curl_none_cleanup, /* cleanup */
1159 bearssl_version, /* version */
1160 Curl_none_check_cxn, /* check_cxn */
1161 bearssl_shutdown, /* shutdown */
1162 bearssl_data_pending, /* data_pending */
1163 bearssl_random, /* random */
1164 Curl_none_cert_status_request, /* cert_status_request */
1165 bearssl_connect, /* connect */
1166 bearssl_connect_nonblocking, /* connect_nonblocking */
1167 Curl_ssl_adjust_pollset, /* adjust_pollset */
1168 bearssl_get_internals, /* get_internals */
1169 bearssl_close, /* close_one */
1170 Curl_none_close_all, /* close_all */
1171 Curl_none_set_engine, /* set_engine */
1172 Curl_none_set_engine_default, /* set_engine_default */
1173 Curl_none_engines_list, /* engines_list */
1174 Curl_none_false_start, /* false_start */
1175 bearssl_sha256sum, /* sha256sum */
1176 NULL, /* associate_connection */
1177 NULL, /* disassociate_connection */
1178 bearssl_recv, /* recv decrypted data */
1179 bearssl_send, /* send data to encrypt */
1180 NULL, /* get_channel_binding */
1181 };
1182
1183 #endif /* USE_BEARSSL */
1184