xref: /curl/lib/vtls/bearssl.c (revision fbf5d507)
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 *session;
613 
614     CURL_TRC_CF(data, cf, "connect_step1, check session cache");
615     Curl_ssl_sessionid_lock(data);
616     if(!Curl_ssl_getsessionid(cf, data, &connssl->peer, &session, NULL)) {
617       br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
618       session_set = 1;
619       infof(data, "BearSSL: reusing session ID");
620     }
621     Curl_ssl_sessionid_unlock(data);
622   }
623 
624   if(connssl->alpn) {
625     struct alpn_proto_buf proto;
626     size_t i;
627 
628     for(i = 0; i < connssl->alpn->count; ++i) {
629       backend->protocols[i] = connssl->alpn->entries[i];
630     }
631     br_ssl_engine_set_protocol_names(&backend->ctx.eng, backend->protocols,
632                                      connssl->alpn->count);
633     Curl_alpn_to_proto_str(&proto, connssl->alpn);
634     infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
635   }
636 
637   if(connssl->peer.type != CURL_SSL_PEER_DNS) {
638     if(verifyhost) {
639       failf(data, "BearSSL: "
640             "host verification of IP address is not supported");
641       return CURLE_PEER_FAILED_VERIFICATION;
642     }
643     hostname = NULL;
644   }
645   else {
646     if(!connssl->peer.sni) {
647       failf(data, "Failed to set SNI");
648       return CURLE_SSL_CONNECT_ERROR;
649     }
650     hostname = connssl->peer.sni;
651     CURL_TRC_CF(data, cf, "connect_step1, SNI set");
652   }
653 
654   /* give application a chance to interfere with SSL set up. */
655   if(data->set.ssl.fsslctx) {
656     Curl_set_in_callback(data, true);
657     ret = (*data->set.ssl.fsslctx)(data, &backend->ctx,
658                                    data->set.ssl.fsslctxp);
659     Curl_set_in_callback(data, false);
660     if(ret) {
661       failf(data, "BearSSL: error signaled by ssl ctx callback");
662       return ret;
663     }
664   }
665 
666   if(!br_ssl_client_reset(&backend->ctx, hostname, session_set))
667     return CURLE_FAILED_INIT;
668   backend->active = TRUE;
669 
670   connssl->connecting_state = ssl_connect_2;
671 
672   return CURLE_OK;
673 }
674 
bearssl_run_until(struct Curl_cfilter * cf,struct Curl_easy * data,unsigned target)675 static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
676                                   struct Curl_easy *data,
677                                   unsigned target)
678 {
679   struct ssl_connect_data *connssl = cf->ctx;
680   struct bearssl_ssl_backend_data *backend =
681     (struct bearssl_ssl_backend_data *)connssl->backend;
682   unsigned state;
683   unsigned char *buf;
684   size_t len;
685   ssize_t ret;
686   CURLcode result;
687   int err;
688 
689   DEBUGASSERT(backend);
690 
691   connssl->io_need = CURL_SSL_IO_NEED_NONE;
692   for(;;) {
693     state = br_ssl_engine_current_state(&backend->ctx.eng);
694     if(state & BR_SSL_CLOSED) {
695       err = br_ssl_engine_last_error(&backend->ctx.eng);
696       switch(err) {
697       case BR_ERR_OK:
698         /* TLS close notify */
699         if(connssl->state != ssl_connection_complete) {
700           failf(data, "SSL: connection closed during handshake");
701           return CURLE_SSL_CONNECT_ERROR;
702         }
703         return CURLE_OK;
704       case BR_ERR_X509_EXPIRED:
705         failf(data, "SSL: X.509 verification: "
706               "certificate is expired or not yet valid");
707         return CURLE_PEER_FAILED_VERIFICATION;
708       case BR_ERR_X509_BAD_SERVER_NAME:
709         failf(data, "SSL: X.509 verification: "
710               "expected server name was not found in the chain");
711         return CURLE_PEER_FAILED_VERIFICATION;
712       case BR_ERR_X509_NOT_TRUSTED:
713         failf(data, "SSL: X.509 verification: "
714               "chain could not be linked to a trust anchor");
715         return CURLE_PEER_FAILED_VERIFICATION;
716       default:;
717       }
718       failf(data, "BearSSL: connection error 0x%04x", err);
719       /* X.509 errors are documented to have the range 32..63 */
720       if(err >= 32 && err < 64)
721         return CURLE_PEER_FAILED_VERIFICATION;
722       return CURLE_SSL_CONNECT_ERROR;
723     }
724     if(state & target)
725       return CURLE_OK;
726     if(state & BR_SSL_SENDREC) {
727       buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
728       ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, FALSE,
729                               &result);
730       CURL_TRC_CF(data, cf, "ssl_send(len=%zu) -> %zd, %d", len, ret, result);
731       if(ret <= 0) {
732         if(result == CURLE_AGAIN)
733           connssl->io_need |= CURL_SSL_IO_NEED_SEND;
734         return result;
735       }
736       br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
737     }
738     else if(state & BR_SSL_RECVREC) {
739       buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
740       ret = Curl_conn_cf_recv(cf->next, data, (char *)buf, len, &result);
741       CURL_TRC_CF(data, cf, "ssl_recv(len=%zu) -> %zd, %d", len, ret, result);
742       if(ret == 0) {
743         failf(data, "SSL: EOF without close notify");
744         return CURLE_RECV_ERROR;
745       }
746       if(ret <= 0) {
747         if(result == CURLE_AGAIN)
748           connssl->io_need |= CURL_SSL_IO_NEED_RECV;
749         return result;
750       }
751       br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
752     }
753   }
754 }
755 
bearssl_connect_step2(struct Curl_cfilter * cf,struct Curl_easy * data)756 static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
757                                       struct Curl_easy *data)
758 {
759   struct ssl_connect_data *connssl = cf->ctx;
760   struct bearssl_ssl_backend_data *backend =
761     (struct bearssl_ssl_backend_data *)connssl->backend;
762   br_ssl_session_parameters session;
763   char cipher_str[64];
764   char ver_str[16];
765   CURLcode ret;
766 
767   DEBUGASSERT(backend);
768   CURL_TRC_CF(data, cf, "connect_step2");
769 
770   ret = bearssl_run_until(cf, data, BR_SSL_SENDAPP | BR_SSL_RECVAPP);
771   if(ret == CURLE_AGAIN)
772     return CURLE_OK;
773   if(ret == CURLE_OK) {
774     unsigned int tver;
775 
776     if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) {
777       failf(data, "SSL: connection closed during handshake");
778       return CURLE_SSL_CONNECT_ERROR;
779     }
780     connssl->connecting_state = ssl_connect_3;
781     /* Informational message */
782     tver = br_ssl_engine_get_version(&backend->ctx.eng);
783     if(tver == BR_TLS12)
784       strcpy(ver_str, "TLSv1.2");
785     else if(tver == BR_TLS11)
786       strcpy(ver_str, "TLSv1.1");
787     else if(tver == BR_TLS10)
788       strcpy(ver_str, "TLSv1.0");
789     else {
790       msnprintf(ver_str, sizeof(ver_str), "TLS 0x%04x", tver);
791     }
792     br_ssl_engine_get_session_parameters(&backend->ctx.eng, &session);
793     Curl_cipher_suite_get_str(session.cipher_suite, cipher_str,
794                               sizeof(cipher_str), true);
795     infof(data, "BearSSL: %s connection using %s", ver_str, cipher_str);
796   }
797   return ret;
798 }
799 
bearssl_session_free(void * sessionid,size_t idsize)800 static void bearssl_session_free(void *sessionid, size_t idsize)
801 {
802   (void)idsize;
803   free(sessionid);
804 }
805 
bearssl_connect_step3(struct Curl_cfilter * cf,struct Curl_easy * data)806 static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
807                                       struct Curl_easy *data)
808 {
809   struct ssl_connect_data *connssl = cf->ctx;
810   struct bearssl_ssl_backend_data *backend =
811     (struct bearssl_ssl_backend_data *)connssl->backend;
812   struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
813   CURLcode ret;
814 
815   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
816   DEBUGASSERT(backend);
817   CURL_TRC_CF(data, cf, "connect_step3");
818 
819   if(connssl->alpn) {
820     const char *proto;
821 
822     proto = br_ssl_engine_get_selected_protocol(&backend->ctx.eng);
823     Curl_alpn_set_negotiated(cf, data, (const unsigned char *)proto,
824                              proto ? strlen(proto) : 0);
825   }
826 
827   if(ssl_config->primary.cache_session) {
828     br_ssl_session_parameters *session;
829 
830     session = malloc(sizeof(*session));
831     if(!session)
832       return CURLE_OUT_OF_MEMORY;
833     br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
834     Curl_ssl_sessionid_lock(data);
835     ret = Curl_ssl_set_sessionid(cf, data, &connssl->peer, session, 0,
836                                  bearssl_session_free);
837     Curl_ssl_sessionid_unlock(data);
838     if(ret)
839       return ret;
840   }
841 
842   connssl->connecting_state = ssl_connect_done;
843 
844   return CURLE_OK;
845 }
846 
bearssl_send(struct Curl_cfilter * cf,struct Curl_easy * data,const void * buf,size_t len,CURLcode * err)847 static ssize_t bearssl_send(struct Curl_cfilter *cf, struct Curl_easy *data,
848                             const void *buf, size_t len, CURLcode *err)
849 {
850   struct ssl_connect_data *connssl = cf->ctx;
851   struct bearssl_ssl_backend_data *backend =
852     (struct bearssl_ssl_backend_data *)connssl->backend;
853   unsigned char *app;
854   size_t applen;
855 
856   DEBUGASSERT(backend);
857 
858   for(;;) {
859     *err = bearssl_run_until(cf, data, BR_SSL_SENDAPP);
860     if(*err)
861       return -1;
862     app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen);
863     if(!app) {
864       failf(data, "SSL: connection closed during write");
865       *err = CURLE_SEND_ERROR;
866       return -1;
867     }
868     if(backend->pending_write) {
869       applen = backend->pending_write;
870       backend->pending_write = 0;
871       return applen;
872     }
873     if(applen > len)
874       applen = len;
875     memcpy(app, buf, applen);
876     br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen);
877     br_ssl_engine_flush(&backend->ctx.eng, 0);
878     backend->pending_write = applen;
879   }
880 }
881 
bearssl_recv(struct Curl_cfilter * cf,struct Curl_easy * data,char * buf,size_t len,CURLcode * err)882 static ssize_t bearssl_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
883                             char *buf, size_t len, CURLcode *err)
884 {
885   struct ssl_connect_data *connssl = cf->ctx;
886   struct bearssl_ssl_backend_data *backend =
887     (struct bearssl_ssl_backend_data *)connssl->backend;
888   unsigned char *app;
889   size_t applen;
890 
891   DEBUGASSERT(backend);
892 
893   *err = bearssl_run_until(cf, data, BR_SSL_RECVAPP);
894   if(*err != CURLE_OK)
895     return -1;
896   app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen);
897   if(!app)
898     return 0;
899   if(applen > len)
900     applen = len;
901   memcpy(buf, app, applen);
902   br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen);
903 
904   return applen;
905 }
906 
bearssl_connect_common(struct Curl_cfilter * cf,struct Curl_easy * data,bool nonblocking,bool * done)907 static CURLcode bearssl_connect_common(struct Curl_cfilter *cf,
908                                        struct Curl_easy *data,
909                                        bool nonblocking,
910                                        bool *done)
911 {
912   CURLcode ret;
913   struct ssl_connect_data *connssl = cf->ctx;
914   curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
915   timediff_t timeout_ms;
916   int what;
917 
918   CURL_TRC_CF(data, cf, "connect_common(blocking=%d)", !nonblocking);
919   /* check if the connection has already been established */
920   if(ssl_connection_complete == connssl->state) {
921     CURL_TRC_CF(data, cf, "connect_common, connected");
922     *done = TRUE;
923     return CURLE_OK;
924   }
925 
926   if(ssl_connect_1 == connssl->connecting_state) {
927     ret = bearssl_connect_step1(cf, data);
928     if(ret)
929       return ret;
930   }
931 
932   while(ssl_connect_2 == connssl->connecting_state) {
933     /* check allowed time left */
934     timeout_ms = Curl_timeleft(data, NULL, TRUE);
935 
936     if(timeout_ms < 0) {
937       /* no need to continue if time already is up */
938       failf(data, "SSL connection timeout");
939       return CURLE_OPERATION_TIMEDOUT;
940     }
941 
942     /* if ssl is expecting something, check if it is available. */
943     if(connssl->io_need) {
944       curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
945         sockfd : CURL_SOCKET_BAD;
946       curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
947         sockfd : CURL_SOCKET_BAD;
948 
949       CURL_TRC_CF(data, cf, "connect_common, check socket");
950       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
951                                nonblocking ? 0 : timeout_ms);
952       CURL_TRC_CF(data, cf, "connect_common, check socket -> %d", what);
953       if(what < 0) {
954         /* fatal error */
955         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
956         return CURLE_SSL_CONNECT_ERROR;
957       }
958       else if(0 == what) {
959         if(nonblocking) {
960           *done = FALSE;
961           return CURLE_OK;
962         }
963         else {
964           /* timeout */
965           failf(data, "SSL connection timeout");
966           return CURLE_OPERATION_TIMEDOUT;
967         }
968       }
969       /* socket is readable or writable */
970     }
971 
972     /* Run transaction, and return to the caller if it failed or if this
973      * connection is done nonblocking and this loop would execute again. This
974      * permits the owner of a multi handle to abort a connection attempt
975      * before step2 has completed while ensuring that a client using select()
976      * or epoll() will always have a valid fdset to wait on.
977      */
978     connssl->io_need = CURL_SSL_IO_NEED_NONE;
979     ret = bearssl_connect_step2(cf, data);
980     if(ret || (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
981       return ret;
982   }
983 
984   if(ssl_connect_3 == connssl->connecting_state) {
985     ret = bearssl_connect_step3(cf, data);
986     if(ret)
987       return ret;
988   }
989 
990   if(ssl_connect_done == connssl->connecting_state) {
991     connssl->state = ssl_connection_complete;
992     *done = TRUE;
993   }
994   else
995     *done = FALSE;
996 
997   /* Reset our connect state machine */
998   connssl->connecting_state = ssl_connect_1;
999 
1000   return CURLE_OK;
1001 }
1002 
bearssl_version(char * buffer,size_t size)1003 static size_t bearssl_version(char *buffer, size_t size)
1004 {
1005   return msnprintf(buffer, size, "BearSSL");
1006 }
1007 
bearssl_data_pending(struct Curl_cfilter * cf,const struct Curl_easy * data)1008 static bool bearssl_data_pending(struct Curl_cfilter *cf,
1009                                  const struct Curl_easy *data)
1010 {
1011   struct ssl_connect_data *ctx = cf->ctx;
1012   struct bearssl_ssl_backend_data *backend;
1013 
1014   (void)data;
1015   DEBUGASSERT(ctx && ctx->backend);
1016   backend = (struct bearssl_ssl_backend_data *)ctx->backend;
1017   return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
1018 }
1019 
bearssl_random(struct Curl_easy * data UNUSED_PARAM,unsigned char * entropy,size_t length)1020 static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
1021                                unsigned char *entropy, size_t length)
1022 {
1023   static br_hmac_drbg_context ctx;
1024   static bool seeded = FALSE;
1025 
1026   if(!seeded) {
1027     br_prng_seeder seeder;
1028 
1029     br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0);
1030     seeder = br_prng_seeder_system(NULL);
1031     if(!seeder || !seeder(&ctx.vtable))
1032       return CURLE_FAILED_INIT;
1033     seeded = TRUE;
1034   }
1035   br_hmac_drbg_generate(&ctx, entropy, length);
1036 
1037   return CURLE_OK;
1038 }
1039 
bearssl_connect(struct Curl_cfilter * cf,struct Curl_easy * data)1040 static CURLcode bearssl_connect(struct Curl_cfilter *cf,
1041                                 struct Curl_easy *data)
1042 {
1043   CURLcode ret;
1044   bool done = FALSE;
1045 
1046   ret = bearssl_connect_common(cf, data, FALSE, &done);
1047   if(ret)
1048     return ret;
1049 
1050   DEBUGASSERT(done);
1051 
1052   return CURLE_OK;
1053 }
1054 
bearssl_connect_nonblocking(struct Curl_cfilter * cf,struct Curl_easy * data,bool * done)1055 static CURLcode bearssl_connect_nonblocking(struct Curl_cfilter *cf,
1056                                             struct Curl_easy *data,
1057                                             bool *done)
1058 {
1059   return bearssl_connect_common(cf, data, TRUE, done);
1060 }
1061 
bearssl_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)1062 static void *bearssl_get_internals(struct ssl_connect_data *connssl,
1063                                    CURLINFO info UNUSED_PARAM)
1064 {
1065   struct bearssl_ssl_backend_data *backend =
1066     (struct bearssl_ssl_backend_data *)connssl->backend;
1067   DEBUGASSERT(backend);
1068   return &backend->ctx;
1069 }
1070 
bearssl_shutdown(struct Curl_cfilter * cf,struct Curl_easy * data,bool send_shutdown,bool * done)1071 static CURLcode bearssl_shutdown(struct Curl_cfilter *cf,
1072                                  struct Curl_easy *data,
1073                                  bool send_shutdown, bool *done)
1074 {
1075   struct ssl_connect_data *connssl = cf->ctx;
1076   struct bearssl_ssl_backend_data *backend =
1077     (struct bearssl_ssl_backend_data *)connssl->backend;
1078   CURLcode result;
1079 
1080   DEBUGASSERT(backend);
1081   if(!backend->active || cf->shutdown) {
1082     *done = TRUE;
1083     return CURLE_OK;
1084   }
1085 
1086   *done = FALSE;
1087   if(!backend->sent_shutdown) {
1088     (void)send_shutdown; /* unknown how to suppress our close notify */
1089     br_ssl_engine_close(&backend->ctx.eng);
1090     backend->sent_shutdown = TRUE;
1091   }
1092 
1093   result = bearssl_run_until(cf, data, BR_SSL_CLOSED);
1094   if(result == CURLE_OK) {
1095     *done = TRUE;
1096   }
1097   else if(result == CURLE_AGAIN) {
1098     CURL_TRC_CF(data, cf, "shutdown EAGAIN, io_need=%x", connssl->io_need);
1099     result = CURLE_OK;
1100   }
1101   else
1102     CURL_TRC_CF(data, cf, "shutdown error: %d", result);
1103 
1104   cf->shutdown = (result || *done);
1105   return result;
1106 }
1107 
bearssl_close(struct Curl_cfilter * cf,struct Curl_easy * data)1108 static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
1109 {
1110   struct ssl_connect_data *connssl = cf->ctx;
1111   struct bearssl_ssl_backend_data *backend =
1112     (struct bearssl_ssl_backend_data *)connssl->backend;
1113   size_t i;
1114 
1115   (void)data;
1116   DEBUGASSERT(backend);
1117 
1118   backend->active = FALSE;
1119   if(backend->anchors) {
1120     for(i = 0; i < backend->anchors_len; ++i)
1121       free(backend->anchors[i].dn.data);
1122     Curl_safefree(backend->anchors);
1123   }
1124 }
1125 
bearssl_sha256sum(const unsigned char * input,size_t inputlen,unsigned char * sha256sum,size_t sha256len UNUSED_PARAM)1126 static CURLcode bearssl_sha256sum(const unsigned char *input,
1127                                   size_t inputlen,
1128                                   unsigned char *sha256sum,
1129                                   size_t sha256len UNUSED_PARAM)
1130 {
1131   br_sha256_context ctx;
1132 
1133   br_sha256_init(&ctx);
1134   br_sha256_update(&ctx, input, inputlen);
1135   br_sha256_out(&ctx, sha256sum);
1136   return CURLE_OK;
1137 }
1138 
1139 const struct Curl_ssl Curl_ssl_bearssl = {
1140   { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
1141 
1142   SSLSUPP_CAINFO_BLOB |
1143   SSLSUPP_SSL_CTX |
1144   SSLSUPP_HTTPS_PROXY |
1145   SSLSUPP_CIPHER_LIST,
1146 
1147   sizeof(struct bearssl_ssl_backend_data),
1148 
1149   Curl_none_init,                  /* init */
1150   Curl_none_cleanup,               /* cleanup */
1151   bearssl_version,                 /* version */
1152   Curl_none_check_cxn,             /* check_cxn */
1153   bearssl_shutdown,                /* shutdown */
1154   bearssl_data_pending,            /* data_pending */
1155   bearssl_random,                  /* random */
1156   Curl_none_cert_status_request,   /* cert_status_request */
1157   bearssl_connect,                 /* connect */
1158   bearssl_connect_nonblocking,     /* connect_nonblocking */
1159   Curl_ssl_adjust_pollset,         /* adjust_pollset */
1160   bearssl_get_internals,           /* get_internals */
1161   bearssl_close,                   /* close_one */
1162   Curl_none_close_all,             /* close_all */
1163   Curl_none_set_engine,            /* set_engine */
1164   Curl_none_set_engine_default,    /* set_engine_default */
1165   Curl_none_engines_list,          /* engines_list */
1166   Curl_none_false_start,           /* false_start */
1167   bearssl_sha256sum,               /* sha256sum */
1168   NULL,                            /* associate_connection */
1169   NULL,                            /* disassociate_connection */
1170   bearssl_recv,                    /* recv decrypted data */
1171   bearssl_send,                    /* send data to encrypt */
1172   NULL,                            /* get_channel_binding */
1173 };
1174 
1175 #endif /* USE_BEARSSL */
1176