da8cb82ce23e5a5ef85aa3e631cb7eececf99a17
[platform/upstream/cmake.git] / Utilities / cmcurl / lib / vtls / wolfssl.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
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  ***************************************************************************/
22
23 /*
24  * Source file for all wolfSSL specific code for the TLS/SSL layer. No code
25  * but vtls.c should ever call or use these functions.
26  *
27  */
28
29 #include "curl_setup.h"
30
31 #ifdef USE_WOLFSSL
32
33 #define WOLFSSL_OPTIONS_IGNORE_SYS
34 #include <wolfssl/version.h>
35 #include <wolfssl/options.h>
36
37 /* To determine what functions are available we rely on one or both of:
38    - the user's options.h generated by wolfSSL
39    - the symbols detected by curl's configure
40    Since they are markedly different from one another, and one or the other may
41    not be available, we do some checking below to bring things in sync. */
42
43 /* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */
44 #ifndef HAVE_ALPN
45 #ifdef HAVE_WOLFSSL_USEALPN
46 #define HAVE_ALPN
47 #endif
48 #endif
49
50 #include <limits.h>
51
52 #include "urldata.h"
53 #include "sendf.h"
54 #include "inet_pton.h"
55 #include "vtls.h"
56 #include "keylog.h"
57 #include "parsedate.h"
58 #include "connect.h" /* for the connect timeout */
59 #include "select.h"
60 #include "strcase.h"
61 #include "x509asn1.h"
62 #include "curl_printf.h"
63 #include "multiif.h"
64
65 #include <wolfssl/openssl/ssl.h>
66 #include <wolfssl/ssl.h>
67 #include <wolfssl/error-ssl.h>
68 #include "wolfssl.h"
69
70 /* The last #include files should be: */
71 #include "curl_memory.h"
72 #include "memdebug.h"
73
74 /* KEEP_PEER_CERT is a product of the presence of build time symbol
75    OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is
76    in wolfSSL's settings.h, and the latter two are build time symbols in
77    options.h. */
78 #ifndef KEEP_PEER_CERT
79 #if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
80     (defined(OPENSSL_EXTRA) && !defined(NO_CERTS))
81 #define KEEP_PEER_CERT
82 #endif
83 #endif
84
85 struct ssl_backend_data {
86   SSL_CTX* ctx;
87   SSL*     handle;
88 };
89
90 static Curl_recv wolfssl_recv;
91 static Curl_send wolfssl_send;
92
93 #ifdef OPENSSL_EXTRA
94 /*
95  * Availability note:
96  * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in
97  * WolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that
98  * option is not set, then TLS 1.3 will not be logged.
99  * For TLS 1.2 and before, we use wolfSSL_get_keys().
100  * SSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA
101  * (--enable-opensslextra or --enable-all).
102  */
103 #if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
104 static int
105 wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret,
106                               int secretSz, void *ctx)
107 {
108   const char *label;
109   unsigned char client_random[SSL3_RANDOM_SIZE];
110   (void)ctx;
111
112   if(!ssl || !Curl_tls_keylog_enabled()) {
113     return 0;
114   }
115
116   switch(id) {
117   case CLIENT_EARLY_TRAFFIC_SECRET:
118     label = "CLIENT_EARLY_TRAFFIC_SECRET";
119     break;
120   case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
121     label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
122     break;
123   case SERVER_HANDSHAKE_TRAFFIC_SECRET:
124     label = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
125     break;
126   case CLIENT_TRAFFIC_SECRET:
127     label = "CLIENT_TRAFFIC_SECRET_0";
128     break;
129   case SERVER_TRAFFIC_SECRET:
130     label = "SERVER_TRAFFIC_SECRET_0";
131     break;
132   case EARLY_EXPORTER_SECRET:
133     label = "EARLY_EXPORTER_SECRET";
134     break;
135   case EXPORTER_SECRET:
136     label = "EXPORTER_SECRET";
137     break;
138   default:
139     return 0;
140   }
141
142   if(SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) {
143     /* Should never happen as wolfSSL_KeepArrays() was called before. */
144     return 0;
145   }
146
147   Curl_tls_keylog_write(label, client_random, secret, secretSz);
148   return 0;
149 }
150 #endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */
151
152 static void
153 wolfssl_log_tls12_secret(SSL *ssl)
154 {
155   unsigned char *ms, *sr, *cr;
156   unsigned int msLen, srLen, crLen, i, x = 0;
157
158 #if LIBWOLFSSL_VERSION_HEX >= 0x0300d000 /* >= 3.13.0 */
159   /* wolfSSL_GetVersion is available since 3.13, we use it instead of
160    * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or
161    * --enable-all). Failing to perform this check could result in an unusable
162    * key log line when TLS 1.3 is actually negotiated. */
163   switch(wolfSSL_GetVersion(ssl)) {
164   case WOLFSSL_SSLV3:
165   case WOLFSSL_TLSV1:
166   case WOLFSSL_TLSV1_1:
167   case WOLFSSL_TLSV1_2:
168     break;
169   default:
170     /* TLS 1.3 does not use this mechanism, the "master secret" returned below
171      * is not directly usable. */
172     return;
173   }
174 #endif
175
176   if(SSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) != SSL_SUCCESS) {
177     return;
178   }
179
180   /* Check for a missing master secret and skip logging. That can happen if
181    * curl rejects the server certificate and aborts the handshake.
182    */
183   for(i = 0; i < msLen; i++) {
184     x |= ms[i];
185   }
186   if(x == 0) {
187     return;
188   }
189
190   Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen);
191 }
192 #endif /* OPENSSL_EXTRA */
193
194 static int do_file_type(const char *type)
195 {
196   if(!type || !type[0])
197     return SSL_FILETYPE_PEM;
198   if(strcasecompare(type, "PEM"))
199     return SSL_FILETYPE_PEM;
200   if(strcasecompare(type, "DER"))
201     return SSL_FILETYPE_ASN1;
202   return -1;
203 }
204
205 #ifdef HAVE_LIBOQS
206 struct group_name_map {
207   const word16 group;
208   const char   *name;
209 };
210
211 static const struct group_name_map gnm[] = {
212   { WOLFSSL_KYBER_LEVEL1, "KYBER_LEVEL1" },
213   { WOLFSSL_KYBER_LEVEL3, "KYBER_LEVEL3" },
214   { WOLFSSL_KYBER_LEVEL5, "KYBER_LEVEL5" },
215   { WOLFSSL_NTRU_HPS_LEVEL1, "NTRU_HPS_LEVEL1" },
216   { WOLFSSL_NTRU_HPS_LEVEL3, "NTRU_HPS_LEVEL3" },
217   { WOLFSSL_NTRU_HPS_LEVEL5, "NTRU_HPS_LEVEL5" },
218   { WOLFSSL_NTRU_HRSS_LEVEL3, "NTRU_HRSS_LEVEL3" },
219   { WOLFSSL_SABER_LEVEL1, "SABER_LEVEL1" },
220   { WOLFSSL_SABER_LEVEL3, "SABER_LEVEL3" },
221   { WOLFSSL_SABER_LEVEL5, "SABER_LEVEL5" },
222   { WOLFSSL_KYBER_90S_LEVEL1, "KYBER_90S_LEVEL1" },
223   { WOLFSSL_KYBER_90S_LEVEL3, "KYBER_90S_LEVEL3" },
224   { WOLFSSL_KYBER_90S_LEVEL5, "KYBER_90S_LEVEL5" },
225   { WOLFSSL_P256_NTRU_HPS_LEVEL1, "P256_NTRU_HPS_LEVEL1" },
226   { WOLFSSL_P384_NTRU_HPS_LEVEL3, "P384_NTRU_HPS_LEVEL3" },
227   { WOLFSSL_P521_NTRU_HPS_LEVEL5, "P521_NTRU_HPS_LEVEL5" },
228   { WOLFSSL_P384_NTRU_HRSS_LEVEL3, "P384_NTRU_HRSS_LEVEL3" },
229   { WOLFSSL_P256_SABER_LEVEL1, "P256_SABER_LEVEL1" },
230   { WOLFSSL_P384_SABER_LEVEL3, "P384_SABER_LEVEL3" },
231   { WOLFSSL_P521_SABER_LEVEL5, "P521_SABER_LEVEL5" },
232   { WOLFSSL_P256_KYBER_LEVEL1, "P256_KYBER_LEVEL1" },
233   { WOLFSSL_P384_KYBER_LEVEL3, "P384_KYBER_LEVEL3" },
234   { WOLFSSL_P521_KYBER_LEVEL5, "P521_KYBER_LEVEL5" },
235   { WOLFSSL_P256_KYBER_90S_LEVEL1, "P256_KYBER_90S_LEVEL1" },
236   { WOLFSSL_P384_KYBER_90S_LEVEL3, "P384_KYBER_90S_LEVEL3" },
237   { WOLFSSL_P521_KYBER_90S_LEVEL5, "P521_KYBER_90S_LEVEL5" },
238   { 0, NULL }
239 };
240 #endif
241
242 /*
243  * This function loads all the client/CA certificates and CRLs. Setup the TLS
244  * layer and do all necessary magic.
245  */
246 static CURLcode
247 wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
248                      int sockindex)
249 {
250   char *ciphers, *curves;
251   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
252   struct ssl_backend_data *backend = connssl->backend;
253   SSL_METHOD* req_method = NULL;
254   curl_socket_t sockfd = conn->sock[sockindex];
255 #ifdef HAVE_LIBOQS
256   word16 oqsAlg = 0;
257   size_t idx = 0;
258 #endif
259 #ifdef HAVE_SNI
260   bool sni = FALSE;
261 #define use_sni(x)  sni = (x)
262 #else
263 #define use_sni(x)  Curl_nop_stmt
264 #endif
265
266   DEBUGASSERT(backend);
267
268   if(connssl->state == ssl_connection_complete)
269     return CURLE_OK;
270
271   if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
272     failf(data, "wolfSSL does not support to set maximum SSL/TLS version");
273     return CURLE_SSL_CONNECT_ERROR;
274   }
275
276   /* check to see if we've been told to use an explicit SSL/TLS version */
277   switch(SSL_CONN_CONFIG(version)) {
278   case CURL_SSLVERSION_DEFAULT:
279   case CURL_SSLVERSION_TLSv1:
280 #if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
281     /* minimum protocol version is set later after the CTX object is created */
282     req_method = SSLv23_client_method();
283 #else
284     infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
285           "TLS 1.0 is used exclusively");
286     req_method = TLSv1_client_method();
287 #endif
288     use_sni(TRUE);
289     break;
290   case CURL_SSLVERSION_TLSv1_0:
291 #if defined(WOLFSSL_ALLOW_TLSV10) && !defined(NO_OLD_TLS)
292     req_method = TLSv1_client_method();
293     use_sni(TRUE);
294 #else
295     failf(data, "wolfSSL does not support TLS 1.0");
296     return CURLE_NOT_BUILT_IN;
297 #endif
298     break;
299   case CURL_SSLVERSION_TLSv1_1:
300 #ifndef NO_OLD_TLS
301     req_method = TLSv1_1_client_method();
302     use_sni(TRUE);
303 #else
304     failf(data, "wolfSSL does not support TLS 1.1");
305     return CURLE_NOT_BUILT_IN;
306 #endif
307     break;
308   case CURL_SSLVERSION_TLSv1_2:
309     req_method = TLSv1_2_client_method();
310     use_sni(TRUE);
311     break;
312   case CURL_SSLVERSION_TLSv1_3:
313 #ifdef WOLFSSL_TLS13
314     req_method = wolfTLSv1_3_client_method();
315     use_sni(TRUE);
316     break;
317 #else
318     failf(data, "wolfSSL: TLS 1.3 is not yet supported");
319     return CURLE_SSL_CONNECT_ERROR;
320 #endif
321   default:
322     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
323     return CURLE_SSL_CONNECT_ERROR;
324   }
325
326   if(!req_method) {
327     failf(data, "SSL: couldn't create a method");
328     return CURLE_OUT_OF_MEMORY;
329   }
330
331   if(backend->ctx)
332     SSL_CTX_free(backend->ctx);
333   backend->ctx = SSL_CTX_new(req_method);
334
335   if(!backend->ctx) {
336     failf(data, "SSL: couldn't create a context");
337     return CURLE_OUT_OF_MEMORY;
338   }
339
340   switch(SSL_CONN_CONFIG(version)) {
341   case CURL_SSLVERSION_DEFAULT:
342   case CURL_SSLVERSION_TLSv1:
343 #if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
344     /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is
345      * whatever minimum version of TLS was built in and at least TLS 1.0. For
346      * later library versions that could change (eg TLS 1.0 built in but
347      * defaults to TLS 1.1) so we have this short circuit evaluation to find
348      * the minimum supported TLS version.
349     */
350     if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) &&
351        (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) &&
352        (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1)
353 #ifdef WOLFSSL_TLS13
354        && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1)
355 #endif
356       ) {
357       failf(data, "SSL: couldn't set the minimum protocol version");
358       return CURLE_SSL_CONNECT_ERROR;
359     }
360 #endif
361     break;
362   }
363
364   ciphers = SSL_CONN_CONFIG(cipher_list);
365   if(ciphers) {
366     if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
367       failf(data, "failed setting cipher list: %s", ciphers);
368       return CURLE_SSL_CIPHER;
369     }
370     infof(data, "Cipher selection: %s", ciphers);
371   }
372
373   curves = SSL_CONN_CONFIG(curves);
374   if(curves) {
375
376 #ifdef HAVE_LIBOQS
377     for(idx = 0; gnm[idx].name != NULL; idx++) {
378       if(strncmp(curves, gnm[idx].name, strlen(gnm[idx].name)) == 0) {
379         oqsAlg = gnm[idx].group;
380         break;
381       }
382     }
383
384     if(oqsAlg == 0)
385 #endif
386     {
387       if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) {
388         failf(data, "failed setting curves list: '%s'", curves);
389         return CURLE_SSL_CIPHER;
390       }
391     }
392   }
393 #ifndef NO_FILESYSTEM
394   /* load trusted cacert */
395   if(SSL_CONN_CONFIG(CAfile)) {
396     if(1 != SSL_CTX_load_verify_locations(backend->ctx,
397                                       SSL_CONN_CONFIG(CAfile),
398                                       SSL_CONN_CONFIG(CApath))) {
399       if(SSL_CONN_CONFIG(verifypeer)) {
400         /* Fail if we insist on successfully verifying the server. */
401         failf(data, "error setting certificate verify locations:"
402               " CAfile: %s CApath: %s",
403               SSL_CONN_CONFIG(CAfile)?
404               SSL_CONN_CONFIG(CAfile): "none",
405               SSL_CONN_CONFIG(CApath)?
406               SSL_CONN_CONFIG(CApath) : "none");
407         return CURLE_SSL_CACERT_BADFILE;
408       }
409       else {
410         /* Just continue with a warning if no strict certificate
411            verification is required. */
412         infof(data, "error setting certificate verify locations,"
413               " continuing anyway:");
414       }
415     }
416     else {
417       /* Everything is fine. */
418       infof(data, "successfully set certificate verify locations:");
419     }
420     infof(data, " CAfile: %s",
421           SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none");
422     infof(data, " CApath: %s",
423           SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none");
424   }
425
426   /* Load the client certificate, and private key */
427   if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
428     int file_type = do_file_type(SSL_SET_OPTION(cert_type));
429
430     if(SSL_CTX_use_certificate_file(backend->ctx,
431                                     SSL_SET_OPTION(primary.clientcert),
432                                     file_type) != 1) {
433       failf(data, "unable to use client certificate (no key or wrong pass"
434             " phrase?)");
435       return CURLE_SSL_CONNECT_ERROR;
436     }
437
438     file_type = do_file_type(SSL_SET_OPTION(key_type));
439     if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key),
440                                     file_type) != 1) {
441       failf(data, "unable to set private key");
442       return CURLE_SSL_CONNECT_ERROR;
443     }
444   }
445 #endif /* !NO_FILESYSTEM */
446
447   /* SSL always tries to verify the peer, this only says whether it should
448    * fail to connect if the verification fails, or if it should continue
449    * anyway. In the latter case the result of the verification is checked with
450    * SSL_get_verify_result() below. */
451   SSL_CTX_set_verify(backend->ctx,
452                      SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
453                                                  SSL_VERIFY_NONE,
454                      NULL);
455
456 #ifdef HAVE_SNI
457   if(sni) {
458     struct in_addr addr4;
459 #ifdef ENABLE_IPV6
460     struct in6_addr addr6;
461 #endif
462     const char * const hostname = SSL_HOST_NAME();
463     size_t hostname_len = strlen(hostname);
464     if((hostname_len < USHRT_MAX) &&
465        !Curl_inet_pton(AF_INET, hostname, &addr4)
466 #ifdef ENABLE_IPV6
467        && !Curl_inet_pton(AF_INET6, hostname, &addr6)
468 #endif
469       ) {
470       size_t snilen;
471       char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
472       if(!snihost ||
473          wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, snihost,
474                             (unsigned short)snilen) != 1) {
475         failf(data, "Failed to set SNI");
476         return CURLE_SSL_CONNECT_ERROR;
477       }
478     }
479   }
480 #endif
481
482   /* give application a chance to interfere with SSL set up. */
483   if(data->set.ssl.fsslctx) {
484     CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx,
485                                                data->set.ssl.fsslctxp);
486     if(result) {
487       failf(data, "error signaled by ssl ctx callback");
488       return result;
489     }
490   }
491 #ifdef NO_FILESYSTEM
492   else if(SSL_CONN_CONFIG(verifypeer)) {
493     failf(data, "SSL: Certificates can't be loaded because wolfSSL was built"
494           " with \"no filesystem\". Either disable peer verification"
495           " (insecure) or if you are building an application with libcurl you"
496           " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
497     return CURLE_SSL_CONNECT_ERROR;
498   }
499 #endif
500
501   /* Let's make an SSL structure */
502   if(backend->handle)
503     SSL_free(backend->handle);
504   backend->handle = SSL_new(backend->ctx);
505   if(!backend->handle) {
506     failf(data, "SSL: couldn't create a context");
507     return CURLE_OUT_OF_MEMORY;
508   }
509
510 #ifdef HAVE_LIBOQS
511   if(oqsAlg) {
512     if(wolfSSL_UseKeyShare(backend->handle, oqsAlg) != WOLFSSL_SUCCESS) {
513       failf(data, "unable to use oqs KEM");
514     }
515   }
516 #endif
517
518 #ifdef HAVE_ALPN
519   if(conn->bits.tls_enable_alpn) {
520     char protocols[128];
521     *protocols = '\0';
522
523     /* wolfSSL's ALPN protocol name list format is a comma separated string of
524        protocols in descending order of preference, eg: "h2,http/1.1" */
525
526 #ifdef USE_HTTP2
527     if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
528       strcpy(protocols + strlen(protocols), ALPN_H2 ",");
529       infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
530     }
531 #endif
532
533     strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
534     infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
535
536     if(wolfSSL_UseALPN(backend->handle, protocols,
537                        (unsigned)strlen(protocols),
538                        WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
539       failf(data, "SSL: failed setting ALPN protocols");
540       return CURLE_SSL_CONNECT_ERROR;
541     }
542   }
543 #endif /* HAVE_ALPN */
544
545 #ifdef OPENSSL_EXTRA
546   if(Curl_tls_keylog_enabled()) {
547     /* Ensure the Client Random is preserved. */
548     wolfSSL_KeepArrays(backend->handle);
549 #if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
550     wolfSSL_set_tls13_secret_cb(backend->handle,
551                                 wolfssl_tls13_secret_callback, NULL);
552 #endif
553   }
554 #endif /* OPENSSL_EXTRA */
555
556 #ifdef HAVE_SECURE_RENEGOTIATION
557   if(wolfSSL_UseSecureRenegotiation(backend->handle) != SSL_SUCCESS) {
558     failf(data, "SSL: failed setting secure renegotiation");
559     return CURLE_SSL_CONNECT_ERROR;
560   }
561 #endif /* HAVE_SECURE_RENEGOTIATION */
562
563   /* Check if there's a cached ID we can/should use here! */
564   if(SSL_SET_OPTION(primary.sessionid)) {
565     void *ssl_sessionid = NULL;
566
567     Curl_ssl_sessionid_lock(data);
568     if(!Curl_ssl_getsessionid(data, conn,
569                               SSL_IS_PROXY() ? TRUE : FALSE,
570                               &ssl_sessionid, NULL, sockindex)) {
571       /* we got a session id, use it! */
572       if(!SSL_set_session(backend->handle, ssl_sessionid)) {
573         Curl_ssl_delsessionid(data, ssl_sessionid);
574         infof(data, "Can't use session ID, going on without");
575       }
576       else
577         infof(data, "SSL re-using session ID");
578     }
579     Curl_ssl_sessionid_unlock(data);
580   }
581
582   /* pass the raw socket into the SSL layer */
583   if(!SSL_set_fd(backend->handle, (int)sockfd)) {
584     failf(data, "SSL: SSL_set_fd failed");
585     return CURLE_SSL_CONNECT_ERROR;
586   }
587
588   connssl->connecting_state = ssl_connect_2;
589   return CURLE_OK;
590 }
591
592
593 static CURLcode
594 wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
595                      int sockindex)
596 {
597   int ret = -1;
598   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
599   struct ssl_backend_data *backend = connssl->backend;
600   const char * const dispname = SSL_HOST_DISPNAME();
601   const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
602
603   DEBUGASSERT(backend);
604
605   ERR_clear_error();
606
607   conn->recv[sockindex] = wolfssl_recv;
608   conn->send[sockindex] = wolfssl_send;
609
610   /* Enable RFC2818 checks */
611   if(SSL_CONN_CONFIG(verifyhost)) {
612     char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
613     if(!snihost ||
614        (wolfSSL_check_domain_name(backend->handle, snihost) == SSL_FAILURE))
615       return CURLE_SSL_CONNECT_ERROR;
616   }
617
618   ret = SSL_connect(backend->handle);
619
620 #ifdef OPENSSL_EXTRA
621   if(Curl_tls_keylog_enabled()) {
622     /* If key logging is enabled, wait for the handshake to complete and then
623      * proceed with logging secrets (for TLS 1.2 or older).
624      *
625      * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits
626      * for the server response. At that point the master secret is not yet
627      * available, so we must not try to read it.
628      * To log the secret on completion with a handshake failure, detect
629      * completion via the observation that there is nothing to read or write.
630      * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever
631      * changes, the worst case is that no key is logged on error.
632      */
633     if(ret == SSL_SUCCESS ||
634        (!wolfSSL_want_read(backend->handle) &&
635         !wolfSSL_want_write(backend->handle))) {
636       wolfssl_log_tls12_secret(backend->handle);
637       /* Client Random and master secrets are no longer needed, erase these.
638        * Ignored while the handshake is still in progress. */
639       wolfSSL_FreeArrays(backend->handle);
640     }
641   }
642 #endif  /* OPENSSL_EXTRA */
643
644   if(ret != 1) {
645     char error_buffer[WOLFSSL_MAX_ERROR_SZ];
646     int  detail = SSL_get_error(backend->handle, ret);
647
648     if(SSL_ERROR_WANT_READ == detail) {
649       connssl->connecting_state = ssl_connect_2_reading;
650       return CURLE_OK;
651     }
652     else if(SSL_ERROR_WANT_WRITE == detail) {
653       connssl->connecting_state = ssl_connect_2_writing;
654       return CURLE_OK;
655     }
656     /* There is no easy way to override only the CN matching.
657      * This will enable the override of both mismatching SubjectAltNames
658      * as also mismatching CN fields */
659     else if(DOMAIN_NAME_MISMATCH == detail) {
660 #if 1
661       failf(data, " subject alt name(s) or common name do not match \"%s\"",
662             dispname);
663       return CURLE_PEER_FAILED_VERIFICATION;
664 #else
665       /* When the wolfssl_check_domain_name() is used and you desire to
666        * continue on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost
667        * == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA
668        * error. The only way to do this is currently to switch the
669        * Wolfssl_check_domain_name() in and out based on the
670        * 'conn->ssl_config.verifyhost' value. */
671       if(SSL_CONN_CONFIG(verifyhost)) {
672         failf(data,
673               " subject alt name(s) or common name do not match \"%s\"\n",
674               dispname);
675         return CURLE_PEER_FAILED_VERIFICATION;
676       }
677       else {
678         infof(data,
679               " subject alt name(s) and/or common name do not match \"%s\"",
680               dispname);
681         return CURLE_OK;
682       }
683 #endif
684     }
685 #if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
686     else if(ASN_NO_SIGNER_E == detail) {
687       if(SSL_CONN_CONFIG(verifypeer)) {
688         failf(data, " CA signer not available for verification");
689         return CURLE_SSL_CACERT_BADFILE;
690       }
691       else {
692         /* Just continue with a warning if no strict certificate
693            verification is required. */
694         infof(data, "CA signer not available for verification, "
695                     "continuing anyway");
696       }
697     }
698 #endif
699     else {
700       failf(data, "SSL_connect failed with error %d: %s", detail,
701           ERR_error_string(detail, error_buffer));
702       return CURLE_SSL_CONNECT_ERROR;
703     }
704   }
705
706   if(pinnedpubkey) {
707 #ifdef KEEP_PEER_CERT
708     X509 *x509;
709     const char *x509_der;
710     int x509_der_len;
711     struct Curl_X509certificate x509_parsed;
712     struct Curl_asn1Element *pubkey;
713     CURLcode result;
714
715     x509 = SSL_get_peer_certificate(backend->handle);
716     if(!x509) {
717       failf(data, "SSL: failed retrieving server certificate");
718       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
719     }
720
721     x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len);
722     if(!x509_der) {
723       failf(data, "SSL: failed retrieving ASN.1 server certificate");
724       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
725     }
726
727     memset(&x509_parsed, 0, sizeof(x509_parsed));
728     if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
729       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
730
731     pubkey = &x509_parsed.subjectPublicKeyInfo;
732     if(!pubkey->header || pubkey->end <= pubkey->header) {
733       failf(data, "SSL: failed retrieving public key from server certificate");
734       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
735     }
736
737     result = Curl_pin_peer_pubkey(data,
738                                   pinnedpubkey,
739                                   (const unsigned char *)pubkey->header,
740                                   (size_t)(pubkey->end - pubkey->header));
741     if(result) {
742       failf(data, "SSL: public key does not match pinned public key");
743       return result;
744     }
745 #else
746     failf(data, "Library lacks pinning support built-in");
747     return CURLE_NOT_BUILT_IN;
748 #endif
749   }
750
751 #ifdef HAVE_ALPN
752   if(conn->bits.tls_enable_alpn) {
753     int rc;
754     char *protocol = NULL;
755     unsigned short protocol_len = 0;
756
757     rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len);
758
759     if(rc == SSL_SUCCESS) {
760       infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, protocol_len, protocol);
761
762       if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
763          !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
764         conn->negnpn = CURL_HTTP_VERSION_1_1;
765 #ifdef USE_HTTP2
766       else if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
767               protocol_len == ALPN_H2_LENGTH &&
768               !memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH))
769         conn->negnpn = CURL_HTTP_VERSION_2;
770 #endif
771       else
772         infof(data, "ALPN, unrecognized protocol %.*s", protocol_len,
773               protocol);
774       Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
775                           BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
776     }
777     else if(rc == SSL_ALPN_NOT_FOUND)
778       infof(data, VTLS_INFOF_NO_ALPN);
779     else {
780       failf(data, "ALPN, failure getting protocol, error %d", rc);
781       return CURLE_SSL_CONNECT_ERROR;
782     }
783   }
784 #endif /* HAVE_ALPN */
785
786   connssl->connecting_state = ssl_connect_3;
787 #if (LIBWOLFSSL_VERSION_HEX >= 0x03009010)
788   infof(data, "SSL connection using %s / %s",
789         wolfSSL_get_version(backend->handle),
790         wolfSSL_get_cipher_name(backend->handle));
791 #else
792   infof(data, "SSL connected");
793 #endif
794
795   return CURLE_OK;
796 }
797
798
799 static CURLcode
800 wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
801                      int sockindex)
802 {
803   CURLcode result = CURLE_OK;
804   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
805   struct ssl_backend_data *backend = connssl->backend;
806
807   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
808   DEBUGASSERT(backend);
809
810   if(SSL_SET_OPTION(primary.sessionid)) {
811     bool incache;
812     void *old_ssl_sessionid = NULL;
813     SSL_SESSION *our_ssl_sessionid = SSL_get_session(backend->handle);
814     bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
815
816     if(our_ssl_sessionid) {
817       Curl_ssl_sessionid_lock(data);
818       incache = !(Curl_ssl_getsessionid(data, conn, isproxy,
819                                         &old_ssl_sessionid, NULL, sockindex));
820       if(incache) {
821         if(old_ssl_sessionid != our_ssl_sessionid) {
822           infof(data, "old SSL session ID is stale, removing");
823           Curl_ssl_delsessionid(data, old_ssl_sessionid);
824           incache = FALSE;
825         }
826       }
827
828       if(!incache) {
829         result = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid,
830                                        0, sockindex, NULL);
831         if(result) {
832           Curl_ssl_sessionid_unlock(data);
833           failf(data, "failed to store ssl session");
834           return result;
835         }
836       }
837       Curl_ssl_sessionid_unlock(data);
838     }
839   }
840
841   connssl->connecting_state = ssl_connect_done;
842
843   return result;
844 }
845
846
847 static ssize_t wolfssl_send(struct Curl_easy *data,
848                             int sockindex,
849                             const void *mem,
850                             size_t len,
851                             CURLcode *curlcode)
852 {
853   struct connectdata *conn = data->conn;
854   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
855   struct ssl_backend_data *backend = connssl->backend;
856   char error_buffer[WOLFSSL_MAX_ERROR_SZ];
857   int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
858   int rc;
859
860   DEBUGASSERT(backend);
861
862   ERR_clear_error();
863
864   rc = SSL_write(backend->handle, mem, memlen);
865
866   if(rc <= 0) {
867     int err = SSL_get_error(backend->handle, rc);
868
869     switch(err) {
870     case SSL_ERROR_WANT_READ:
871     case SSL_ERROR_WANT_WRITE:
872       /* there's data pending, re-invoke SSL_write() */
873       *curlcode = CURLE_AGAIN;
874       return -1;
875     default:
876       failf(data, "SSL write: %s, errno %d",
877             ERR_error_string(err, error_buffer),
878             SOCKERRNO);
879       *curlcode = CURLE_SEND_ERROR;
880       return -1;
881     }
882   }
883   return rc;
884 }
885
886 static void wolfssl_close(struct Curl_easy *data, struct connectdata *conn,
887                           int sockindex)
888 {
889   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
890   struct ssl_backend_data *backend = connssl->backend;
891
892   (void) data;
893
894   DEBUGASSERT(backend);
895
896   if(backend->handle) {
897     char buf[32];
898     /* Maybe the server has already sent a close notify alert.
899        Read it to avoid an RST on the TCP connection. */
900     (void)SSL_read(backend->handle, buf, (int)sizeof(buf));
901     (void)SSL_shutdown(backend->handle);
902     SSL_free(backend->handle);
903     backend->handle = NULL;
904   }
905   if(backend->ctx) {
906     SSL_CTX_free(backend->ctx);
907     backend->ctx = NULL;
908   }
909 }
910
911 static ssize_t wolfssl_recv(struct Curl_easy *data,
912                             int num,
913                             char *buf,
914                             size_t buffersize,
915                             CURLcode *curlcode)
916 {
917   struct connectdata *conn = data->conn;
918   struct ssl_connect_data *connssl = &conn->ssl[num];
919   struct ssl_backend_data *backend = connssl->backend;
920   char error_buffer[WOLFSSL_MAX_ERROR_SZ];
921   int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
922   int nread;
923
924   DEBUGASSERT(backend);
925
926   ERR_clear_error();
927
928   nread = SSL_read(backend->handle, buf, buffsize);
929
930   if(nread <= 0) {
931     int err = SSL_get_error(backend->handle, nread);
932
933     switch(err) {
934     case SSL_ERROR_ZERO_RETURN: /* no more data */
935       break;
936     case SSL_ERROR_NONE:
937       /* FALLTHROUGH */
938     case SSL_ERROR_WANT_READ:
939       /* FALLTHROUGH */
940     case SSL_ERROR_WANT_WRITE:
941       /* there's data pending, re-invoke SSL_read() */
942       *curlcode = CURLE_AGAIN;
943       return -1;
944     default:
945       failf(data, "SSL read: %s, errno %d",
946             ERR_error_string(err, error_buffer), SOCKERRNO);
947       *curlcode = CURLE_RECV_ERROR;
948       return -1;
949     }
950   }
951   return nread;
952 }
953
954
955 static void wolfssl_session_free(void *ptr)
956 {
957   (void)ptr;
958   /* wolfSSL reuses sessions on own, no free */
959 }
960
961
962 static size_t wolfssl_version(char *buffer, size_t size)
963 {
964 #if LIBWOLFSSL_VERSION_HEX >= 0x03006000
965   return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
966 #elif defined(WOLFSSL_VERSION)
967   return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
968 #endif
969 }
970
971
972 static int wolfssl_init(void)
973 {
974 #ifdef OPENSSL_EXTRA
975   Curl_tls_keylog_open();
976 #endif
977   return (wolfSSL_Init() == SSL_SUCCESS);
978 }
979
980
981 static void wolfssl_cleanup(void)
982 {
983   wolfSSL_Cleanup();
984 #ifdef OPENSSL_EXTRA
985   Curl_tls_keylog_close();
986 #endif
987 }
988
989
990 static bool wolfssl_data_pending(const struct connectdata *conn,
991                                  int connindex)
992 {
993   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
994   struct ssl_backend_data *backend = connssl->backend;
995   DEBUGASSERT(backend);
996   if(backend->handle)   /* SSL is in use */
997     return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
998   else
999     return FALSE;
1000 }
1001
1002
1003 /*
1004  * This function is called to shut down the SSL layer but keep the
1005  * socket open (CCC - Clear Command Channel)
1006  */
1007 static int wolfssl_shutdown(struct Curl_easy *data, struct connectdata *conn,
1008                             int sockindex)
1009 {
1010   int retval = 0;
1011   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1012   struct ssl_backend_data *backend = connssl->backend;
1013
1014   (void) data;
1015
1016   DEBUGASSERT(backend);
1017
1018   if(backend->handle) {
1019     ERR_clear_error();
1020     SSL_free(backend->handle);
1021     backend->handle = NULL;
1022   }
1023   return retval;
1024 }
1025
1026
1027 static CURLcode
1028 wolfssl_connect_common(struct Curl_easy *data,
1029                       struct connectdata *conn,
1030                       int sockindex,
1031                       bool nonblocking,
1032                       bool *done)
1033 {
1034   CURLcode result;
1035   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1036   curl_socket_t sockfd = conn->sock[sockindex];
1037   int what;
1038
1039   /* check if the connection has already been established */
1040   if(ssl_connection_complete == connssl->state) {
1041     *done = TRUE;
1042     return CURLE_OK;
1043   }
1044
1045   if(ssl_connect_1 == connssl->connecting_state) {
1046     /* Find out how much more time we're allowed */
1047     const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
1048
1049     if(timeout_ms < 0) {
1050       /* no need to continue if time already is up */
1051       failf(data, "SSL connection timeout");
1052       return CURLE_OPERATION_TIMEDOUT;
1053     }
1054
1055     result = wolfssl_connect_step1(data, conn, sockindex);
1056     if(result)
1057       return result;
1058   }
1059
1060   while(ssl_connect_2 == connssl->connecting_state ||
1061         ssl_connect_2_reading == connssl->connecting_state ||
1062         ssl_connect_2_writing == connssl->connecting_state) {
1063
1064     /* check allowed time left */
1065     const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
1066
1067     if(timeout_ms < 0) {
1068       /* no need to continue if time already is up */
1069       failf(data, "SSL connection timeout");
1070       return CURLE_OPERATION_TIMEDOUT;
1071     }
1072
1073     /* if ssl is expecting something, check if it's available. */
1074     if(connssl->connecting_state == ssl_connect_2_reading
1075        || connssl->connecting_state == ssl_connect_2_writing) {
1076
1077       curl_socket_t writefd = ssl_connect_2_writing ==
1078         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1079       curl_socket_t readfd = ssl_connect_2_reading ==
1080         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1081
1082       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
1083                                nonblocking?0:timeout_ms);
1084       if(what < 0) {
1085         /* fatal error */
1086         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1087         return CURLE_SSL_CONNECT_ERROR;
1088       }
1089       else if(0 == what) {
1090         if(nonblocking) {
1091           *done = FALSE;
1092           return CURLE_OK;
1093         }
1094         else {
1095           /* timeout */
1096           failf(data, "SSL connection timeout");
1097           return CURLE_OPERATION_TIMEDOUT;
1098         }
1099       }
1100       /* socket is readable or writable */
1101     }
1102
1103     /* Run transaction, and return to the caller if it failed or if
1104      * this connection is part of a multi handle and this loop would
1105      * execute again. This permits the owner of a multi handle to
1106      * abort a connection attempt before step2 has completed while
1107      * ensuring that a client using select() or epoll() will always
1108      * have a valid fdset to wait on.
1109      */
1110     result = wolfssl_connect_step2(data, conn, sockindex);
1111     if(result || (nonblocking &&
1112                   (ssl_connect_2 == connssl->connecting_state ||
1113                    ssl_connect_2_reading == connssl->connecting_state ||
1114                    ssl_connect_2_writing == connssl->connecting_state)))
1115       return result;
1116   } /* repeat step2 until all transactions are done. */
1117
1118   if(ssl_connect_3 == connssl->connecting_state) {
1119     result = wolfssl_connect_step3(data, conn, sockindex);
1120     if(result)
1121       return result;
1122   }
1123
1124   if(ssl_connect_done == connssl->connecting_state) {
1125     connssl->state = ssl_connection_complete;
1126     conn->recv[sockindex] = wolfssl_recv;
1127     conn->send[sockindex] = wolfssl_send;
1128     *done = TRUE;
1129   }
1130   else
1131     *done = FALSE;
1132
1133   /* Reset our connect state machine */
1134   connssl->connecting_state = ssl_connect_1;
1135
1136   return CURLE_OK;
1137 }
1138
1139
1140 static CURLcode wolfssl_connect_nonblocking(struct Curl_easy *data,
1141                                             struct connectdata *conn,
1142                                             int sockindex, bool *done)
1143 {
1144   return wolfssl_connect_common(data, conn, sockindex, TRUE, done);
1145 }
1146
1147
1148 static CURLcode wolfssl_connect(struct Curl_easy *data,
1149                                 struct connectdata *conn, int sockindex)
1150 {
1151   CURLcode result;
1152   bool done = FALSE;
1153
1154   result = wolfssl_connect_common(data, conn, sockindex, FALSE, &done);
1155   if(result)
1156     return result;
1157
1158   DEBUGASSERT(done);
1159
1160   return CURLE_OK;
1161 }
1162
1163 static CURLcode wolfssl_random(struct Curl_easy *data,
1164                                unsigned char *entropy, size_t length)
1165 {
1166   WC_RNG rng;
1167   (void)data;
1168   if(wc_InitRng(&rng))
1169     return CURLE_FAILED_INIT;
1170   if(length > UINT_MAX)
1171     return CURLE_FAILED_INIT;
1172   if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length))
1173     return CURLE_FAILED_INIT;
1174   if(wc_FreeRng(&rng))
1175     return CURLE_FAILED_INIT;
1176   return CURLE_OK;
1177 }
1178
1179 static CURLcode wolfssl_sha256sum(const unsigned char *tmp, /* input */
1180                                   size_t tmplen,
1181                                   unsigned char *sha256sum /* output */,
1182                                   size_t unused)
1183 {
1184   wc_Sha256 SHA256pw;
1185   (void)unused;
1186   wc_InitSha256(&SHA256pw);
1187   wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen);
1188   wc_Sha256Final(&SHA256pw, sha256sum);
1189   return CURLE_OK;
1190 }
1191
1192 static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
1193                                    CURLINFO info UNUSED_PARAM)
1194 {
1195   struct ssl_backend_data *backend = connssl->backend;
1196   (void)info;
1197   DEBUGASSERT(backend);
1198   return backend->handle;
1199 }
1200
1201 const struct Curl_ssl Curl_ssl_wolfssl = {
1202   { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */
1203
1204 #ifdef KEEP_PEER_CERT
1205   SSLSUPP_PINNEDPUBKEY |
1206 #endif
1207   SSLSUPP_SSL_CTX,
1208
1209   sizeof(struct ssl_backend_data),
1210
1211   wolfssl_init,                    /* init */
1212   wolfssl_cleanup,                 /* cleanup */
1213   wolfssl_version,                 /* version */
1214   Curl_none_check_cxn,             /* check_cxn */
1215   wolfssl_shutdown,                /* shutdown */
1216   wolfssl_data_pending,            /* data_pending */
1217   wolfssl_random,                  /* random */
1218   Curl_none_cert_status_request,   /* cert_status_request */
1219   wolfssl_connect,                 /* connect */
1220   wolfssl_connect_nonblocking,     /* connect_nonblocking */
1221   Curl_ssl_getsock,                /* getsock */
1222   wolfssl_get_internals,           /* get_internals */
1223   wolfssl_close,                   /* close_one */
1224   Curl_none_close_all,             /* close_all */
1225   wolfssl_session_free,            /* session_free */
1226   Curl_none_set_engine,            /* set_engine */
1227   Curl_none_set_engine_default,    /* set_engine_default */
1228   Curl_none_engines_list,          /* engines_list */
1229   Curl_none_false_start,           /* false_start */
1230   wolfssl_sha256sum,               /* sha256sum */
1231   NULL,                            /* associate_connection */
1232   NULL                             /* disassociate_connection */
1233 };
1234
1235 #endif