1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker /*
26*6236dae4SAndroid Build Coastguard Worker * Source file for all wolfSSL specific code for the TLS/SSL layer. No code
27*6236dae4SAndroid Build Coastguard Worker * but vtls.c should ever call or use these functions.
28*6236dae4SAndroid Build Coastguard Worker *
29*6236dae4SAndroid Build Coastguard Worker */
30*6236dae4SAndroid Build Coastguard Worker
31*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
32*6236dae4SAndroid Build Coastguard Worker
33*6236dae4SAndroid Build Coastguard Worker #ifdef USE_WOLFSSL
34*6236dae4SAndroid Build Coastguard Worker
35*6236dae4SAndroid Build Coastguard Worker #define WOLFSSL_OPTIONS_IGNORE_SYS
36*6236dae4SAndroid Build Coastguard Worker #include <wolfssl/version.h>
37*6236dae4SAndroid Build Coastguard Worker #include <wolfssl/options.h>
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker #if LIBWOLFSSL_VERSION_HEX < 0x03004006 /* wolfSSL 3.4.6 (2015) */
40*6236dae4SAndroid Build Coastguard Worker #error "wolfSSL version should be at least 3.4.6"
41*6236dae4SAndroid Build Coastguard Worker #endif
42*6236dae4SAndroid Build Coastguard Worker
43*6236dae4SAndroid Build Coastguard Worker /* To determine what functions are available we rely on one or both of:
44*6236dae4SAndroid Build Coastguard Worker - the user's options.h generated by wolfSSL
45*6236dae4SAndroid Build Coastguard Worker - the symbols detected by curl's configure
46*6236dae4SAndroid Build Coastguard Worker Since they are markedly different from one another, and one or the other may
47*6236dae4SAndroid Build Coastguard Worker not be available, we do some checking below to bring things in sync. */
48*6236dae4SAndroid Build Coastguard Worker
49*6236dae4SAndroid Build Coastguard Worker /* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */
50*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_ALPN
51*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_WOLFSSL_USEALPN
52*6236dae4SAndroid Build Coastguard Worker #define HAVE_ALPN
53*6236dae4SAndroid Build Coastguard Worker #endif
54*6236dae4SAndroid Build Coastguard Worker #endif
55*6236dae4SAndroid Build Coastguard Worker
56*6236dae4SAndroid Build Coastguard Worker #include <limits.h>
57*6236dae4SAndroid Build Coastguard Worker
58*6236dae4SAndroid Build Coastguard Worker #include "urldata.h"
59*6236dae4SAndroid Build Coastguard Worker #include "sendf.h"
60*6236dae4SAndroid Build Coastguard Worker #include "inet_pton.h"
61*6236dae4SAndroid Build Coastguard Worker #include "vtls.h"
62*6236dae4SAndroid Build Coastguard Worker #include "vtls_int.h"
63*6236dae4SAndroid Build Coastguard Worker #include "keylog.h"
64*6236dae4SAndroid Build Coastguard Worker #include "parsedate.h"
65*6236dae4SAndroid Build Coastguard Worker #include "connect.h" /* for the connect timeout */
66*6236dae4SAndroid Build Coastguard Worker #include "select.h"
67*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
68*6236dae4SAndroid Build Coastguard Worker #include "x509asn1.h"
69*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
70*6236dae4SAndroid Build Coastguard Worker #include "multiif.h"
71*6236dae4SAndroid Build Coastguard Worker
72*6236dae4SAndroid Build Coastguard Worker #include <wolfssl/openssl/ssl.h>
73*6236dae4SAndroid Build Coastguard Worker #include <wolfssl/ssl.h>
74*6236dae4SAndroid Build Coastguard Worker #include <wolfssl/error-ssl.h>
75*6236dae4SAndroid Build Coastguard Worker #include "wolfssl.h"
76*6236dae4SAndroid Build Coastguard Worker
77*6236dae4SAndroid Build Coastguard Worker /* The last #include files should be: */
78*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
79*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
80*6236dae4SAndroid Build Coastguard Worker
81*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
82*6236dae4SAndroid Build Coastguard Worker # include "curl_base64.h"
83*6236dae4SAndroid Build Coastguard Worker # define ECH_ENABLED(__data__) \
84*6236dae4SAndroid Build Coastguard Worker (__data__->set.tls_ech && \
85*6236dae4SAndroid Build Coastguard Worker !(__data__->set.tls_ech & CURLECH_DISABLE)\
86*6236dae4SAndroid Build Coastguard Worker )
87*6236dae4SAndroid Build Coastguard Worker #endif /* USE_ECH */
88*6236dae4SAndroid Build Coastguard Worker
89*6236dae4SAndroid Build Coastguard Worker /* KEEP_PEER_CERT is a product of the presence of build time symbol
90*6236dae4SAndroid Build Coastguard Worker OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is
91*6236dae4SAndroid Build Coastguard Worker in wolfSSL's settings.h, and the latter two are build time symbols in
92*6236dae4SAndroid Build Coastguard Worker options.h. */
93*6236dae4SAndroid Build Coastguard Worker #ifndef KEEP_PEER_CERT
94*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
95*6236dae4SAndroid Build Coastguard Worker (defined(OPENSSL_EXTRA) && !defined(NO_CERTS))
96*6236dae4SAndroid Build Coastguard Worker #define KEEP_PEER_CERT
97*6236dae4SAndroid Build Coastguard Worker #endif
98*6236dae4SAndroid Build Coastguard Worker #endif
99*6236dae4SAndroid Build Coastguard Worker
100*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_WOLFSSL_BIO
101*6236dae4SAndroid Build Coastguard Worker #define USE_BIO_CHAIN
102*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_WOLFSSL_FULL_BIO
103*6236dae4SAndroid Build Coastguard Worker #define USE_FULL_BIO
104*6236dae4SAndroid Build Coastguard Worker #else /* HAVE_WOLFSSL_FULL_BIO */
105*6236dae4SAndroid Build Coastguard Worker #undef USE_FULL_BIO
106*6236dae4SAndroid Build Coastguard Worker #endif
107*6236dae4SAndroid Build Coastguard Worker /* wolfSSL 5.7.4 and older do not have these symbols, but only the
108*6236dae4SAndroid Build Coastguard Worker * OpenSSL ones. */
109*6236dae4SAndroid Build Coastguard Worker #ifndef WOLFSSL_BIO_CTRL_GET_CLOSE
110*6236dae4SAndroid Build Coastguard Worker #define WOLFSSL_BIO_CTRL_GET_CLOSE BIO_CTRL_GET_CLOSE
111*6236dae4SAndroid Build Coastguard Worker #define WOLFSSL_BIO_CTRL_SET_CLOSE BIO_CTRL_SET_CLOSE
112*6236dae4SAndroid Build Coastguard Worker #define WOLFSSL_BIO_CTRL_FLUSH BIO_CTRL_FLUSH
113*6236dae4SAndroid Build Coastguard Worker #define WOLFSSL_BIO_CTRL_DUP BIO_CTRL_DUP
114*6236dae4SAndroid Build Coastguard Worker #define wolfSSL_BIO_set_retry_write BIO_set_retry_write
115*6236dae4SAndroid Build Coastguard Worker #define wolfSSL_BIO_set_retry_read BIO_set_retry_read
116*6236dae4SAndroid Build Coastguard Worker #endif /* !WOLFSSL_BIO_CTRL_GET_CLOSE */
117*6236dae4SAndroid Build Coastguard Worker
118*6236dae4SAndroid Build Coastguard Worker #else /* HAVE_WOLFSSL_BIO */
119*6236dae4SAndroid Build Coastguard Worker #undef USE_BIO_CHAIN
120*6236dae4SAndroid Build Coastguard Worker #endif
121*6236dae4SAndroid Build Coastguard Worker
122*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_EXTRA
123*6236dae4SAndroid Build Coastguard Worker /*
124*6236dae4SAndroid Build Coastguard Worker * Availability note:
125*6236dae4SAndroid Build Coastguard Worker * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in
126*6236dae4SAndroid Build Coastguard Worker * wolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that
127*6236dae4SAndroid Build Coastguard Worker * option is not set, then TLS 1.3 will not be logged.
128*6236dae4SAndroid Build Coastguard Worker * For TLS 1.2 and before, we use wolfSSL_get_keys().
129*6236dae4SAndroid Build Coastguard Worker * SSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA
130*6236dae4SAndroid Build Coastguard Worker * (--enable-opensslextra or --enable-all).
131*6236dae4SAndroid Build Coastguard Worker */
132*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
133*6236dae4SAndroid Build Coastguard Worker static int
wolfssl_tls13_secret_callback(SSL * ssl,int id,const unsigned char * secret,int secretSz,void * ctx)134*6236dae4SAndroid Build Coastguard Worker wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret,
135*6236dae4SAndroid Build Coastguard Worker int secretSz, void *ctx)
136*6236dae4SAndroid Build Coastguard Worker {
137*6236dae4SAndroid Build Coastguard Worker const char *label;
138*6236dae4SAndroid Build Coastguard Worker unsigned char client_random[SSL3_RANDOM_SIZE];
139*6236dae4SAndroid Build Coastguard Worker (void)ctx;
140*6236dae4SAndroid Build Coastguard Worker
141*6236dae4SAndroid Build Coastguard Worker if(!ssl || !Curl_tls_keylog_enabled()) {
142*6236dae4SAndroid Build Coastguard Worker return 0;
143*6236dae4SAndroid Build Coastguard Worker }
144*6236dae4SAndroid Build Coastguard Worker
145*6236dae4SAndroid Build Coastguard Worker switch(id) {
146*6236dae4SAndroid Build Coastguard Worker case CLIENT_EARLY_TRAFFIC_SECRET:
147*6236dae4SAndroid Build Coastguard Worker label = "CLIENT_EARLY_TRAFFIC_SECRET";
148*6236dae4SAndroid Build Coastguard Worker break;
149*6236dae4SAndroid Build Coastguard Worker case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
150*6236dae4SAndroid Build Coastguard Worker label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
151*6236dae4SAndroid Build Coastguard Worker break;
152*6236dae4SAndroid Build Coastguard Worker case SERVER_HANDSHAKE_TRAFFIC_SECRET:
153*6236dae4SAndroid Build Coastguard Worker label = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
154*6236dae4SAndroid Build Coastguard Worker break;
155*6236dae4SAndroid Build Coastguard Worker case CLIENT_TRAFFIC_SECRET:
156*6236dae4SAndroid Build Coastguard Worker label = "CLIENT_TRAFFIC_SECRET_0";
157*6236dae4SAndroid Build Coastguard Worker break;
158*6236dae4SAndroid Build Coastguard Worker case SERVER_TRAFFIC_SECRET:
159*6236dae4SAndroid Build Coastguard Worker label = "SERVER_TRAFFIC_SECRET_0";
160*6236dae4SAndroid Build Coastguard Worker break;
161*6236dae4SAndroid Build Coastguard Worker case EARLY_EXPORTER_SECRET:
162*6236dae4SAndroid Build Coastguard Worker label = "EARLY_EXPORTER_SECRET";
163*6236dae4SAndroid Build Coastguard Worker break;
164*6236dae4SAndroid Build Coastguard Worker case EXPORTER_SECRET:
165*6236dae4SAndroid Build Coastguard Worker label = "EXPORTER_SECRET";
166*6236dae4SAndroid Build Coastguard Worker break;
167*6236dae4SAndroid Build Coastguard Worker default:
168*6236dae4SAndroid Build Coastguard Worker return 0;
169*6236dae4SAndroid Build Coastguard Worker }
170*6236dae4SAndroid Build Coastguard Worker
171*6236dae4SAndroid Build Coastguard Worker if(SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) {
172*6236dae4SAndroid Build Coastguard Worker /* Should never happen as wolfSSL_KeepArrays() was called before. */
173*6236dae4SAndroid Build Coastguard Worker return 0;
174*6236dae4SAndroid Build Coastguard Worker }
175*6236dae4SAndroid Build Coastguard Worker
176*6236dae4SAndroid Build Coastguard Worker Curl_tls_keylog_write(label, client_random, secret, secretSz);
177*6236dae4SAndroid Build Coastguard Worker return 0;
178*6236dae4SAndroid Build Coastguard Worker }
179*6236dae4SAndroid Build Coastguard Worker #endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */
180*6236dae4SAndroid Build Coastguard Worker
181*6236dae4SAndroid Build Coastguard Worker static void
wolfssl_log_tls12_secret(WOLFSSL * ssl)182*6236dae4SAndroid Build Coastguard Worker wolfssl_log_tls12_secret(WOLFSSL *ssl)
183*6236dae4SAndroid Build Coastguard Worker {
184*6236dae4SAndroid Build Coastguard Worker unsigned char *ms, *sr, *cr;
185*6236dae4SAndroid Build Coastguard Worker unsigned int msLen, srLen, crLen, i, x = 0;
186*6236dae4SAndroid Build Coastguard Worker
187*6236dae4SAndroid Build Coastguard Worker #if LIBWOLFSSL_VERSION_HEX >= 0x0300d000 /* >= 3.13.0 */
188*6236dae4SAndroid Build Coastguard Worker /* wolfSSL_GetVersion is available since 3.13, we use it instead of
189*6236dae4SAndroid Build Coastguard Worker * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or
190*6236dae4SAndroid Build Coastguard Worker * --enable-all). Failing to perform this check could result in an unusable
191*6236dae4SAndroid Build Coastguard Worker * key log line when TLS 1.3 is actually negotiated. */
192*6236dae4SAndroid Build Coastguard Worker switch(wolfSSL_GetVersion(ssl)) {
193*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_SSLV3:
194*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_TLSV1:
195*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_TLSV1_1:
196*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_TLSV1_2:
197*6236dae4SAndroid Build Coastguard Worker break;
198*6236dae4SAndroid Build Coastguard Worker default:
199*6236dae4SAndroid Build Coastguard Worker /* TLS 1.3 does not use this mechanism, the "master secret" returned below
200*6236dae4SAndroid Build Coastguard Worker * is not directly usable. */
201*6236dae4SAndroid Build Coastguard Worker return;
202*6236dae4SAndroid Build Coastguard Worker }
203*6236dae4SAndroid Build Coastguard Worker #endif
204*6236dae4SAndroid Build Coastguard Worker
205*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) !=
206*6236dae4SAndroid Build Coastguard Worker WOLFSSL_SUCCESS) {
207*6236dae4SAndroid Build Coastguard Worker return;
208*6236dae4SAndroid Build Coastguard Worker }
209*6236dae4SAndroid Build Coastguard Worker
210*6236dae4SAndroid Build Coastguard Worker /* Check for a missing master secret and skip logging. That can happen if
211*6236dae4SAndroid Build Coastguard Worker * curl rejects the server certificate and aborts the handshake.
212*6236dae4SAndroid Build Coastguard Worker */
213*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < msLen; i++) {
214*6236dae4SAndroid Build Coastguard Worker x |= ms[i];
215*6236dae4SAndroid Build Coastguard Worker }
216*6236dae4SAndroid Build Coastguard Worker if(x == 0) {
217*6236dae4SAndroid Build Coastguard Worker return;
218*6236dae4SAndroid Build Coastguard Worker }
219*6236dae4SAndroid Build Coastguard Worker
220*6236dae4SAndroid Build Coastguard Worker Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen);
221*6236dae4SAndroid Build Coastguard Worker }
222*6236dae4SAndroid Build Coastguard Worker #endif /* OPENSSL_EXTRA */
223*6236dae4SAndroid Build Coastguard Worker
wolfssl_do_file_type(const char * type)224*6236dae4SAndroid Build Coastguard Worker static int wolfssl_do_file_type(const char *type)
225*6236dae4SAndroid Build Coastguard Worker {
226*6236dae4SAndroid Build Coastguard Worker if(!type || !type[0])
227*6236dae4SAndroid Build Coastguard Worker return WOLFSSL_FILETYPE_PEM;
228*6236dae4SAndroid Build Coastguard Worker if(strcasecompare(type, "PEM"))
229*6236dae4SAndroid Build Coastguard Worker return WOLFSSL_FILETYPE_PEM;
230*6236dae4SAndroid Build Coastguard Worker if(strcasecompare(type, "DER"))
231*6236dae4SAndroid Build Coastguard Worker return WOLFSSL_FILETYPE_ASN1;
232*6236dae4SAndroid Build Coastguard Worker return -1;
233*6236dae4SAndroid Build Coastguard Worker }
234*6236dae4SAndroid Build Coastguard Worker
235*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_HAVE_KYBER
236*6236dae4SAndroid Build Coastguard Worker struct group_name_map {
237*6236dae4SAndroid Build Coastguard Worker const word16 group;
238*6236dae4SAndroid Build Coastguard Worker const char *name;
239*6236dae4SAndroid Build Coastguard Worker };
240*6236dae4SAndroid Build Coastguard Worker
241*6236dae4SAndroid Build Coastguard Worker static const struct group_name_map gnm[] = {
242*6236dae4SAndroid Build Coastguard Worker { WOLFSSL_KYBER_LEVEL1, "KYBER_LEVEL1" },
243*6236dae4SAndroid Build Coastguard Worker { WOLFSSL_KYBER_LEVEL3, "KYBER_LEVEL3" },
244*6236dae4SAndroid Build Coastguard Worker { WOLFSSL_KYBER_LEVEL5, "KYBER_LEVEL5" },
245*6236dae4SAndroid Build Coastguard Worker { WOLFSSL_P256_KYBER_LEVEL1, "P256_KYBER_LEVEL1" },
246*6236dae4SAndroid Build Coastguard Worker { WOLFSSL_P384_KYBER_LEVEL3, "P384_KYBER_LEVEL3" },
247*6236dae4SAndroid Build Coastguard Worker { WOLFSSL_P521_KYBER_LEVEL5, "P521_KYBER_LEVEL5" },
248*6236dae4SAndroid Build Coastguard Worker { 0, NULL }
249*6236dae4SAndroid Build Coastguard Worker };
250*6236dae4SAndroid Build Coastguard Worker #endif
251*6236dae4SAndroid Build Coastguard Worker
252*6236dae4SAndroid Build Coastguard Worker #ifdef USE_BIO_CHAIN
253*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_create(WOLFSSL_BIO * bio)254*6236dae4SAndroid Build Coastguard Worker static int wolfssl_bio_cf_create(WOLFSSL_BIO *bio)
255*6236dae4SAndroid Build Coastguard Worker {
256*6236dae4SAndroid Build Coastguard Worker #ifdef USE_FULL_BIO
257*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_set_shutdown(bio, 1);
258*6236dae4SAndroid Build Coastguard Worker #endif
259*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_set_data(bio, NULL);
260*6236dae4SAndroid Build Coastguard Worker return 1;
261*6236dae4SAndroid Build Coastguard Worker }
262*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_destroy(WOLFSSL_BIO * bio)263*6236dae4SAndroid Build Coastguard Worker static int wolfssl_bio_cf_destroy(WOLFSSL_BIO *bio)
264*6236dae4SAndroid Build Coastguard Worker {
265*6236dae4SAndroid Build Coastguard Worker if(!bio)
266*6236dae4SAndroid Build Coastguard Worker return 0;
267*6236dae4SAndroid Build Coastguard Worker return 1;
268*6236dae4SAndroid Build Coastguard Worker }
269*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_ctrl(WOLFSSL_BIO * bio,int cmd,long num,void * ptr)270*6236dae4SAndroid Build Coastguard Worker static long wolfssl_bio_cf_ctrl(WOLFSSL_BIO *bio, int cmd, long num, void *ptr)
271*6236dae4SAndroid Build Coastguard Worker {
272*6236dae4SAndroid Build Coastguard Worker struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
273*6236dae4SAndroid Build Coastguard Worker long ret = 1;
274*6236dae4SAndroid Build Coastguard Worker
275*6236dae4SAndroid Build Coastguard Worker (void)cf;
276*6236dae4SAndroid Build Coastguard Worker (void)ptr;
277*6236dae4SAndroid Build Coastguard Worker (void)num;
278*6236dae4SAndroid Build Coastguard Worker switch(cmd) {
279*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_BIO_CTRL_GET_CLOSE:
280*6236dae4SAndroid Build Coastguard Worker #ifdef USE_FULL_BIO
281*6236dae4SAndroid Build Coastguard Worker ret = (long)wolfSSL_BIO_get_shutdown(bio);
282*6236dae4SAndroid Build Coastguard Worker #else
283*6236dae4SAndroid Build Coastguard Worker ret = 0;
284*6236dae4SAndroid Build Coastguard Worker #endif
285*6236dae4SAndroid Build Coastguard Worker break;
286*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_BIO_CTRL_SET_CLOSE:
287*6236dae4SAndroid Build Coastguard Worker #ifdef USE_FULL_BIO
288*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_set_shutdown(bio, (int)num);
289*6236dae4SAndroid Build Coastguard Worker #endif
290*6236dae4SAndroid Build Coastguard Worker break;
291*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_BIO_CTRL_FLUSH:
292*6236dae4SAndroid Build Coastguard Worker /* we do no delayed writes, but if we ever would, this
293*6236dae4SAndroid Build Coastguard Worker * needs to trigger it. */
294*6236dae4SAndroid Build Coastguard Worker ret = 1;
295*6236dae4SAndroid Build Coastguard Worker break;
296*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_BIO_CTRL_DUP:
297*6236dae4SAndroid Build Coastguard Worker ret = 1;
298*6236dae4SAndroid Build Coastguard Worker break;
299*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_BIO_CTRL_EOF
300*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_BIO_CTRL_EOF:
301*6236dae4SAndroid Build Coastguard Worker /* EOF has been reached on input? */
302*6236dae4SAndroid Build Coastguard Worker return (!cf->next || !cf->next->connected);
303*6236dae4SAndroid Build Coastguard Worker #endif
304*6236dae4SAndroid Build Coastguard Worker default:
305*6236dae4SAndroid Build Coastguard Worker ret = 0;
306*6236dae4SAndroid Build Coastguard Worker break;
307*6236dae4SAndroid Build Coastguard Worker }
308*6236dae4SAndroid Build Coastguard Worker return ret;
309*6236dae4SAndroid Build Coastguard Worker }
310*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_out_write(WOLFSSL_BIO * bio,const char * buf,int blen)311*6236dae4SAndroid Build Coastguard Worker static int wolfssl_bio_cf_out_write(WOLFSSL_BIO *bio,
312*6236dae4SAndroid Build Coastguard Worker const char *buf, int blen)
313*6236dae4SAndroid Build Coastguard Worker {
314*6236dae4SAndroid Build Coastguard Worker struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
315*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
316*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
317*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
318*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data = CF_DATA_CURRENT(cf);
319*6236dae4SAndroid Build Coastguard Worker ssize_t nwritten, skiplen = 0;
320*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
321*6236dae4SAndroid Build Coastguard Worker
322*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(data);
323*6236dae4SAndroid Build Coastguard Worker if(backend->shutting_down && backend->io_send_blocked_len &&
324*6236dae4SAndroid Build Coastguard Worker (backend->io_send_blocked_len < blen)) {
325*6236dae4SAndroid Build Coastguard Worker /* bug in wolfSSL: <https://github.com/wolfSSL/wolfssl/issues/7784>
326*6236dae4SAndroid Build Coastguard Worker * It adds the close notify message again every time we retry
327*6236dae4SAndroid Build Coastguard Worker * sending during shutdown. */
328*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "bio_write, shutdown restrict send of %d"
329*6236dae4SAndroid Build Coastguard Worker " to %d bytes", blen, backend->io_send_blocked_len);
330*6236dae4SAndroid Build Coastguard Worker skiplen = (ssize_t)(blen - backend->io_send_blocked_len);
331*6236dae4SAndroid Build Coastguard Worker blen = backend->io_send_blocked_len;
332*6236dae4SAndroid Build Coastguard Worker }
333*6236dae4SAndroid Build Coastguard Worker nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &result);
334*6236dae4SAndroid Build Coastguard Worker backend->io_result = result;
335*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "bio_write(len=%d) -> %zd, %d",
336*6236dae4SAndroid Build Coastguard Worker blen, nwritten, result);
337*6236dae4SAndroid Build Coastguard Worker #ifdef USE_FULL_BIO
338*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_clear_retry_flags(bio);
339*6236dae4SAndroid Build Coastguard Worker #endif
340*6236dae4SAndroid Build Coastguard Worker if(nwritten < 0 && CURLE_AGAIN == result) {
341*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_set_retry_write(bio);
342*6236dae4SAndroid Build Coastguard Worker if(backend->shutting_down && !backend->io_send_blocked_len)
343*6236dae4SAndroid Build Coastguard Worker backend->io_send_blocked_len = blen;
344*6236dae4SAndroid Build Coastguard Worker }
345*6236dae4SAndroid Build Coastguard Worker else if(!result && skiplen)
346*6236dae4SAndroid Build Coastguard Worker nwritten += skiplen;
347*6236dae4SAndroid Build Coastguard Worker return (int)nwritten;
348*6236dae4SAndroid Build Coastguard Worker }
349*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_in_read(WOLFSSL_BIO * bio,char * buf,int blen)350*6236dae4SAndroid Build Coastguard Worker static int wolfssl_bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
351*6236dae4SAndroid Build Coastguard Worker {
352*6236dae4SAndroid Build Coastguard Worker struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
353*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
354*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
355*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
356*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data = CF_DATA_CURRENT(cf);
357*6236dae4SAndroid Build Coastguard Worker ssize_t nread;
358*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
359*6236dae4SAndroid Build Coastguard Worker
360*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(data);
361*6236dae4SAndroid Build Coastguard Worker /* OpenSSL catches this case, so should we. */
362*6236dae4SAndroid Build Coastguard Worker if(!buf)
363*6236dae4SAndroid Build Coastguard Worker return 0;
364*6236dae4SAndroid Build Coastguard Worker
365*6236dae4SAndroid Build Coastguard Worker nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
366*6236dae4SAndroid Build Coastguard Worker backend->io_result = result;
367*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "bio_read(len=%d) -> %zd, %d", blen, nread, result);
368*6236dae4SAndroid Build Coastguard Worker #ifdef USE_FULL_BIO
369*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_clear_retry_flags(bio);
370*6236dae4SAndroid Build Coastguard Worker #endif
371*6236dae4SAndroid Build Coastguard Worker if(nread < 0 && CURLE_AGAIN == result)
372*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_set_retry_read(bio);
373*6236dae4SAndroid Build Coastguard Worker else if(nread == 0)
374*6236dae4SAndroid Build Coastguard Worker connssl->peer_closed = TRUE;
375*6236dae4SAndroid Build Coastguard Worker return (int)nread;
376*6236dae4SAndroid Build Coastguard Worker }
377*6236dae4SAndroid Build Coastguard Worker
378*6236dae4SAndroid Build Coastguard Worker static WOLFSSL_BIO_METHOD *wolfssl_bio_cf_method = NULL;
379*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_init_methods(void)380*6236dae4SAndroid Build Coastguard Worker static void wolfssl_bio_cf_init_methods(void)
381*6236dae4SAndroid Build Coastguard Worker {
382*6236dae4SAndroid Build Coastguard Worker wolfssl_bio_cf_method = wolfSSL_BIO_meth_new(WOLFSSL_BIO_MEMORY,
383*6236dae4SAndroid Build Coastguard Worker "wolfSSL CF BIO");
384*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_meth_set_write(wolfssl_bio_cf_method, &wolfssl_bio_cf_out_write);
385*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_meth_set_read(wolfssl_bio_cf_method, &wolfssl_bio_cf_in_read);
386*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_meth_set_ctrl(wolfssl_bio_cf_method, &wolfssl_bio_cf_ctrl);
387*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_meth_set_create(wolfssl_bio_cf_method, &wolfssl_bio_cf_create);
388*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_meth_set_destroy(wolfssl_bio_cf_method, &wolfssl_bio_cf_destroy);
389*6236dae4SAndroid Build Coastguard Worker }
390*6236dae4SAndroid Build Coastguard Worker
wolfssl_bio_cf_free_methods(void)391*6236dae4SAndroid Build Coastguard Worker static void wolfssl_bio_cf_free_methods(void)
392*6236dae4SAndroid Build Coastguard Worker {
393*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_meth_free(wolfssl_bio_cf_method);
394*6236dae4SAndroid Build Coastguard Worker }
395*6236dae4SAndroid Build Coastguard Worker
396*6236dae4SAndroid Build Coastguard Worker #else /* USE_BIO_CHAIN */
397*6236dae4SAndroid Build Coastguard Worker
398*6236dae4SAndroid Build Coastguard Worker #define wolfssl_bio_cf_init_methods() Curl_nop_stmt
399*6236dae4SAndroid Build Coastguard Worker #define wolfssl_bio_cf_free_methods() Curl_nop_stmt
400*6236dae4SAndroid Build Coastguard Worker
401*6236dae4SAndroid Build Coastguard Worker #endif /* !USE_BIO_CHAIN */
402*6236dae4SAndroid Build Coastguard Worker
wolfssl_session_free(void * sdata,size_t slen)403*6236dae4SAndroid Build Coastguard Worker static void wolfssl_session_free(void *sdata, size_t slen)
404*6236dae4SAndroid Build Coastguard Worker {
405*6236dae4SAndroid Build Coastguard Worker (void)slen;
406*6236dae4SAndroid Build Coastguard Worker free(sdata);
407*6236dae4SAndroid Build Coastguard Worker }
408*6236dae4SAndroid Build Coastguard Worker
wssl_cache_session(struct Curl_cfilter * cf,struct Curl_easy * data,struct ssl_peer * peer,WOLFSSL_SESSION * session)409*6236dae4SAndroid Build Coastguard Worker CURLcode wssl_cache_session(struct Curl_cfilter *cf,
410*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
411*6236dae4SAndroid Build Coastguard Worker struct ssl_peer *peer,
412*6236dae4SAndroid Build Coastguard Worker WOLFSSL_SESSION *session)
413*6236dae4SAndroid Build Coastguard Worker {
414*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
415*6236dae4SAndroid Build Coastguard Worker unsigned char *sdata = NULL;
416*6236dae4SAndroid Build Coastguard Worker unsigned int slen;
417*6236dae4SAndroid Build Coastguard Worker
418*6236dae4SAndroid Build Coastguard Worker if(!session)
419*6236dae4SAndroid Build Coastguard Worker goto out;
420*6236dae4SAndroid Build Coastguard Worker
421*6236dae4SAndroid Build Coastguard Worker slen = wolfSSL_i2d_SSL_SESSION(session, NULL);
422*6236dae4SAndroid Build Coastguard Worker if(slen <= 0) {
423*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "fail to assess session length: %u", slen);
424*6236dae4SAndroid Build Coastguard Worker result = CURLE_FAILED_INIT;
425*6236dae4SAndroid Build Coastguard Worker goto out;
426*6236dae4SAndroid Build Coastguard Worker }
427*6236dae4SAndroid Build Coastguard Worker sdata = calloc(1, slen);
428*6236dae4SAndroid Build Coastguard Worker if(!sdata) {
429*6236dae4SAndroid Build Coastguard Worker failf(data, "unable to allocate session buffer of %u bytes", slen);
430*6236dae4SAndroid Build Coastguard Worker result = CURLE_OUT_OF_MEMORY;
431*6236dae4SAndroid Build Coastguard Worker goto out;
432*6236dae4SAndroid Build Coastguard Worker }
433*6236dae4SAndroid Build Coastguard Worker slen = wolfSSL_i2d_SSL_SESSION(session, &sdata);
434*6236dae4SAndroid Build Coastguard Worker if(slen <= 0) {
435*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "fail to serialize session: %u", slen);
436*6236dae4SAndroid Build Coastguard Worker result = CURLE_FAILED_INIT;
437*6236dae4SAndroid Build Coastguard Worker goto out;
438*6236dae4SAndroid Build Coastguard Worker }
439*6236dae4SAndroid Build Coastguard Worker
440*6236dae4SAndroid Build Coastguard Worker Curl_ssl_sessionid_lock(data);
441*6236dae4SAndroid Build Coastguard Worker result = Curl_ssl_set_sessionid(cf, data, peer, NULL,
442*6236dae4SAndroid Build Coastguard Worker sdata, slen, wolfssl_session_free);
443*6236dae4SAndroid Build Coastguard Worker Curl_ssl_sessionid_unlock(data);
444*6236dae4SAndroid Build Coastguard Worker if(result)
445*6236dae4SAndroid Build Coastguard Worker failf(data, "failed to add new ssl session to cache (%d)", result);
446*6236dae4SAndroid Build Coastguard Worker else {
447*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "added new session to cache");
448*6236dae4SAndroid Build Coastguard Worker sdata = NULL;
449*6236dae4SAndroid Build Coastguard Worker }
450*6236dae4SAndroid Build Coastguard Worker
451*6236dae4SAndroid Build Coastguard Worker out:
452*6236dae4SAndroid Build Coastguard Worker free(sdata);
453*6236dae4SAndroid Build Coastguard Worker return 0;
454*6236dae4SAndroid Build Coastguard Worker }
455*6236dae4SAndroid Build Coastguard Worker
wssl_vtls_new_session_cb(WOLFSSL * ssl,WOLFSSL_SESSION * session)456*6236dae4SAndroid Build Coastguard Worker static int wssl_vtls_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session)
457*6236dae4SAndroid Build Coastguard Worker {
458*6236dae4SAndroid Build Coastguard Worker struct Curl_cfilter *cf;
459*6236dae4SAndroid Build Coastguard Worker
460*6236dae4SAndroid Build Coastguard Worker cf = (struct Curl_cfilter*)wolfSSL_get_app_data(ssl);
461*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(cf != NULL);
462*6236dae4SAndroid Build Coastguard Worker if(cf && session) {
463*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
464*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data = CF_DATA_CURRENT(cf);
465*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(connssl);
466*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(data);
467*6236dae4SAndroid Build Coastguard Worker if(connssl && data) {
468*6236dae4SAndroid Build Coastguard Worker (void)wssl_cache_session(cf, data, &connssl->peer, session);
469*6236dae4SAndroid Build Coastguard Worker }
470*6236dae4SAndroid Build Coastguard Worker }
471*6236dae4SAndroid Build Coastguard Worker return 0;
472*6236dae4SAndroid Build Coastguard Worker }
473*6236dae4SAndroid Build Coastguard Worker
wssl_setup_session(struct Curl_cfilter * cf,struct Curl_easy * data,struct wolfssl_ctx * wss,struct ssl_peer * peer)474*6236dae4SAndroid Build Coastguard Worker CURLcode wssl_setup_session(struct Curl_cfilter *cf,
475*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
476*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *wss,
477*6236dae4SAndroid Build Coastguard Worker struct ssl_peer *peer)
478*6236dae4SAndroid Build Coastguard Worker {
479*6236dae4SAndroid Build Coastguard Worker void *psdata;
480*6236dae4SAndroid Build Coastguard Worker const unsigned char *sdata = NULL;
481*6236dae4SAndroid Build Coastguard Worker size_t slen = 0;
482*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
483*6236dae4SAndroid Build Coastguard Worker
484*6236dae4SAndroid Build Coastguard Worker Curl_ssl_sessionid_lock(data);
485*6236dae4SAndroid Build Coastguard Worker if(!Curl_ssl_getsessionid(cf, data, peer, &psdata, &slen, NULL)) {
486*6236dae4SAndroid Build Coastguard Worker WOLFSSL_SESSION *session;
487*6236dae4SAndroid Build Coastguard Worker sdata = psdata;
488*6236dae4SAndroid Build Coastguard Worker session = wolfSSL_d2i_SSL_SESSION(NULL, &sdata, (long)slen);
489*6236dae4SAndroid Build Coastguard Worker if(session) {
490*6236dae4SAndroid Build Coastguard Worker int ret = wolfSSL_set_session(wss->handle, session);
491*6236dae4SAndroid Build Coastguard Worker if(ret != WOLFSSL_SUCCESS) {
492*6236dae4SAndroid Build Coastguard Worker Curl_ssl_delsessionid(data, psdata);
493*6236dae4SAndroid Build Coastguard Worker infof(data, "previous session not accepted (%d), "
494*6236dae4SAndroid Build Coastguard Worker "removing from cache", ret);
495*6236dae4SAndroid Build Coastguard Worker }
496*6236dae4SAndroid Build Coastguard Worker else
497*6236dae4SAndroid Build Coastguard Worker infof(data, "SSL reusing session ID");
498*6236dae4SAndroid Build Coastguard Worker wolfSSL_SESSION_free(session);
499*6236dae4SAndroid Build Coastguard Worker }
500*6236dae4SAndroid Build Coastguard Worker else {
501*6236dae4SAndroid Build Coastguard Worker failf(data, "could not decode previous session");
502*6236dae4SAndroid Build Coastguard Worker }
503*6236dae4SAndroid Build Coastguard Worker }
504*6236dae4SAndroid Build Coastguard Worker Curl_ssl_sessionid_unlock(data);
505*6236dae4SAndroid Build Coastguard Worker return result;
506*6236dae4SAndroid Build Coastguard Worker }
507*6236dae4SAndroid Build Coastguard Worker
populate_x509_store(struct Curl_cfilter * cf,struct Curl_easy * data,WOLFSSL_X509_STORE * store,struct wolfssl_ctx * wssl)508*6236dae4SAndroid Build Coastguard Worker static CURLcode populate_x509_store(struct Curl_cfilter *cf,
509*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
510*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *store,
511*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *wssl)
512*6236dae4SAndroid Build Coastguard Worker {
513*6236dae4SAndroid Build Coastguard Worker struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
514*6236dae4SAndroid Build Coastguard Worker const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
515*6236dae4SAndroid Build Coastguard Worker const char * const ssl_cafile =
516*6236dae4SAndroid Build Coastguard Worker /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
517*6236dae4SAndroid Build Coastguard Worker (ca_info_blob ? NULL : conn_config->CAfile);
518*6236dae4SAndroid Build Coastguard Worker const char * const ssl_capath = conn_config->CApath;
519*6236dae4SAndroid Build Coastguard Worker struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
520*6236dae4SAndroid Build Coastguard Worker bool imported_native_ca = FALSE;
521*6236dae4SAndroid Build Coastguard Worker
522*6236dae4SAndroid Build Coastguard Worker #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SYS_CA_CERTS)
523*6236dae4SAndroid Build Coastguard Worker /* load native CA certificates */
524*6236dae4SAndroid Build Coastguard Worker if(ssl_config->native_ca_store) {
525*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_CTX_load_system_CA_certs(wssl->ctx) != WOLFSSL_SUCCESS) {
526*6236dae4SAndroid Build Coastguard Worker infof(data, "error importing native CA store, continuing anyway");
527*6236dae4SAndroid Build Coastguard Worker }
528*6236dae4SAndroid Build Coastguard Worker else {
529*6236dae4SAndroid Build Coastguard Worker imported_native_ca = TRUE;
530*6236dae4SAndroid Build Coastguard Worker infof(data, "successfully imported native CA store");
531*6236dae4SAndroid Build Coastguard Worker wssl->x509_store_setup = TRUE;
532*6236dae4SAndroid Build Coastguard Worker }
533*6236dae4SAndroid Build Coastguard Worker }
534*6236dae4SAndroid Build Coastguard Worker #endif /* !NO_FILESYSTEM */
535*6236dae4SAndroid Build Coastguard Worker
536*6236dae4SAndroid Build Coastguard Worker /* load certificate blob */
537*6236dae4SAndroid Build Coastguard Worker if(ca_info_blob) {
538*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_CTX_load_verify_buffer(wssl->ctx, ca_info_blob->data,
539*6236dae4SAndroid Build Coastguard Worker (long)ca_info_blob->len,
540*6236dae4SAndroid Build Coastguard Worker WOLFSSL_FILETYPE_PEM) !=
541*6236dae4SAndroid Build Coastguard Worker WOLFSSL_SUCCESS) {
542*6236dae4SAndroid Build Coastguard Worker if(imported_native_ca) {
543*6236dae4SAndroid Build Coastguard Worker infof(data, "error importing CA certificate blob, continuing anyway");
544*6236dae4SAndroid Build Coastguard Worker }
545*6236dae4SAndroid Build Coastguard Worker else {
546*6236dae4SAndroid Build Coastguard Worker failf(data, "error importing CA certificate blob");
547*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CACERT_BADFILE;
548*6236dae4SAndroid Build Coastguard Worker }
549*6236dae4SAndroid Build Coastguard Worker }
550*6236dae4SAndroid Build Coastguard Worker else {
551*6236dae4SAndroid Build Coastguard Worker infof(data, "successfully imported CA certificate blob");
552*6236dae4SAndroid Build Coastguard Worker wssl->x509_store_setup = TRUE;
553*6236dae4SAndroid Build Coastguard Worker }
554*6236dae4SAndroid Build Coastguard Worker }
555*6236dae4SAndroid Build Coastguard Worker
556*6236dae4SAndroid Build Coastguard Worker #ifndef NO_FILESYSTEM
557*6236dae4SAndroid Build Coastguard Worker /* load trusted cacert from file if not blob */
558*6236dae4SAndroid Build Coastguard Worker
559*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "populate_x509_store, path=%s, blob=%d",
560*6236dae4SAndroid Build Coastguard Worker ssl_cafile ? ssl_cafile : "none", !!ca_info_blob);
561*6236dae4SAndroid Build Coastguard Worker if(!store)
562*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
563*6236dae4SAndroid Build Coastguard Worker
564*6236dae4SAndroid Build Coastguard Worker if((ssl_cafile || ssl_capath) && (!wssl->x509_store_setup)) {
565*6236dae4SAndroid Build Coastguard Worker int rc =
566*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_load_verify_locations_ex(wssl->ctx,
567*6236dae4SAndroid Build Coastguard Worker ssl_cafile,
568*6236dae4SAndroid Build Coastguard Worker ssl_capath,
569*6236dae4SAndroid Build Coastguard Worker WOLFSSL_LOAD_FLAG_IGNORE_ERR);
570*6236dae4SAndroid Build Coastguard Worker if(WOLFSSL_SUCCESS != rc) {
571*6236dae4SAndroid Build Coastguard Worker if(conn_config->verifypeer) {
572*6236dae4SAndroid Build Coastguard Worker /* Fail if we insist on successfully verifying the server. */
573*6236dae4SAndroid Build Coastguard Worker failf(data, "error setting certificate verify locations:"
574*6236dae4SAndroid Build Coastguard Worker " CAfile: %s CApath: %s",
575*6236dae4SAndroid Build Coastguard Worker ssl_cafile ? ssl_cafile : "none",
576*6236dae4SAndroid Build Coastguard Worker ssl_capath ? ssl_capath : "none");
577*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CACERT_BADFILE;
578*6236dae4SAndroid Build Coastguard Worker }
579*6236dae4SAndroid Build Coastguard Worker else {
580*6236dae4SAndroid Build Coastguard Worker /* Just continue with a warning if no strict certificate
581*6236dae4SAndroid Build Coastguard Worker verification is required. */
582*6236dae4SAndroid Build Coastguard Worker infof(data, "error setting certificate verify locations,"
583*6236dae4SAndroid Build Coastguard Worker " continuing anyway:");
584*6236dae4SAndroid Build Coastguard Worker }
585*6236dae4SAndroid Build Coastguard Worker }
586*6236dae4SAndroid Build Coastguard Worker else {
587*6236dae4SAndroid Build Coastguard Worker /* Everything is fine. */
588*6236dae4SAndroid Build Coastguard Worker infof(data, "successfully set certificate verify locations:");
589*6236dae4SAndroid Build Coastguard Worker }
590*6236dae4SAndroid Build Coastguard Worker infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
591*6236dae4SAndroid Build Coastguard Worker infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
592*6236dae4SAndroid Build Coastguard Worker }
593*6236dae4SAndroid Build Coastguard Worker #endif
594*6236dae4SAndroid Build Coastguard Worker (void)store;
595*6236dae4SAndroid Build Coastguard Worker wssl->x509_store_setup = TRUE;
596*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
597*6236dae4SAndroid Build Coastguard Worker }
598*6236dae4SAndroid Build Coastguard Worker
599*6236dae4SAndroid Build Coastguard Worker /* key to use at `multi->proto_hash` */
600*6236dae4SAndroid Build Coastguard Worker #define MPROTO_WSSL_X509_KEY "tls:wssl:x509:share"
601*6236dae4SAndroid Build Coastguard Worker
602*6236dae4SAndroid Build Coastguard Worker struct wssl_x509_share {
603*6236dae4SAndroid Build Coastguard Worker char *CAfile; /* CAfile path used to generate X509 store */
604*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *store; /* cached X509 store or NULL if none */
605*6236dae4SAndroid Build Coastguard Worker struct curltime time; /* when the cached store was created */
606*6236dae4SAndroid Build Coastguard Worker };
607*6236dae4SAndroid Build Coastguard Worker
wssl_x509_share_free(void * key,size_t key_len,void * p)608*6236dae4SAndroid Build Coastguard Worker static void wssl_x509_share_free(void *key, size_t key_len, void *p)
609*6236dae4SAndroid Build Coastguard Worker {
610*6236dae4SAndroid Build Coastguard Worker struct wssl_x509_share *share = p;
611*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(key_len == (sizeof(MPROTO_WSSL_X509_KEY)-1));
612*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(!memcmp(MPROTO_WSSL_X509_KEY, key, key_len));
613*6236dae4SAndroid Build Coastguard Worker (void)key;
614*6236dae4SAndroid Build Coastguard Worker (void)key_len;
615*6236dae4SAndroid Build Coastguard Worker if(share->store) {
616*6236dae4SAndroid Build Coastguard Worker wolfSSL_X509_STORE_free(share->store);
617*6236dae4SAndroid Build Coastguard Worker }
618*6236dae4SAndroid Build Coastguard Worker free(share->CAfile);
619*6236dae4SAndroid Build Coastguard Worker free(share);
620*6236dae4SAndroid Build Coastguard Worker }
621*6236dae4SAndroid Build Coastguard Worker
622*6236dae4SAndroid Build Coastguard Worker static bool
cached_x509_store_expired(const struct Curl_easy * data,const struct wssl_x509_share * mb)623*6236dae4SAndroid Build Coastguard Worker cached_x509_store_expired(const struct Curl_easy *data,
624*6236dae4SAndroid Build Coastguard Worker const struct wssl_x509_share *mb)
625*6236dae4SAndroid Build Coastguard Worker {
626*6236dae4SAndroid Build Coastguard Worker const struct ssl_general_config *cfg = &data->set.general_ssl;
627*6236dae4SAndroid Build Coastguard Worker struct curltime now = Curl_now();
628*6236dae4SAndroid Build Coastguard Worker timediff_t elapsed_ms = Curl_timediff(now, mb->time);
629*6236dae4SAndroid Build Coastguard Worker timediff_t timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000;
630*6236dae4SAndroid Build Coastguard Worker
631*6236dae4SAndroid Build Coastguard Worker if(timeout_ms < 0)
632*6236dae4SAndroid Build Coastguard Worker return FALSE;
633*6236dae4SAndroid Build Coastguard Worker
634*6236dae4SAndroid Build Coastguard Worker return elapsed_ms >= timeout_ms;
635*6236dae4SAndroid Build Coastguard Worker }
636*6236dae4SAndroid Build Coastguard Worker
637*6236dae4SAndroid Build Coastguard Worker static bool
cached_x509_store_different(struct Curl_cfilter * cf,const struct wssl_x509_share * mb)638*6236dae4SAndroid Build Coastguard Worker cached_x509_store_different(struct Curl_cfilter *cf,
639*6236dae4SAndroid Build Coastguard Worker const struct wssl_x509_share *mb)
640*6236dae4SAndroid Build Coastguard Worker {
641*6236dae4SAndroid Build Coastguard Worker struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
642*6236dae4SAndroid Build Coastguard Worker if(!mb->CAfile || !conn_config->CAfile)
643*6236dae4SAndroid Build Coastguard Worker return mb->CAfile != conn_config->CAfile;
644*6236dae4SAndroid Build Coastguard Worker
645*6236dae4SAndroid Build Coastguard Worker return strcmp(mb->CAfile, conn_config->CAfile);
646*6236dae4SAndroid Build Coastguard Worker }
647*6236dae4SAndroid Build Coastguard Worker
get_cached_x509_store(struct Curl_cfilter * cf,const struct Curl_easy * data)648*6236dae4SAndroid Build Coastguard Worker static WOLFSSL_X509_STORE *get_cached_x509_store(struct Curl_cfilter *cf,
649*6236dae4SAndroid Build Coastguard Worker const struct Curl_easy *data)
650*6236dae4SAndroid Build Coastguard Worker {
651*6236dae4SAndroid Build Coastguard Worker struct Curl_multi *multi = data->multi;
652*6236dae4SAndroid Build Coastguard Worker struct wssl_x509_share *share;
653*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *store = NULL;
654*6236dae4SAndroid Build Coastguard Worker
655*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(multi);
656*6236dae4SAndroid Build Coastguard Worker share = multi ? Curl_hash_pick(&multi->proto_hash,
657*6236dae4SAndroid Build Coastguard Worker (void *)MPROTO_WSSL_X509_KEY,
658*6236dae4SAndroid Build Coastguard Worker sizeof(MPROTO_WSSL_X509_KEY)-1) : NULL;
659*6236dae4SAndroid Build Coastguard Worker if(share && share->store &&
660*6236dae4SAndroid Build Coastguard Worker !cached_x509_store_expired(data, share) &&
661*6236dae4SAndroid Build Coastguard Worker !cached_x509_store_different(cf, share)) {
662*6236dae4SAndroid Build Coastguard Worker store = share->store;
663*6236dae4SAndroid Build Coastguard Worker }
664*6236dae4SAndroid Build Coastguard Worker
665*6236dae4SAndroid Build Coastguard Worker return store;
666*6236dae4SAndroid Build Coastguard Worker }
667*6236dae4SAndroid Build Coastguard Worker
set_cached_x509_store(struct Curl_cfilter * cf,const struct Curl_easy * data,WOLFSSL_X509_STORE * store)668*6236dae4SAndroid Build Coastguard Worker static void set_cached_x509_store(struct Curl_cfilter *cf,
669*6236dae4SAndroid Build Coastguard Worker const struct Curl_easy *data,
670*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *store)
671*6236dae4SAndroid Build Coastguard Worker {
672*6236dae4SAndroid Build Coastguard Worker struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
673*6236dae4SAndroid Build Coastguard Worker struct Curl_multi *multi = data->multi;
674*6236dae4SAndroid Build Coastguard Worker struct wssl_x509_share *share;
675*6236dae4SAndroid Build Coastguard Worker
676*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(multi);
677*6236dae4SAndroid Build Coastguard Worker if(!multi)
678*6236dae4SAndroid Build Coastguard Worker return;
679*6236dae4SAndroid Build Coastguard Worker share = Curl_hash_pick(&multi->proto_hash,
680*6236dae4SAndroid Build Coastguard Worker (void *)MPROTO_WSSL_X509_KEY,
681*6236dae4SAndroid Build Coastguard Worker sizeof(MPROTO_WSSL_X509_KEY)-1);
682*6236dae4SAndroid Build Coastguard Worker
683*6236dae4SAndroid Build Coastguard Worker if(!share) {
684*6236dae4SAndroid Build Coastguard Worker share = calloc(1, sizeof(*share));
685*6236dae4SAndroid Build Coastguard Worker if(!share)
686*6236dae4SAndroid Build Coastguard Worker return;
687*6236dae4SAndroid Build Coastguard Worker if(!Curl_hash_add2(&multi->proto_hash,
688*6236dae4SAndroid Build Coastguard Worker (void *)MPROTO_WSSL_X509_KEY,
689*6236dae4SAndroid Build Coastguard Worker sizeof(MPROTO_WSSL_X509_KEY)-1,
690*6236dae4SAndroid Build Coastguard Worker share, wssl_x509_share_free)) {
691*6236dae4SAndroid Build Coastguard Worker free(share);
692*6236dae4SAndroid Build Coastguard Worker return;
693*6236dae4SAndroid Build Coastguard Worker }
694*6236dae4SAndroid Build Coastguard Worker }
695*6236dae4SAndroid Build Coastguard Worker
696*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_X509_STORE_up_ref(store)) {
697*6236dae4SAndroid Build Coastguard Worker char *CAfile = NULL;
698*6236dae4SAndroid Build Coastguard Worker
699*6236dae4SAndroid Build Coastguard Worker if(conn_config->CAfile) {
700*6236dae4SAndroid Build Coastguard Worker CAfile = strdup(conn_config->CAfile);
701*6236dae4SAndroid Build Coastguard Worker if(!CAfile) {
702*6236dae4SAndroid Build Coastguard Worker wolfSSL_X509_STORE_free(store);
703*6236dae4SAndroid Build Coastguard Worker return;
704*6236dae4SAndroid Build Coastguard Worker }
705*6236dae4SAndroid Build Coastguard Worker }
706*6236dae4SAndroid Build Coastguard Worker
707*6236dae4SAndroid Build Coastguard Worker if(share->store) {
708*6236dae4SAndroid Build Coastguard Worker wolfSSL_X509_STORE_free(share->store);
709*6236dae4SAndroid Build Coastguard Worker free(share->CAfile);
710*6236dae4SAndroid Build Coastguard Worker }
711*6236dae4SAndroid Build Coastguard Worker
712*6236dae4SAndroid Build Coastguard Worker share->time = Curl_now();
713*6236dae4SAndroid Build Coastguard Worker share->store = store;
714*6236dae4SAndroid Build Coastguard Worker share->CAfile = CAfile;
715*6236dae4SAndroid Build Coastguard Worker }
716*6236dae4SAndroid Build Coastguard Worker }
717*6236dae4SAndroid Build Coastguard Worker
Curl_wssl_setup_x509_store(struct Curl_cfilter * cf,struct Curl_easy * data,struct wolfssl_ctx * wssl)718*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
719*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
720*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *wssl)
721*6236dae4SAndroid Build Coastguard Worker {
722*6236dae4SAndroid Build Coastguard Worker struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
723*6236dae4SAndroid Build Coastguard Worker struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
724*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
725*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *cached_store;
726*6236dae4SAndroid Build Coastguard Worker bool cache_criteria_met;
727*6236dae4SAndroid Build Coastguard Worker
728*6236dae4SAndroid Build Coastguard Worker /* Consider the X509 store cacheable if it comes exclusively from a CAfile,
729*6236dae4SAndroid Build Coastguard Worker or no source is provided and we are falling back to wolfSSL's built-in
730*6236dae4SAndroid Build Coastguard Worker default. */
731*6236dae4SAndroid Build Coastguard Worker cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) &&
732*6236dae4SAndroid Build Coastguard Worker conn_config->verifypeer &&
733*6236dae4SAndroid Build Coastguard Worker !conn_config->CApath &&
734*6236dae4SAndroid Build Coastguard Worker !conn_config->ca_info_blob &&
735*6236dae4SAndroid Build Coastguard Worker !ssl_config->primary.CRLfile &&
736*6236dae4SAndroid Build Coastguard Worker !ssl_config->native_ca_store;
737*6236dae4SAndroid Build Coastguard Worker
738*6236dae4SAndroid Build Coastguard Worker cached_store = cache_criteria_met ? get_cached_x509_store(cf, data) : NULL;
739*6236dae4SAndroid Build Coastguard Worker if(cached_store && wolfSSL_CTX_get_cert_store(wssl->ctx) == cached_store) {
740*6236dae4SAndroid Build Coastguard Worker /* The cached store is already in use, do nothing. */
741*6236dae4SAndroid Build Coastguard Worker }
742*6236dae4SAndroid Build Coastguard Worker else if(cached_store && wolfSSL_X509_STORE_up_ref(cached_store)) {
743*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_set_cert_store(wssl->ctx, cached_store);
744*6236dae4SAndroid Build Coastguard Worker }
745*6236dae4SAndroid Build Coastguard Worker else if(cache_criteria_met) {
746*6236dae4SAndroid Build Coastguard Worker /* wolfSSL's initial store in CTX is not shareable by default.
747*6236dae4SAndroid Build Coastguard Worker * Make a new one, suitable for adding to the cache. See #14278 */
748*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *store = wolfSSL_X509_STORE_new();
749*6236dae4SAndroid Build Coastguard Worker if(!store) {
750*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: could not create a X509 store");
751*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
752*6236dae4SAndroid Build Coastguard Worker }
753*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_set_cert_store(wssl->ctx, store);
754*6236dae4SAndroid Build Coastguard Worker
755*6236dae4SAndroid Build Coastguard Worker result = populate_x509_store(cf, data, store, wssl);
756*6236dae4SAndroid Build Coastguard Worker if(!result) {
757*6236dae4SAndroid Build Coastguard Worker set_cached_x509_store(cf, data, store);
758*6236dae4SAndroid Build Coastguard Worker }
759*6236dae4SAndroid Build Coastguard Worker }
760*6236dae4SAndroid Build Coastguard Worker else {
761*6236dae4SAndroid Build Coastguard Worker /* We never share the CTX's store, use it. */
762*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509_STORE *store = wolfSSL_CTX_get_cert_store(wssl->ctx);
763*6236dae4SAndroid Build Coastguard Worker result = populate_x509_store(cf, data, store, wssl);
764*6236dae4SAndroid Build Coastguard Worker }
765*6236dae4SAndroid Build Coastguard Worker
766*6236dae4SAndroid Build Coastguard Worker return result;
767*6236dae4SAndroid Build Coastguard Worker }
768*6236dae4SAndroid Build Coastguard Worker
769*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_TLS13
770*6236dae4SAndroid Build Coastguard Worker static CURLcode
wssl_add_default_ciphers(bool tls13,struct dynbuf * buf)771*6236dae4SAndroid Build Coastguard Worker wssl_add_default_ciphers(bool tls13, struct dynbuf *buf)
772*6236dae4SAndroid Build Coastguard Worker {
773*6236dae4SAndroid Build Coastguard Worker int i;
774*6236dae4SAndroid Build Coastguard Worker char *str;
775*6236dae4SAndroid Build Coastguard Worker
776*6236dae4SAndroid Build Coastguard Worker for(i = 0; (str = wolfSSL_get_cipher_list(i)); i++) {
777*6236dae4SAndroid Build Coastguard Worker size_t n;
778*6236dae4SAndroid Build Coastguard Worker if((strncmp(str, "TLS13", 5) == 0) != tls13)
779*6236dae4SAndroid Build Coastguard Worker continue;
780*6236dae4SAndroid Build Coastguard Worker
781*6236dae4SAndroid Build Coastguard Worker /* if there already is data in the string, add colon separator */
782*6236dae4SAndroid Build Coastguard Worker if(Curl_dyn_len(buf)) {
783*6236dae4SAndroid Build Coastguard Worker CURLcode result = Curl_dyn_addn(buf, ":", 1);
784*6236dae4SAndroid Build Coastguard Worker if(result)
785*6236dae4SAndroid Build Coastguard Worker return result;
786*6236dae4SAndroid Build Coastguard Worker }
787*6236dae4SAndroid Build Coastguard Worker
788*6236dae4SAndroid Build Coastguard Worker n = strlen(str);
789*6236dae4SAndroid Build Coastguard Worker if(Curl_dyn_addn(buf, str, n))
790*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
791*6236dae4SAndroid Build Coastguard Worker }
792*6236dae4SAndroid Build Coastguard Worker
793*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
794*6236dae4SAndroid Build Coastguard Worker }
795*6236dae4SAndroid Build Coastguard Worker #endif
796*6236dae4SAndroid Build Coastguard Worker
797*6236dae4SAndroid Build Coastguard Worker /* 4.2.0 (2019) */
798*6236dae4SAndroid Build Coastguard Worker #if LIBWOLFSSL_VERSION_HEX < 0x04002000 || !defined(OPENSSL_EXTRA)
799*6236dae4SAndroid Build Coastguard Worker static int
wssl_legacy_CTX_set_min_proto_version(WOLFSSL_CTX * ctx,int version)800*6236dae4SAndroid Build Coastguard Worker wssl_legacy_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
801*6236dae4SAndroid Build Coastguard Worker {
802*6236dae4SAndroid Build Coastguard Worker int res;
803*6236dae4SAndroid Build Coastguard Worker switch(version) {
804*6236dae4SAndroid Build Coastguard Worker default:
805*6236dae4SAndroid Build Coastguard Worker case TLS1_VERSION:
806*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1);
807*6236dae4SAndroid Build Coastguard Worker if(res == WOLFSSL_SUCCESS)
808*6236dae4SAndroid Build Coastguard Worker return res;
809*6236dae4SAndroid Build Coastguard Worker FALLTHROUGH();
810*6236dae4SAndroid Build Coastguard Worker case TLS1_1_VERSION:
811*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_1);
812*6236dae4SAndroid Build Coastguard Worker if(res == WOLFSSL_SUCCESS)
813*6236dae4SAndroid Build Coastguard Worker return res;
814*6236dae4SAndroid Build Coastguard Worker FALLTHROUGH();
815*6236dae4SAndroid Build Coastguard Worker case TLS1_2_VERSION:
816*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_2);
817*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_TLS13
818*6236dae4SAndroid Build Coastguard Worker if(res == WOLFSSL_SUCCESS)
819*6236dae4SAndroid Build Coastguard Worker return res;
820*6236dae4SAndroid Build Coastguard Worker FALLTHROUGH();
821*6236dae4SAndroid Build Coastguard Worker case TLS1_3_VERSION:
822*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_3);
823*6236dae4SAndroid Build Coastguard Worker #endif
824*6236dae4SAndroid Build Coastguard Worker }
825*6236dae4SAndroid Build Coastguard Worker return res;
826*6236dae4SAndroid Build Coastguard Worker }
827*6236dae4SAndroid Build Coastguard Worker static int
wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX * ctx,int version)828*6236dae4SAndroid Build Coastguard Worker wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
829*6236dae4SAndroid Build Coastguard Worker {
830*6236dae4SAndroid Build Coastguard Worker (void) ctx, (void) version;
831*6236dae4SAndroid Build Coastguard Worker return WOLFSSL_NOT_IMPLEMENTED;
832*6236dae4SAndroid Build Coastguard Worker }
833*6236dae4SAndroid Build Coastguard Worker #define wolfSSL_CTX_set_min_proto_version wssl_legacy_CTX_set_min_proto_version
834*6236dae4SAndroid Build Coastguard Worker #define wolfSSL_CTX_set_max_proto_version wssl_legacy_CTX_set_max_proto_version
835*6236dae4SAndroid Build Coastguard Worker #endif
836*6236dae4SAndroid Build Coastguard Worker
837*6236dae4SAndroid Build Coastguard Worker /*
838*6236dae4SAndroid Build Coastguard Worker * This function loads all the client/CA certificates and CRLs. Setup the TLS
839*6236dae4SAndroid Build Coastguard Worker * layer and do all necessary magic.
840*6236dae4SAndroid Build Coastguard Worker */
841*6236dae4SAndroid Build Coastguard Worker static CURLcode
wolfssl_connect_step1(struct Curl_cfilter * cf,struct Curl_easy * data)842*6236dae4SAndroid Build Coastguard Worker wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
843*6236dae4SAndroid Build Coastguard Worker {
844*6236dae4SAndroid Build Coastguard Worker int res;
845*6236dae4SAndroid Build Coastguard Worker char *curves;
846*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
847*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
848*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
849*6236dae4SAndroid Build Coastguard Worker struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
850*6236dae4SAndroid Build Coastguard Worker const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
851*6236dae4SAndroid Build Coastguard Worker WOLFSSL_METHOD* req_method = NULL;
852*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_HAVE_KYBER
853*6236dae4SAndroid Build Coastguard Worker word16 pqkem = 0;
854*6236dae4SAndroid Build Coastguard Worker size_t idx = 0;
855*6236dae4SAndroid Build Coastguard Worker #endif
856*6236dae4SAndroid Build Coastguard Worker
857*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(backend);
858*6236dae4SAndroid Build Coastguard Worker
859*6236dae4SAndroid Build Coastguard Worker if(connssl->state == ssl_connection_complete)
860*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
861*6236dae4SAndroid Build Coastguard Worker
862*6236dae4SAndroid Build Coastguard Worker #if LIBWOLFSSL_VERSION_HEX < 0x04002000 /* 4.2.0 (2019) */
863*6236dae4SAndroid Build Coastguard Worker req_method = wolfSSLv23_client_method();
864*6236dae4SAndroid Build Coastguard Worker #else
865*6236dae4SAndroid Build Coastguard Worker req_method = wolfTLS_client_method();
866*6236dae4SAndroid Build Coastguard Worker #endif
867*6236dae4SAndroid Build Coastguard Worker if(!req_method) {
868*6236dae4SAndroid Build Coastguard Worker failf(data, "wolfSSL: could not create a client method");
869*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
870*6236dae4SAndroid Build Coastguard Worker }
871*6236dae4SAndroid Build Coastguard Worker
872*6236dae4SAndroid Build Coastguard Worker if(backend->ctx)
873*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_free(backend->ctx);
874*6236dae4SAndroid Build Coastguard Worker
875*6236dae4SAndroid Build Coastguard Worker backend->ctx = wolfSSL_CTX_new(req_method);
876*6236dae4SAndroid Build Coastguard Worker if(!backend->ctx) {
877*6236dae4SAndroid Build Coastguard Worker failf(data, "wolfSSL: could not create a context");
878*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
879*6236dae4SAndroid Build Coastguard Worker }
880*6236dae4SAndroid Build Coastguard Worker
881*6236dae4SAndroid Build Coastguard Worker switch(conn_config->version) {
882*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_DEFAULT:
883*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_TLSv1:
884*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_TLSv1_0:
885*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_VERSION);
886*6236dae4SAndroid Build Coastguard Worker break;
887*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_TLSv1_1:
888*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_1_VERSION);
889*6236dae4SAndroid Build Coastguard Worker break;
890*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_TLSv1_2:
891*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_2_VERSION);
892*6236dae4SAndroid Build Coastguard Worker break;
893*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_TLS13
894*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_TLSv1_3:
895*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_3_VERSION);
896*6236dae4SAndroid Build Coastguard Worker break;
897*6236dae4SAndroid Build Coastguard Worker #endif
898*6236dae4SAndroid Build Coastguard Worker default:
899*6236dae4SAndroid Build Coastguard Worker failf(data, "wolfSSL: unsupported minimum TLS version value");
900*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
901*6236dae4SAndroid Build Coastguard Worker }
902*6236dae4SAndroid Build Coastguard Worker if(res != WOLFSSL_SUCCESS) {
903*6236dae4SAndroid Build Coastguard Worker failf(data, "wolfSSL: failed set the minimum TLS version");
904*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
905*6236dae4SAndroid Build Coastguard Worker }
906*6236dae4SAndroid Build Coastguard Worker
907*6236dae4SAndroid Build Coastguard Worker switch(conn_config->version_max) {
908*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_TLS13
909*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_MAX_TLSv1_3:
910*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
911*6236dae4SAndroid Build Coastguard Worker break;
912*6236dae4SAndroid Build Coastguard Worker #endif
913*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_MAX_TLSv1_2:
914*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_2_VERSION);
915*6236dae4SAndroid Build Coastguard Worker break;
916*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_MAX_TLSv1_1:
917*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_1_VERSION);
918*6236dae4SAndroid Build Coastguard Worker break;
919*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_MAX_TLSv1_0:
920*6236dae4SAndroid Build Coastguard Worker res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_VERSION);
921*6236dae4SAndroid Build Coastguard Worker break;
922*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_MAX_DEFAULT:
923*6236dae4SAndroid Build Coastguard Worker case CURL_SSLVERSION_MAX_NONE:
924*6236dae4SAndroid Build Coastguard Worker res = WOLFSSL_SUCCESS;
925*6236dae4SAndroid Build Coastguard Worker break;
926*6236dae4SAndroid Build Coastguard Worker default:
927*6236dae4SAndroid Build Coastguard Worker failf(data, "wolfSSL: unsupported maximum TLS version value");
928*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
929*6236dae4SAndroid Build Coastguard Worker }
930*6236dae4SAndroid Build Coastguard Worker if(res != WOLFSSL_SUCCESS) {
931*6236dae4SAndroid Build Coastguard Worker failf(data, "wolfSSL: failed set the maximum TLS version");
932*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
933*6236dae4SAndroid Build Coastguard Worker }
934*6236dae4SAndroid Build Coastguard Worker
935*6236dae4SAndroid Build Coastguard Worker #ifndef WOLFSSL_TLS13
936*6236dae4SAndroid Build Coastguard Worker {
937*6236dae4SAndroid Build Coastguard Worker char *ciphers = conn_config->cipher_list;
938*6236dae4SAndroid Build Coastguard Worker if(ciphers) {
939*6236dae4SAndroid Build Coastguard Worker if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
940*6236dae4SAndroid Build Coastguard Worker failf(data, "failed setting cipher list: %s", ciphers);
941*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CIPHER;
942*6236dae4SAndroid Build Coastguard Worker }
943*6236dae4SAndroid Build Coastguard Worker infof(data, "Cipher selection: %s", ciphers);
944*6236dae4SAndroid Build Coastguard Worker }
945*6236dae4SAndroid Build Coastguard Worker }
946*6236dae4SAndroid Build Coastguard Worker #else
947*6236dae4SAndroid Build Coastguard Worker #define MAX_CIPHER_LEN 4096
948*6236dae4SAndroid Build Coastguard Worker if(conn_config->cipher_list || conn_config->cipher_list13) {
949*6236dae4SAndroid Build Coastguard Worker const char *ciphers12 = conn_config->cipher_list;
950*6236dae4SAndroid Build Coastguard Worker const char *ciphers13 = conn_config->cipher_list13;
951*6236dae4SAndroid Build Coastguard Worker struct dynbuf c;
952*6236dae4SAndroid Build Coastguard Worker CURLcode result;
953*6236dae4SAndroid Build Coastguard Worker Curl_dyn_init(&c, MAX_CIPHER_LEN);
954*6236dae4SAndroid Build Coastguard Worker
955*6236dae4SAndroid Build Coastguard Worker if(ciphers13)
956*6236dae4SAndroid Build Coastguard Worker result = Curl_dyn_add(&c, ciphers13);
957*6236dae4SAndroid Build Coastguard Worker else
958*6236dae4SAndroid Build Coastguard Worker result = wssl_add_default_ciphers(TRUE, &c);
959*6236dae4SAndroid Build Coastguard Worker
960*6236dae4SAndroid Build Coastguard Worker if(!result) {
961*6236dae4SAndroid Build Coastguard Worker if(ciphers12) {
962*6236dae4SAndroid Build Coastguard Worker if(Curl_dyn_len(&c))
963*6236dae4SAndroid Build Coastguard Worker result = Curl_dyn_addn(&c, ":", 1);
964*6236dae4SAndroid Build Coastguard Worker if(!result)
965*6236dae4SAndroid Build Coastguard Worker result = Curl_dyn_add(&c, ciphers12);
966*6236dae4SAndroid Build Coastguard Worker }
967*6236dae4SAndroid Build Coastguard Worker else
968*6236dae4SAndroid Build Coastguard Worker result = wssl_add_default_ciphers(FALSE, &c);
969*6236dae4SAndroid Build Coastguard Worker }
970*6236dae4SAndroid Build Coastguard Worker if(result)
971*6236dae4SAndroid Build Coastguard Worker return result;
972*6236dae4SAndroid Build Coastguard Worker
973*6236dae4SAndroid Build Coastguard Worker if(!wolfSSL_CTX_set_cipher_list(backend->ctx, Curl_dyn_ptr(&c))) {
974*6236dae4SAndroid Build Coastguard Worker failf(data, "failed setting cipher list: %s", Curl_dyn_ptr(&c));
975*6236dae4SAndroid Build Coastguard Worker Curl_dyn_free(&c);
976*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CIPHER;
977*6236dae4SAndroid Build Coastguard Worker }
978*6236dae4SAndroid Build Coastguard Worker infof(data, "Cipher selection: %s", Curl_dyn_ptr(&c));
979*6236dae4SAndroid Build Coastguard Worker Curl_dyn_free(&c);
980*6236dae4SAndroid Build Coastguard Worker }
981*6236dae4SAndroid Build Coastguard Worker #endif
982*6236dae4SAndroid Build Coastguard Worker
983*6236dae4SAndroid Build Coastguard Worker curves = conn_config->curves;
984*6236dae4SAndroid Build Coastguard Worker if(curves) {
985*6236dae4SAndroid Build Coastguard Worker
986*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_HAVE_KYBER
987*6236dae4SAndroid Build Coastguard Worker for(idx = 0; gnm[idx].name != NULL; idx++) {
988*6236dae4SAndroid Build Coastguard Worker if(strncmp(curves, gnm[idx].name, strlen(gnm[idx].name)) == 0) {
989*6236dae4SAndroid Build Coastguard Worker pqkem = gnm[idx].group;
990*6236dae4SAndroid Build Coastguard Worker break;
991*6236dae4SAndroid Build Coastguard Worker }
992*6236dae4SAndroid Build Coastguard Worker }
993*6236dae4SAndroid Build Coastguard Worker
994*6236dae4SAndroid Build Coastguard Worker if(pqkem == 0)
995*6236dae4SAndroid Build Coastguard Worker #endif
996*6236dae4SAndroid Build Coastguard Worker {
997*6236dae4SAndroid Build Coastguard Worker if(!wolfSSL_CTX_set1_curves_list(backend->ctx, curves)) {
998*6236dae4SAndroid Build Coastguard Worker failf(data, "failed setting curves list: '%s'", curves);
999*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CIPHER;
1000*6236dae4SAndroid Build Coastguard Worker }
1001*6236dae4SAndroid Build Coastguard Worker }
1002*6236dae4SAndroid Build Coastguard Worker }
1003*6236dae4SAndroid Build Coastguard Worker
1004*6236dae4SAndroid Build Coastguard Worker /* Load the client certificate, and private key */
1005*6236dae4SAndroid Build Coastguard Worker #ifndef NO_FILESYSTEM
1006*6236dae4SAndroid Build Coastguard Worker if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) {
1007*6236dae4SAndroid Build Coastguard Worker const char *cert_file = ssl_config->primary.clientcert;
1008*6236dae4SAndroid Build Coastguard Worker const char *key_file = ssl_config->key;
1009*6236dae4SAndroid Build Coastguard Worker const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
1010*6236dae4SAndroid Build Coastguard Worker const struct curl_blob *key_blob = ssl_config->key_blob;
1011*6236dae4SAndroid Build Coastguard Worker int file_type = wolfssl_do_file_type(ssl_config->cert_type);
1012*6236dae4SAndroid Build Coastguard Worker int rc;
1013*6236dae4SAndroid Build Coastguard Worker
1014*6236dae4SAndroid Build Coastguard Worker switch(file_type) {
1015*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_FILETYPE_PEM:
1016*6236dae4SAndroid Build Coastguard Worker rc = cert_blob ?
1017*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_use_certificate_chain_buffer(backend->ctx,
1018*6236dae4SAndroid Build Coastguard Worker cert_blob->data,
1019*6236dae4SAndroid Build Coastguard Worker (long)cert_blob->len) :
1020*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_use_certificate_chain_file(backend->ctx, cert_file);
1021*6236dae4SAndroid Build Coastguard Worker break;
1022*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_FILETYPE_ASN1:
1023*6236dae4SAndroid Build Coastguard Worker rc = cert_blob ?
1024*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_use_certificate_buffer(backend->ctx, cert_blob->data,
1025*6236dae4SAndroid Build Coastguard Worker (long)cert_blob->len, file_type) :
1026*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_use_certificate_file(backend->ctx, cert_file, file_type);
1027*6236dae4SAndroid Build Coastguard Worker break;
1028*6236dae4SAndroid Build Coastguard Worker default:
1029*6236dae4SAndroid Build Coastguard Worker failf(data, "unknown cert type");
1030*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_FUNCTION_ARGUMENT;
1031*6236dae4SAndroid Build Coastguard Worker }
1032*6236dae4SAndroid Build Coastguard Worker if(rc != 1) {
1033*6236dae4SAndroid Build Coastguard Worker failf(data, "unable to use client certificate");
1034*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1035*6236dae4SAndroid Build Coastguard Worker }
1036*6236dae4SAndroid Build Coastguard Worker
1037*6236dae4SAndroid Build Coastguard Worker if(!key_blob && !key_file) {
1038*6236dae4SAndroid Build Coastguard Worker key_blob = cert_blob;
1039*6236dae4SAndroid Build Coastguard Worker key_file = cert_file;
1040*6236dae4SAndroid Build Coastguard Worker }
1041*6236dae4SAndroid Build Coastguard Worker else
1042*6236dae4SAndroid Build Coastguard Worker file_type = wolfssl_do_file_type(ssl_config->key_type);
1043*6236dae4SAndroid Build Coastguard Worker
1044*6236dae4SAndroid Build Coastguard Worker rc = key_blob ?
1045*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_use_PrivateKey_buffer(backend->ctx, key_blob->data,
1046*6236dae4SAndroid Build Coastguard Worker (long)key_blob->len, file_type) :
1047*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_use_PrivateKey_file(backend->ctx, key_file, file_type);
1048*6236dae4SAndroid Build Coastguard Worker if(rc != 1) {
1049*6236dae4SAndroid Build Coastguard Worker failf(data, "unable to set private key");
1050*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1051*6236dae4SAndroid Build Coastguard Worker }
1052*6236dae4SAndroid Build Coastguard Worker }
1053*6236dae4SAndroid Build Coastguard Worker #else /* NO_FILESYSTEM */
1054*6236dae4SAndroid Build Coastguard Worker if(ssl_config->primary.cert_blob) {
1055*6236dae4SAndroid Build Coastguard Worker const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
1056*6236dae4SAndroid Build Coastguard Worker const struct curl_blob *key_blob = ssl_config->key_blob;
1057*6236dae4SAndroid Build Coastguard Worker int file_type = wolfssl_do_file_type(ssl_config->cert_type);
1058*6236dae4SAndroid Build Coastguard Worker int rc;
1059*6236dae4SAndroid Build Coastguard Worker
1060*6236dae4SAndroid Build Coastguard Worker switch(file_type) {
1061*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_FILETYPE_PEM:
1062*6236dae4SAndroid Build Coastguard Worker rc = wolfSSL_CTX_use_certificate_chain_buffer(backend->ctx,
1063*6236dae4SAndroid Build Coastguard Worker cert_blob->data,
1064*6236dae4SAndroid Build Coastguard Worker (long)cert_blob->len);
1065*6236dae4SAndroid Build Coastguard Worker break;
1066*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_FILETYPE_ASN1:
1067*6236dae4SAndroid Build Coastguard Worker rc = wolfSSL_CTX_use_certificate_buffer(backend->ctx, cert_blob->data,
1068*6236dae4SAndroid Build Coastguard Worker (long)cert_blob->len, file_type);
1069*6236dae4SAndroid Build Coastguard Worker break;
1070*6236dae4SAndroid Build Coastguard Worker default:
1071*6236dae4SAndroid Build Coastguard Worker failf(data, "unknown cert type");
1072*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_FUNCTION_ARGUMENT;
1073*6236dae4SAndroid Build Coastguard Worker }
1074*6236dae4SAndroid Build Coastguard Worker if(rc != 1) {
1075*6236dae4SAndroid Build Coastguard Worker failf(data, "unable to use client certificate");
1076*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1077*6236dae4SAndroid Build Coastguard Worker }
1078*6236dae4SAndroid Build Coastguard Worker
1079*6236dae4SAndroid Build Coastguard Worker if(!key_blob)
1080*6236dae4SAndroid Build Coastguard Worker key_blob = cert_blob;
1081*6236dae4SAndroid Build Coastguard Worker else
1082*6236dae4SAndroid Build Coastguard Worker file_type = wolfssl_do_file_type(ssl_config->key_type);
1083*6236dae4SAndroid Build Coastguard Worker
1084*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_CTX_use_PrivateKey_buffer(backend->ctx, key_blob->data,
1085*6236dae4SAndroid Build Coastguard Worker (long)key_blob->len,
1086*6236dae4SAndroid Build Coastguard Worker file_type) != 1) {
1087*6236dae4SAndroid Build Coastguard Worker failf(data, "unable to set private key");
1088*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1089*6236dae4SAndroid Build Coastguard Worker }
1090*6236dae4SAndroid Build Coastguard Worker }
1091*6236dae4SAndroid Build Coastguard Worker #endif /* !NO_FILESYSTEM */
1092*6236dae4SAndroid Build Coastguard Worker
1093*6236dae4SAndroid Build Coastguard Worker /* SSL always tries to verify the peer, this only says whether it should
1094*6236dae4SAndroid Build Coastguard Worker * fail to connect if the verification fails, or if it should continue
1095*6236dae4SAndroid Build Coastguard Worker * anyway. In the latter case the result of the verification is checked with
1096*6236dae4SAndroid Build Coastguard Worker * SSL_get_verify_result() below. */
1097*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_set_verify(backend->ctx,
1098*6236dae4SAndroid Build Coastguard Worker conn_config->verifypeer ? WOLFSSL_VERIFY_PEER :
1099*6236dae4SAndroid Build Coastguard Worker WOLFSSL_VERIFY_NONE, NULL);
1100*6236dae4SAndroid Build Coastguard Worker
1101*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SNI
1102*6236dae4SAndroid Build Coastguard Worker if(connssl->peer.sni) {
1103*6236dae4SAndroid Build Coastguard Worker size_t sni_len = strlen(connssl->peer.sni);
1104*6236dae4SAndroid Build Coastguard Worker if((sni_len < USHRT_MAX)) {
1105*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME,
1106*6236dae4SAndroid Build Coastguard Worker connssl->peer.sni,
1107*6236dae4SAndroid Build Coastguard Worker (unsigned short)sni_len) != 1) {
1108*6236dae4SAndroid Build Coastguard Worker failf(data, "Failed to set SNI");
1109*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1110*6236dae4SAndroid Build Coastguard Worker }
1111*6236dae4SAndroid Build Coastguard Worker }
1112*6236dae4SAndroid Build Coastguard Worker }
1113*6236dae4SAndroid Build Coastguard Worker #endif
1114*6236dae4SAndroid Build Coastguard Worker
1115*6236dae4SAndroid Build Coastguard Worker /* give application a chance to interfere with SSL set up. */
1116*6236dae4SAndroid Build Coastguard Worker if(data->set.ssl.fsslctx) {
1117*6236dae4SAndroid Build Coastguard Worker CURLcode result;
1118*6236dae4SAndroid Build Coastguard Worker if(!backend->x509_store_setup) {
1119*6236dae4SAndroid Build Coastguard Worker result = Curl_wssl_setup_x509_store(cf, data, backend);
1120*6236dae4SAndroid Build Coastguard Worker if(result)
1121*6236dae4SAndroid Build Coastguard Worker return result;
1122*6236dae4SAndroid Build Coastguard Worker }
1123*6236dae4SAndroid Build Coastguard Worker result = (*data->set.ssl.fsslctx)(data, backend->ctx,
1124*6236dae4SAndroid Build Coastguard Worker data->set.ssl.fsslctxp);
1125*6236dae4SAndroid Build Coastguard Worker if(result) {
1126*6236dae4SAndroid Build Coastguard Worker failf(data, "error signaled by ssl ctx callback");
1127*6236dae4SAndroid Build Coastguard Worker return result;
1128*6236dae4SAndroid Build Coastguard Worker }
1129*6236dae4SAndroid Build Coastguard Worker }
1130*6236dae4SAndroid Build Coastguard Worker #ifdef NO_FILESYSTEM
1131*6236dae4SAndroid Build Coastguard Worker else if(conn_config->verifypeer) {
1132*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: Certificates cannot be loaded because wolfSSL was built"
1133*6236dae4SAndroid Build Coastguard Worker " with \"no filesystem\". Either disable peer verification"
1134*6236dae4SAndroid Build Coastguard Worker " (insecure) or if you are building an application with libcurl you"
1135*6236dae4SAndroid Build Coastguard Worker " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
1136*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1137*6236dae4SAndroid Build Coastguard Worker }
1138*6236dae4SAndroid Build Coastguard Worker #endif
1139*6236dae4SAndroid Build Coastguard Worker
1140*6236dae4SAndroid Build Coastguard Worker /* Let's make an SSL structure */
1141*6236dae4SAndroid Build Coastguard Worker if(backend->handle)
1142*6236dae4SAndroid Build Coastguard Worker wolfSSL_free(backend->handle);
1143*6236dae4SAndroid Build Coastguard Worker backend->handle = wolfSSL_new(backend->ctx);
1144*6236dae4SAndroid Build Coastguard Worker if(!backend->handle) {
1145*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: could not create a handle");
1146*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
1147*6236dae4SAndroid Build Coastguard Worker }
1148*6236dae4SAndroid Build Coastguard Worker
1149*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_HAVE_KYBER
1150*6236dae4SAndroid Build Coastguard Worker if(pqkem) {
1151*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_UseKeyShare(backend->handle, pqkem) != WOLFSSL_SUCCESS) {
1152*6236dae4SAndroid Build Coastguard Worker failf(data, "unable to use PQ KEM");
1153*6236dae4SAndroid Build Coastguard Worker }
1154*6236dae4SAndroid Build Coastguard Worker }
1155*6236dae4SAndroid Build Coastguard Worker #endif
1156*6236dae4SAndroid Build Coastguard Worker
1157*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_ALPN
1158*6236dae4SAndroid Build Coastguard Worker if(connssl->alpn) {
1159*6236dae4SAndroid Build Coastguard Worker struct alpn_proto_buf proto;
1160*6236dae4SAndroid Build Coastguard Worker CURLcode result;
1161*6236dae4SAndroid Build Coastguard Worker
1162*6236dae4SAndroid Build Coastguard Worker result = Curl_alpn_to_proto_str(&proto, connssl->alpn);
1163*6236dae4SAndroid Build Coastguard Worker if(result ||
1164*6236dae4SAndroid Build Coastguard Worker wolfSSL_UseALPN(backend->handle,
1165*6236dae4SAndroid Build Coastguard Worker (char *)proto.data, (unsigned int)proto.len,
1166*6236dae4SAndroid Build Coastguard Worker WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != WOLFSSL_SUCCESS) {
1167*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: failed setting ALPN protocols");
1168*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1169*6236dae4SAndroid Build Coastguard Worker }
1170*6236dae4SAndroid Build Coastguard Worker infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
1171*6236dae4SAndroid Build Coastguard Worker }
1172*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_ALPN */
1173*6236dae4SAndroid Build Coastguard Worker
1174*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_EXTRA
1175*6236dae4SAndroid Build Coastguard Worker if(Curl_tls_keylog_enabled()) {
1176*6236dae4SAndroid Build Coastguard Worker /* Ensure the Client Random is preserved. */
1177*6236dae4SAndroid Build Coastguard Worker wolfSSL_KeepArrays(backend->handle);
1178*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
1179*6236dae4SAndroid Build Coastguard Worker wolfSSL_set_tls13_secret_cb(backend->handle,
1180*6236dae4SAndroid Build Coastguard Worker wolfssl_tls13_secret_callback, NULL);
1181*6236dae4SAndroid Build Coastguard Worker #endif
1182*6236dae4SAndroid Build Coastguard Worker }
1183*6236dae4SAndroid Build Coastguard Worker #endif /* OPENSSL_EXTRA */
1184*6236dae4SAndroid Build Coastguard Worker
1185*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SECURE_RENEGOTIATION
1186*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_UseSecureRenegotiation(backend->handle) != SSL_SUCCESS) {
1187*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: failed setting secure renegotiation");
1188*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1189*6236dae4SAndroid Build Coastguard Worker }
1190*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_SECURE_RENEGOTIATION */
1191*6236dae4SAndroid Build Coastguard Worker
1192*6236dae4SAndroid Build Coastguard Worker /* Check if there is a cached ID we can/should use here! */
1193*6236dae4SAndroid Build Coastguard Worker if(ssl_config->primary.cache_session) {
1194*6236dae4SAndroid Build Coastguard Worker /* Set session from cache if there is one */
1195*6236dae4SAndroid Build Coastguard Worker (void)wssl_setup_session(cf, data, backend, &connssl->peer);
1196*6236dae4SAndroid Build Coastguard Worker /* Register to get notified when a new session is received */
1197*6236dae4SAndroid Build Coastguard Worker wolfSSL_set_app_data(backend->handle, cf);
1198*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_sess_set_new_cb(backend->ctx, wssl_vtls_new_session_cb);
1199*6236dae4SAndroid Build Coastguard Worker }
1200*6236dae4SAndroid Build Coastguard Worker
1201*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
1202*6236dae4SAndroid Build Coastguard Worker if(ECH_ENABLED(data)) {
1203*6236dae4SAndroid Build Coastguard Worker int trying_ech_now = 0;
1204*6236dae4SAndroid Build Coastguard Worker
1205*6236dae4SAndroid Build Coastguard Worker if(data->set.str[STRING_ECH_PUBLIC]) {
1206*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: outername not (yet) supported with wolfSSL");
1207*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1208*6236dae4SAndroid Build Coastguard Worker }
1209*6236dae4SAndroid Build Coastguard Worker if(data->set.tls_ech == CURLECH_GREASE) {
1210*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: GREASE'd ECH not yet supported for wolfSSL");
1211*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1212*6236dae4SAndroid Build Coastguard Worker }
1213*6236dae4SAndroid Build Coastguard Worker if(data->set.tls_ech & CURLECH_CLA_CFG
1214*6236dae4SAndroid Build Coastguard Worker && data->set.str[STRING_ECH_CONFIG]) {
1215*6236dae4SAndroid Build Coastguard Worker char *b64val = data->set.str[STRING_ECH_CONFIG];
1216*6236dae4SAndroid Build Coastguard Worker word32 b64len = 0;
1217*6236dae4SAndroid Build Coastguard Worker
1218*6236dae4SAndroid Build Coastguard Worker b64len = (word32) strlen(b64val);
1219*6236dae4SAndroid Build Coastguard Worker if(b64len
1220*6236dae4SAndroid Build Coastguard Worker && wolfSSL_SetEchConfigsBase64(backend->handle, b64val, b64len)
1221*6236dae4SAndroid Build Coastguard Worker != WOLFSSL_SUCCESS) {
1222*6236dae4SAndroid Build Coastguard Worker if(data->set.tls_ech & CURLECH_HARD)
1223*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1224*6236dae4SAndroid Build Coastguard Worker }
1225*6236dae4SAndroid Build Coastguard Worker else {
1226*6236dae4SAndroid Build Coastguard Worker trying_ech_now = 1;
1227*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: ECHConfig from command line");
1228*6236dae4SAndroid Build Coastguard Worker }
1229*6236dae4SAndroid Build Coastguard Worker }
1230*6236dae4SAndroid Build Coastguard Worker else {
1231*6236dae4SAndroid Build Coastguard Worker struct Curl_dns_entry *dns = NULL;
1232*6236dae4SAndroid Build Coastguard Worker
1233*6236dae4SAndroid Build Coastguard Worker dns = Curl_fetch_addr(data, connssl->peer.hostname, connssl->peer.port);
1234*6236dae4SAndroid Build Coastguard Worker if(!dns) {
1235*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: requested but no DNS info available");
1236*6236dae4SAndroid Build Coastguard Worker if(data->set.tls_ech & CURLECH_HARD)
1237*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1238*6236dae4SAndroid Build Coastguard Worker }
1239*6236dae4SAndroid Build Coastguard Worker else {
1240*6236dae4SAndroid Build Coastguard Worker struct Curl_https_rrinfo *rinfo = NULL;
1241*6236dae4SAndroid Build Coastguard Worker
1242*6236dae4SAndroid Build Coastguard Worker rinfo = dns->hinfo;
1243*6236dae4SAndroid Build Coastguard Worker if(rinfo && rinfo->echconfiglist) {
1244*6236dae4SAndroid Build Coastguard Worker unsigned char *ecl = rinfo->echconfiglist;
1245*6236dae4SAndroid Build Coastguard Worker size_t elen = rinfo->echconfiglist_len;
1246*6236dae4SAndroid Build Coastguard Worker
1247*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: ECHConfig from DoH HTTPS RR");
1248*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_SetEchConfigs(backend->handle, ecl, (word32) elen) !=
1249*6236dae4SAndroid Build Coastguard Worker WOLFSSL_SUCCESS) {
1250*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: wolfSSL_SetEchConfigs failed");
1251*6236dae4SAndroid Build Coastguard Worker if(data->set.tls_ech & CURLECH_HARD)
1252*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1253*6236dae4SAndroid Build Coastguard Worker }
1254*6236dae4SAndroid Build Coastguard Worker else {
1255*6236dae4SAndroid Build Coastguard Worker trying_ech_now = 1;
1256*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: imported ECHConfigList of length %ld", elen);
1257*6236dae4SAndroid Build Coastguard Worker }
1258*6236dae4SAndroid Build Coastguard Worker }
1259*6236dae4SAndroid Build Coastguard Worker else {
1260*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: requested but no ECHConfig available");
1261*6236dae4SAndroid Build Coastguard Worker if(data->set.tls_ech & CURLECH_HARD)
1262*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1263*6236dae4SAndroid Build Coastguard Worker }
1264*6236dae4SAndroid Build Coastguard Worker Curl_resolv_unlink(data, &dns);
1265*6236dae4SAndroid Build Coastguard Worker }
1266*6236dae4SAndroid Build Coastguard Worker }
1267*6236dae4SAndroid Build Coastguard Worker
1268*6236dae4SAndroid Build Coastguard Worker if(trying_ech_now
1269*6236dae4SAndroid Build Coastguard Worker && SSL_set_min_proto_version(backend->handle, TLS1_3_VERSION) != 1) {
1270*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: cannot force TLSv1.3 [ERROR]");
1271*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1272*6236dae4SAndroid Build Coastguard Worker }
1273*6236dae4SAndroid Build Coastguard Worker
1274*6236dae4SAndroid Build Coastguard Worker }
1275*6236dae4SAndroid Build Coastguard Worker #endif /* USE_ECH */
1276*6236dae4SAndroid Build Coastguard Worker
1277*6236dae4SAndroid Build Coastguard Worker #ifdef USE_BIO_CHAIN
1278*6236dae4SAndroid Build Coastguard Worker {
1279*6236dae4SAndroid Build Coastguard Worker WOLFSSL_BIO *bio;
1280*6236dae4SAndroid Build Coastguard Worker
1281*6236dae4SAndroid Build Coastguard Worker bio = wolfSSL_BIO_new(wolfssl_bio_cf_method);
1282*6236dae4SAndroid Build Coastguard Worker if(!bio)
1283*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
1284*6236dae4SAndroid Build Coastguard Worker
1285*6236dae4SAndroid Build Coastguard Worker wolfSSL_BIO_set_data(bio, cf);
1286*6236dae4SAndroid Build Coastguard Worker wolfSSL_set_bio(backend->handle, bio, bio);
1287*6236dae4SAndroid Build Coastguard Worker }
1288*6236dae4SAndroid Build Coastguard Worker #else /* USE_BIO_CHAIN */
1289*6236dae4SAndroid Build Coastguard Worker /* pass the raw socket into the SSL layer */
1290*6236dae4SAndroid Build Coastguard Worker if(!wolfSSL_set_fd(backend->handle,
1291*6236dae4SAndroid Build Coastguard Worker (int)Curl_conn_cf_get_socket(cf, data))) {
1292*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: SSL_set_fd failed");
1293*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1294*6236dae4SAndroid Build Coastguard Worker }
1295*6236dae4SAndroid Build Coastguard Worker #endif /* !USE_BIO_CHAIN */
1296*6236dae4SAndroid Build Coastguard Worker
1297*6236dae4SAndroid Build Coastguard Worker connssl->connecting_state = ssl_connect_2;
1298*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1299*6236dae4SAndroid Build Coastguard Worker }
1300*6236dae4SAndroid Build Coastguard Worker
1301*6236dae4SAndroid Build Coastguard Worker
wolfssl_strerror(unsigned long error,char * buf,unsigned long size)1302*6236dae4SAndroid Build Coastguard Worker static char *wolfssl_strerror(unsigned long error, char *buf,
1303*6236dae4SAndroid Build Coastguard Worker unsigned long size)
1304*6236dae4SAndroid Build Coastguard Worker {
1305*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size > 40);
1306*6236dae4SAndroid Build Coastguard Worker *buf = '\0';
1307*6236dae4SAndroid Build Coastguard Worker
1308*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_error_string_n(error, buf, size);
1309*6236dae4SAndroid Build Coastguard Worker
1310*6236dae4SAndroid Build Coastguard Worker if(!*buf) {
1311*6236dae4SAndroid Build Coastguard Worker const char *msg = error ? "Unknown error" : "No error";
1312*6236dae4SAndroid Build Coastguard Worker /* the string fits because the assert above assures this */
1313*6236dae4SAndroid Build Coastguard Worker strcpy(buf, msg);
1314*6236dae4SAndroid Build Coastguard Worker }
1315*6236dae4SAndroid Build Coastguard Worker
1316*6236dae4SAndroid Build Coastguard Worker return buf;
1317*6236dae4SAndroid Build Coastguard Worker }
1318*6236dae4SAndroid Build Coastguard Worker
1319*6236dae4SAndroid Build Coastguard Worker
1320*6236dae4SAndroid Build Coastguard Worker static CURLcode
wolfssl_connect_step2(struct Curl_cfilter * cf,struct Curl_easy * data)1321*6236dae4SAndroid Build Coastguard Worker wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
1322*6236dae4SAndroid Build Coastguard Worker {
1323*6236dae4SAndroid Build Coastguard Worker int ret = -1;
1324*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
1325*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
1326*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
1327*6236dae4SAndroid Build Coastguard Worker struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
1328*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_PROXY
1329*6236dae4SAndroid Build Coastguard Worker const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf) ?
1330*6236dae4SAndroid Build Coastguard Worker data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
1331*6236dae4SAndroid Build Coastguard Worker data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1332*6236dae4SAndroid Build Coastguard Worker #else
1333*6236dae4SAndroid Build Coastguard Worker const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1334*6236dae4SAndroid Build Coastguard Worker #endif
1335*6236dae4SAndroid Build Coastguard Worker
1336*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(backend);
1337*6236dae4SAndroid Build Coastguard Worker
1338*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_clear_error();
1339*6236dae4SAndroid Build Coastguard Worker
1340*6236dae4SAndroid Build Coastguard Worker /* Enable RFC2818 checks */
1341*6236dae4SAndroid Build Coastguard Worker if(conn_config->verifyhost) {
1342*6236dae4SAndroid Build Coastguard Worker char *snihost = connssl->peer.sni ?
1343*6236dae4SAndroid Build Coastguard Worker connssl->peer.sni : connssl->peer.hostname;
1344*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_check_domain_name(backend->handle, snihost) == WOLFSSL_FAILURE)
1345*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1346*6236dae4SAndroid Build Coastguard Worker }
1347*6236dae4SAndroid Build Coastguard Worker
1348*6236dae4SAndroid Build Coastguard Worker if(!backend->x509_store_setup) {
1349*6236dae4SAndroid Build Coastguard Worker /* After having send off the ClientHello, we prepare the x509
1350*6236dae4SAndroid Build Coastguard Worker * store to verify the coming certificate from the server */
1351*6236dae4SAndroid Build Coastguard Worker CURLcode result;
1352*6236dae4SAndroid Build Coastguard Worker result = Curl_wssl_setup_x509_store(cf, data, backend);
1353*6236dae4SAndroid Build Coastguard Worker if(result)
1354*6236dae4SAndroid Build Coastguard Worker return result;
1355*6236dae4SAndroid Build Coastguard Worker }
1356*6236dae4SAndroid Build Coastguard Worker
1357*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_NONE;
1358*6236dae4SAndroid Build Coastguard Worker ret = wolfSSL_connect(backend->handle);
1359*6236dae4SAndroid Build Coastguard Worker
1360*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_EXTRA
1361*6236dae4SAndroid Build Coastguard Worker if(Curl_tls_keylog_enabled()) {
1362*6236dae4SAndroid Build Coastguard Worker /* If key logging is enabled, wait for the handshake to complete and then
1363*6236dae4SAndroid Build Coastguard Worker * proceed with logging secrets (for TLS 1.2 or older).
1364*6236dae4SAndroid Build Coastguard Worker *
1365*6236dae4SAndroid Build Coastguard Worker * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits
1366*6236dae4SAndroid Build Coastguard Worker * for the server response. At that point the master secret is not yet
1367*6236dae4SAndroid Build Coastguard Worker * available, so we must not try to read it.
1368*6236dae4SAndroid Build Coastguard Worker * To log the secret on completion with a handshake failure, detect
1369*6236dae4SAndroid Build Coastguard Worker * completion via the observation that there is nothing to read or write.
1370*6236dae4SAndroid Build Coastguard Worker * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever
1371*6236dae4SAndroid Build Coastguard Worker * changes, the worst case is that no key is logged on error.
1372*6236dae4SAndroid Build Coastguard Worker */
1373*6236dae4SAndroid Build Coastguard Worker if(ret == WOLFSSL_SUCCESS ||
1374*6236dae4SAndroid Build Coastguard Worker (!wolfSSL_want_read(backend->handle) &&
1375*6236dae4SAndroid Build Coastguard Worker !wolfSSL_want_write(backend->handle))) {
1376*6236dae4SAndroid Build Coastguard Worker wolfssl_log_tls12_secret(backend->handle);
1377*6236dae4SAndroid Build Coastguard Worker /* Client Random and master secrets are no longer needed, erase these.
1378*6236dae4SAndroid Build Coastguard Worker * Ignored while the handshake is still in progress. */
1379*6236dae4SAndroid Build Coastguard Worker wolfSSL_FreeArrays(backend->handle);
1380*6236dae4SAndroid Build Coastguard Worker }
1381*6236dae4SAndroid Build Coastguard Worker }
1382*6236dae4SAndroid Build Coastguard Worker #endif /* OPENSSL_EXTRA */
1383*6236dae4SAndroid Build Coastguard Worker
1384*6236dae4SAndroid Build Coastguard Worker if(ret != 1) {
1385*6236dae4SAndroid Build Coastguard Worker int detail = wolfSSL_get_error(backend->handle, ret);
1386*6236dae4SAndroid Build Coastguard Worker
1387*6236dae4SAndroid Build Coastguard Worker if(WOLFSSL_ERROR_WANT_READ == detail) {
1388*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_RECV;
1389*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1390*6236dae4SAndroid Build Coastguard Worker }
1391*6236dae4SAndroid Build Coastguard Worker else if(WOLFSSL_ERROR_WANT_WRITE == detail) {
1392*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_SEND;
1393*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1394*6236dae4SAndroid Build Coastguard Worker }
1395*6236dae4SAndroid Build Coastguard Worker /* There is no easy way to override only the CN matching.
1396*6236dae4SAndroid Build Coastguard Worker * This will enable the override of both mismatching SubjectAltNames
1397*6236dae4SAndroid Build Coastguard Worker * as also mismatching CN fields */
1398*6236dae4SAndroid Build Coastguard Worker else if(DOMAIN_NAME_MISMATCH == detail) {
1399*6236dae4SAndroid Build Coastguard Worker #if 1
1400*6236dae4SAndroid Build Coastguard Worker failf(data, " subject alt name(s) or common name do not match \"%s\"",
1401*6236dae4SAndroid Build Coastguard Worker connssl->peer.dispname);
1402*6236dae4SAndroid Build Coastguard Worker return CURLE_PEER_FAILED_VERIFICATION;
1403*6236dae4SAndroid Build Coastguard Worker #else
1404*6236dae4SAndroid Build Coastguard Worker /* When the wolfssl_check_domain_name() is used and you desire to
1405*6236dae4SAndroid Build Coastguard Worker * continue on a DOMAIN_NAME_MISMATCH, i.e. 'ssl_config.verifyhost
1406*6236dae4SAndroid Build Coastguard Worker * == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA
1407*6236dae4SAndroid Build Coastguard Worker * error. The only way to do this is currently to switch the
1408*6236dae4SAndroid Build Coastguard Worker * Wolfssl_check_domain_name() in and out based on the
1409*6236dae4SAndroid Build Coastguard Worker * 'ssl_config.verifyhost' value. */
1410*6236dae4SAndroid Build Coastguard Worker if(conn_config->verifyhost) {
1411*6236dae4SAndroid Build Coastguard Worker failf(data,
1412*6236dae4SAndroid Build Coastguard Worker " subject alt name(s) or common name do not match \"%s\"\n",
1413*6236dae4SAndroid Build Coastguard Worker connssl->dispname);
1414*6236dae4SAndroid Build Coastguard Worker return CURLE_PEER_FAILED_VERIFICATION;
1415*6236dae4SAndroid Build Coastguard Worker }
1416*6236dae4SAndroid Build Coastguard Worker else {
1417*6236dae4SAndroid Build Coastguard Worker infof(data,
1418*6236dae4SAndroid Build Coastguard Worker " subject alt name(s) and/or common name do not match \"%s\"",
1419*6236dae4SAndroid Build Coastguard Worker connssl->dispname);
1420*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1421*6236dae4SAndroid Build Coastguard Worker }
1422*6236dae4SAndroid Build Coastguard Worker #endif
1423*6236dae4SAndroid Build Coastguard Worker }
1424*6236dae4SAndroid Build Coastguard Worker else if(ASN_NO_SIGNER_E == detail) {
1425*6236dae4SAndroid Build Coastguard Worker if(conn_config->verifypeer) {
1426*6236dae4SAndroid Build Coastguard Worker failf(data, " CA signer not available for verification");
1427*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CACERT_BADFILE;
1428*6236dae4SAndroid Build Coastguard Worker }
1429*6236dae4SAndroid Build Coastguard Worker else {
1430*6236dae4SAndroid Build Coastguard Worker /* Just continue with a warning if no strict certificate
1431*6236dae4SAndroid Build Coastguard Worker verification is required. */
1432*6236dae4SAndroid Build Coastguard Worker infof(data, "CA signer not available for verification, "
1433*6236dae4SAndroid Build Coastguard Worker "continuing anyway");
1434*6236dae4SAndroid Build Coastguard Worker }
1435*6236dae4SAndroid Build Coastguard Worker }
1436*6236dae4SAndroid Build Coastguard Worker else if(ASN_AFTER_DATE_E == detail) {
1437*6236dae4SAndroid Build Coastguard Worker failf(data, "server verification failed: certificate has expired.");
1438*6236dae4SAndroid Build Coastguard Worker return CURLE_PEER_FAILED_VERIFICATION;
1439*6236dae4SAndroid Build Coastguard Worker }
1440*6236dae4SAndroid Build Coastguard Worker else if(ASN_BEFORE_DATE_E == detail) {
1441*6236dae4SAndroid Build Coastguard Worker failf(data, "server verification failed: certificate not valid yet.");
1442*6236dae4SAndroid Build Coastguard Worker return CURLE_PEER_FAILED_VERIFICATION;
1443*6236dae4SAndroid Build Coastguard Worker }
1444*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
1445*6236dae4SAndroid Build Coastguard Worker else if(-1 == detail) {
1446*6236dae4SAndroid Build Coastguard Worker /* try access a retry_config ECHConfigList for tracing */
1447*6236dae4SAndroid Build Coastguard Worker byte echConfigs[1000];
1448*6236dae4SAndroid Build Coastguard Worker word32 echConfigsLen = 1000;
1449*6236dae4SAndroid Build Coastguard Worker int rv = 0;
1450*6236dae4SAndroid Build Coastguard Worker
1451*6236dae4SAndroid Build Coastguard Worker /* this currently does not produce the retry_configs */
1452*6236dae4SAndroid Build Coastguard Worker rv = wolfSSL_GetEchConfigs(backend->handle, echConfigs,
1453*6236dae4SAndroid Build Coastguard Worker &echConfigsLen);
1454*6236dae4SAndroid Build Coastguard Worker if(rv != WOLFSSL_SUCCESS) {
1455*6236dae4SAndroid Build Coastguard Worker infof(data, "Failed to get ECHConfigs");
1456*6236dae4SAndroid Build Coastguard Worker }
1457*6236dae4SAndroid Build Coastguard Worker else {
1458*6236dae4SAndroid Build Coastguard Worker char *b64str = NULL;
1459*6236dae4SAndroid Build Coastguard Worker size_t blen = 0;
1460*6236dae4SAndroid Build Coastguard Worker
1461*6236dae4SAndroid Build Coastguard Worker rv = Curl_base64_encode((const char *)echConfigs, echConfigsLen,
1462*6236dae4SAndroid Build Coastguard Worker &b64str, &blen);
1463*6236dae4SAndroid Build Coastguard Worker if(!rv && b64str)
1464*6236dae4SAndroid Build Coastguard Worker infof(data, "ECH: (not yet) retry_configs %s", b64str);
1465*6236dae4SAndroid Build Coastguard Worker free(b64str);
1466*6236dae4SAndroid Build Coastguard Worker }
1467*6236dae4SAndroid Build Coastguard Worker }
1468*6236dae4SAndroid Build Coastguard Worker #endif
1469*6236dae4SAndroid Build Coastguard Worker else if(backend->io_result == CURLE_AGAIN) {
1470*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1471*6236dae4SAndroid Build Coastguard Worker }
1472*6236dae4SAndroid Build Coastguard Worker else {
1473*6236dae4SAndroid Build Coastguard Worker char error_buffer[256];
1474*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL_connect failed with error %d: %s", detail,
1475*6236dae4SAndroid Build Coastguard Worker wolfssl_strerror((unsigned long)detail, error_buffer,
1476*6236dae4SAndroid Build Coastguard Worker sizeof(error_buffer)));
1477*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1478*6236dae4SAndroid Build Coastguard Worker }
1479*6236dae4SAndroid Build Coastguard Worker }
1480*6236dae4SAndroid Build Coastguard Worker
1481*6236dae4SAndroid Build Coastguard Worker if(pinnedpubkey) {
1482*6236dae4SAndroid Build Coastguard Worker #ifdef KEEP_PEER_CERT
1483*6236dae4SAndroid Build Coastguard Worker WOLFSSL_X509 *x509;
1484*6236dae4SAndroid Build Coastguard Worker const char *x509_der;
1485*6236dae4SAndroid Build Coastguard Worker int x509_der_len;
1486*6236dae4SAndroid Build Coastguard Worker struct Curl_X509certificate x509_parsed;
1487*6236dae4SAndroid Build Coastguard Worker struct Curl_asn1Element *pubkey;
1488*6236dae4SAndroid Build Coastguard Worker CURLcode result;
1489*6236dae4SAndroid Build Coastguard Worker
1490*6236dae4SAndroid Build Coastguard Worker x509 = wolfSSL_get_peer_certificate(backend->handle);
1491*6236dae4SAndroid Build Coastguard Worker if(!x509) {
1492*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: failed retrieving server certificate");
1493*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1494*6236dae4SAndroid Build Coastguard Worker }
1495*6236dae4SAndroid Build Coastguard Worker
1496*6236dae4SAndroid Build Coastguard Worker x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len);
1497*6236dae4SAndroid Build Coastguard Worker if(!x509_der) {
1498*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: failed retrieving ASN.1 server certificate");
1499*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1500*6236dae4SAndroid Build Coastguard Worker }
1501*6236dae4SAndroid Build Coastguard Worker
1502*6236dae4SAndroid Build Coastguard Worker memset(&x509_parsed, 0, sizeof(x509_parsed));
1503*6236dae4SAndroid Build Coastguard Worker if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
1504*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1505*6236dae4SAndroid Build Coastguard Worker
1506*6236dae4SAndroid Build Coastguard Worker pubkey = &x509_parsed.subjectPublicKeyInfo;
1507*6236dae4SAndroid Build Coastguard Worker if(!pubkey->header || pubkey->end <= pubkey->header) {
1508*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: failed retrieving public key from server certificate");
1509*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
1510*6236dae4SAndroid Build Coastguard Worker }
1511*6236dae4SAndroid Build Coastguard Worker
1512*6236dae4SAndroid Build Coastguard Worker result = Curl_pin_peer_pubkey(data,
1513*6236dae4SAndroid Build Coastguard Worker pinnedpubkey,
1514*6236dae4SAndroid Build Coastguard Worker (const unsigned char *)pubkey->header,
1515*6236dae4SAndroid Build Coastguard Worker (size_t)(pubkey->end - pubkey->header));
1516*6236dae4SAndroid Build Coastguard Worker wolfSSL_FreeX509(x509);
1517*6236dae4SAndroid Build Coastguard Worker if(result) {
1518*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL: public key does not match pinned public key");
1519*6236dae4SAndroid Build Coastguard Worker return result;
1520*6236dae4SAndroid Build Coastguard Worker }
1521*6236dae4SAndroid Build Coastguard Worker #else
1522*6236dae4SAndroid Build Coastguard Worker failf(data, "Library lacks pinning support built-in");
1523*6236dae4SAndroid Build Coastguard Worker return CURLE_NOT_BUILT_IN;
1524*6236dae4SAndroid Build Coastguard Worker #endif
1525*6236dae4SAndroid Build Coastguard Worker }
1526*6236dae4SAndroid Build Coastguard Worker
1527*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_ALPN
1528*6236dae4SAndroid Build Coastguard Worker if(connssl->alpn) {
1529*6236dae4SAndroid Build Coastguard Worker int rc;
1530*6236dae4SAndroid Build Coastguard Worker char *protocol = NULL;
1531*6236dae4SAndroid Build Coastguard Worker unsigned short protocol_len = 0;
1532*6236dae4SAndroid Build Coastguard Worker
1533*6236dae4SAndroid Build Coastguard Worker rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len);
1534*6236dae4SAndroid Build Coastguard Worker
1535*6236dae4SAndroid Build Coastguard Worker if(rc == WOLFSSL_SUCCESS) {
1536*6236dae4SAndroid Build Coastguard Worker Curl_alpn_set_negotiated(cf, data, connssl,
1537*6236dae4SAndroid Build Coastguard Worker (const unsigned char *)protocol, protocol_len);
1538*6236dae4SAndroid Build Coastguard Worker }
1539*6236dae4SAndroid Build Coastguard Worker else if(rc == WOLFSSL_ALPN_NOT_FOUND)
1540*6236dae4SAndroid Build Coastguard Worker Curl_alpn_set_negotiated(cf, data, connssl, NULL, 0);
1541*6236dae4SAndroid Build Coastguard Worker else {
1542*6236dae4SAndroid Build Coastguard Worker failf(data, "ALPN, failure getting protocol, error %d", rc);
1543*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1544*6236dae4SAndroid Build Coastguard Worker }
1545*6236dae4SAndroid Build Coastguard Worker }
1546*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_ALPN */
1547*6236dae4SAndroid Build Coastguard Worker
1548*6236dae4SAndroid Build Coastguard Worker connssl->connecting_state = ssl_connect_3;
1549*6236dae4SAndroid Build Coastguard Worker #if (LIBWOLFSSL_VERSION_HEX >= 0x03009010)
1550*6236dae4SAndroid Build Coastguard Worker infof(data, "SSL connection using %s / %s",
1551*6236dae4SAndroid Build Coastguard Worker wolfSSL_get_version(backend->handle),
1552*6236dae4SAndroid Build Coastguard Worker wolfSSL_get_cipher_name(backend->handle));
1553*6236dae4SAndroid Build Coastguard Worker #else
1554*6236dae4SAndroid Build Coastguard Worker infof(data, "SSL connected");
1555*6236dae4SAndroid Build Coastguard Worker #endif
1556*6236dae4SAndroid Build Coastguard Worker
1557*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1558*6236dae4SAndroid Build Coastguard Worker }
1559*6236dae4SAndroid Build Coastguard Worker
wolfssl_send(struct Curl_cfilter * cf,struct Curl_easy * data,const void * mem,size_t len,CURLcode * curlcode)1560*6236dae4SAndroid Build Coastguard Worker static ssize_t wolfssl_send(struct Curl_cfilter *cf,
1561*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
1562*6236dae4SAndroid Build Coastguard Worker const void *mem,
1563*6236dae4SAndroid Build Coastguard Worker size_t len,
1564*6236dae4SAndroid Build Coastguard Worker CURLcode *curlcode)
1565*6236dae4SAndroid Build Coastguard Worker {
1566*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
1567*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
1568*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
1569*6236dae4SAndroid Build Coastguard Worker int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
1570*6236dae4SAndroid Build Coastguard Worker int rc;
1571*6236dae4SAndroid Build Coastguard Worker
1572*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(backend);
1573*6236dae4SAndroid Build Coastguard Worker
1574*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_clear_error();
1575*6236dae4SAndroid Build Coastguard Worker
1576*6236dae4SAndroid Build Coastguard Worker rc = wolfSSL_write(backend->handle, mem, memlen);
1577*6236dae4SAndroid Build Coastguard Worker if(rc <= 0) {
1578*6236dae4SAndroid Build Coastguard Worker int err = wolfSSL_get_error(backend->handle, rc);
1579*6236dae4SAndroid Build Coastguard Worker
1580*6236dae4SAndroid Build Coastguard Worker switch(err) {
1581*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_WANT_READ:
1582*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_WANT_WRITE:
1583*6236dae4SAndroid Build Coastguard Worker /* there is data pending, re-invoke SSL_write() */
1584*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_send(len=%zu) -> AGAIN", len);
1585*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_AGAIN;
1586*6236dae4SAndroid Build Coastguard Worker return -1;
1587*6236dae4SAndroid Build Coastguard Worker default:
1588*6236dae4SAndroid Build Coastguard Worker if(backend->io_result == CURLE_AGAIN) {
1589*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_send(len=%zu) -> AGAIN", len);
1590*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_AGAIN;
1591*6236dae4SAndroid Build Coastguard Worker return -1;
1592*6236dae4SAndroid Build Coastguard Worker }
1593*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_send(len=%zu) -> %d, %d", len, rc, err);
1594*6236dae4SAndroid Build Coastguard Worker {
1595*6236dae4SAndroid Build Coastguard Worker char error_buffer[256];
1596*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL write: %s, errno %d",
1597*6236dae4SAndroid Build Coastguard Worker wolfssl_strerror((unsigned long)err, error_buffer,
1598*6236dae4SAndroid Build Coastguard Worker sizeof(error_buffer)),
1599*6236dae4SAndroid Build Coastguard Worker SOCKERRNO);
1600*6236dae4SAndroid Build Coastguard Worker }
1601*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_SEND_ERROR;
1602*6236dae4SAndroid Build Coastguard Worker return -1;
1603*6236dae4SAndroid Build Coastguard Worker }
1604*6236dae4SAndroid Build Coastguard Worker }
1605*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_send(len=%zu) -> %d", len, rc);
1606*6236dae4SAndroid Build Coastguard Worker return rc;
1607*6236dae4SAndroid Build Coastguard Worker }
1608*6236dae4SAndroid Build Coastguard Worker
wolfssl_shutdown(struct Curl_cfilter * cf,struct Curl_easy * data,bool send_shutdown,bool * done)1609*6236dae4SAndroid Build Coastguard Worker static CURLcode wolfssl_shutdown(struct Curl_cfilter *cf,
1610*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
1611*6236dae4SAndroid Build Coastguard Worker bool send_shutdown, bool *done)
1612*6236dae4SAndroid Build Coastguard Worker {
1613*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
1614*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *wctx = (struct wolfssl_ctx *)connssl->backend;
1615*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
1616*6236dae4SAndroid Build Coastguard Worker char buf[1024];
1617*6236dae4SAndroid Build Coastguard Worker char error_buffer[256];
1618*6236dae4SAndroid Build Coastguard Worker int nread = -1, err;
1619*6236dae4SAndroid Build Coastguard Worker size_t i;
1620*6236dae4SAndroid Build Coastguard Worker int detail;
1621*6236dae4SAndroid Build Coastguard Worker
1622*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(wctx);
1623*6236dae4SAndroid Build Coastguard Worker if(!wctx->handle || cf->shutdown) {
1624*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1625*6236dae4SAndroid Build Coastguard Worker goto out;
1626*6236dae4SAndroid Build Coastguard Worker }
1627*6236dae4SAndroid Build Coastguard Worker
1628*6236dae4SAndroid Build Coastguard Worker wctx->shutting_down = TRUE;
1629*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_NONE;
1630*6236dae4SAndroid Build Coastguard Worker *done = FALSE;
1631*6236dae4SAndroid Build Coastguard Worker if(!(wolfSSL_get_shutdown(wctx->handle) & WOLFSSL_SENT_SHUTDOWN)) {
1632*6236dae4SAndroid Build Coastguard Worker /* We have not started the shutdown from our side yet. Check
1633*6236dae4SAndroid Build Coastguard Worker * if the server already sent us one. */
1634*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_clear_error();
1635*6236dae4SAndroid Build Coastguard Worker nread = wolfSSL_read(wctx->handle, buf, (int)sizeof(buf));
1636*6236dae4SAndroid Build Coastguard Worker err = wolfSSL_get_error(wctx->handle, nread);
1637*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfSSL_read, nread=%d, err=%d", nread, err);
1638*6236dae4SAndroid Build Coastguard Worker if(!nread && err == WOLFSSL_ERROR_ZERO_RETURN) {
1639*6236dae4SAndroid Build Coastguard Worker bool input_pending;
1640*6236dae4SAndroid Build Coastguard Worker /* Yes, it did. */
1641*6236dae4SAndroid Build Coastguard Worker if(!send_shutdown) {
1642*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown received, not sending");
1643*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1644*6236dae4SAndroid Build Coastguard Worker goto out;
1645*6236dae4SAndroid Build Coastguard Worker }
1646*6236dae4SAndroid Build Coastguard Worker else if(!cf->next->cft->is_alive(cf->next, data, &input_pending)) {
1647*6236dae4SAndroid Build Coastguard Worker /* Server closed the connection after its closy notify. It
1648*6236dae4SAndroid Build Coastguard Worker * seems not interested to see our close notify, so do not
1649*6236dae4SAndroid Build Coastguard Worker * send it. We are done. */
1650*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "peer closed connection");
1651*6236dae4SAndroid Build Coastguard Worker connssl->peer_closed = TRUE;
1652*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1653*6236dae4SAndroid Build Coastguard Worker goto out;
1654*6236dae4SAndroid Build Coastguard Worker }
1655*6236dae4SAndroid Build Coastguard Worker }
1656*6236dae4SAndroid Build Coastguard Worker }
1657*6236dae4SAndroid Build Coastguard Worker
1658*6236dae4SAndroid Build Coastguard Worker /* SSL should now have started the shutdown from our side. Since it
1659*6236dae4SAndroid Build Coastguard Worker * was not complete, we are lacking the close notify from the server. */
1660*6236dae4SAndroid Build Coastguard Worker if(send_shutdown) {
1661*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_clear_error();
1662*6236dae4SAndroid Build Coastguard Worker if(wolfSSL_shutdown(wctx->handle) == 1) {
1663*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown finished");
1664*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1665*6236dae4SAndroid Build Coastguard Worker goto out;
1666*6236dae4SAndroid Build Coastguard Worker }
1667*6236dae4SAndroid Build Coastguard Worker if(WOLFSSL_ERROR_WANT_WRITE == wolfSSL_get_error(wctx->handle, nread)) {
1668*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown still wants to send");
1669*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_SEND;
1670*6236dae4SAndroid Build Coastguard Worker goto out;
1671*6236dae4SAndroid Build Coastguard Worker }
1672*6236dae4SAndroid Build Coastguard Worker /* Having sent the close notify, we use wolfSSL_read() to get the
1673*6236dae4SAndroid Build Coastguard Worker * missing close notify from the server. */
1674*6236dae4SAndroid Build Coastguard Worker }
1675*6236dae4SAndroid Build Coastguard Worker
1676*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < 10; ++i) {
1677*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_clear_error();
1678*6236dae4SAndroid Build Coastguard Worker nread = wolfSSL_read(wctx->handle, buf, (int)sizeof(buf));
1679*6236dae4SAndroid Build Coastguard Worker if(nread <= 0)
1680*6236dae4SAndroid Build Coastguard Worker break;
1681*6236dae4SAndroid Build Coastguard Worker }
1682*6236dae4SAndroid Build Coastguard Worker err = wolfSSL_get_error(wctx->handle, nread);
1683*6236dae4SAndroid Build Coastguard Worker switch(err) {
1684*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_ZERO_RETURN: /* no more data */
1685*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown received");
1686*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1687*6236dae4SAndroid Build Coastguard Worker break;
1688*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_NONE: /* just did not get anything */
1689*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_WANT_READ:
1690*6236dae4SAndroid Build Coastguard Worker /* SSL has send its notify and now wants to read the reply
1691*6236dae4SAndroid Build Coastguard Worker * from the server. We are not really interested in that. */
1692*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown sent, want receive");
1693*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_RECV;
1694*6236dae4SAndroid Build Coastguard Worker break;
1695*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_WANT_WRITE:
1696*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown send blocked");
1697*6236dae4SAndroid Build Coastguard Worker connssl->io_need = CURL_SSL_IO_NEED_SEND;
1698*6236dae4SAndroid Build Coastguard Worker break;
1699*6236dae4SAndroid Build Coastguard Worker default:
1700*6236dae4SAndroid Build Coastguard Worker detail = wolfSSL_get_error(wctx->handle, err);
1701*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s'(%d)",
1702*6236dae4SAndroid Build Coastguard Worker wolfssl_strerror((unsigned long)err, error_buffer,
1703*6236dae4SAndroid Build Coastguard Worker sizeof(error_buffer)),
1704*6236dae4SAndroid Build Coastguard Worker detail);
1705*6236dae4SAndroid Build Coastguard Worker result = CURLE_RECV_ERROR;
1706*6236dae4SAndroid Build Coastguard Worker break;
1707*6236dae4SAndroid Build Coastguard Worker }
1708*6236dae4SAndroid Build Coastguard Worker
1709*6236dae4SAndroid Build Coastguard Worker out:
1710*6236dae4SAndroid Build Coastguard Worker cf->shutdown = (result || *done);
1711*6236dae4SAndroid Build Coastguard Worker return result;
1712*6236dae4SAndroid Build Coastguard Worker }
1713*6236dae4SAndroid Build Coastguard Worker
wolfssl_close(struct Curl_cfilter * cf,struct Curl_easy * data)1714*6236dae4SAndroid Build Coastguard Worker static void wolfssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
1715*6236dae4SAndroid Build Coastguard Worker {
1716*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
1717*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
1718*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
1719*6236dae4SAndroid Build Coastguard Worker
1720*6236dae4SAndroid Build Coastguard Worker (void) data;
1721*6236dae4SAndroid Build Coastguard Worker
1722*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(backend);
1723*6236dae4SAndroid Build Coastguard Worker
1724*6236dae4SAndroid Build Coastguard Worker if(backend->handle) {
1725*6236dae4SAndroid Build Coastguard Worker wolfSSL_free(backend->handle);
1726*6236dae4SAndroid Build Coastguard Worker backend->handle = NULL;
1727*6236dae4SAndroid Build Coastguard Worker }
1728*6236dae4SAndroid Build Coastguard Worker if(backend->ctx) {
1729*6236dae4SAndroid Build Coastguard Worker wolfSSL_CTX_free(backend->ctx);
1730*6236dae4SAndroid Build Coastguard Worker backend->ctx = NULL;
1731*6236dae4SAndroid Build Coastguard Worker }
1732*6236dae4SAndroid Build Coastguard Worker }
1733*6236dae4SAndroid Build Coastguard Worker
wolfssl_recv(struct Curl_cfilter * cf,struct Curl_easy * data,char * buf,size_t blen,CURLcode * curlcode)1734*6236dae4SAndroid Build Coastguard Worker static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
1735*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
1736*6236dae4SAndroid Build Coastguard Worker char *buf, size_t blen,
1737*6236dae4SAndroid Build Coastguard Worker CURLcode *curlcode)
1738*6236dae4SAndroid Build Coastguard Worker {
1739*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
1740*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
1741*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
1742*6236dae4SAndroid Build Coastguard Worker int buffsize = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
1743*6236dae4SAndroid Build Coastguard Worker int nread;
1744*6236dae4SAndroid Build Coastguard Worker
1745*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(backend);
1746*6236dae4SAndroid Build Coastguard Worker
1747*6236dae4SAndroid Build Coastguard Worker wolfSSL_ERR_clear_error();
1748*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_OK;
1749*6236dae4SAndroid Build Coastguard Worker
1750*6236dae4SAndroid Build Coastguard Worker nread = wolfSSL_read(backend->handle, buf, buffsize);
1751*6236dae4SAndroid Build Coastguard Worker
1752*6236dae4SAndroid Build Coastguard Worker if(nread <= 0) {
1753*6236dae4SAndroid Build Coastguard Worker int err = wolfSSL_get_error(backend->handle, nread);
1754*6236dae4SAndroid Build Coastguard Worker
1755*6236dae4SAndroid Build Coastguard Worker switch(err) {
1756*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_ZERO_RETURN: /* no more data */
1757*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> CLOSED", blen);
1758*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_OK;
1759*6236dae4SAndroid Build Coastguard Worker return 0;
1760*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_NONE:
1761*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_WANT_READ:
1762*6236dae4SAndroid Build Coastguard Worker case WOLFSSL_ERROR_WANT_WRITE:
1763*6236dae4SAndroid Build Coastguard Worker if(!backend->io_result && connssl->peer_closed) {
1764*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> CLOSED", blen);
1765*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_OK;
1766*6236dae4SAndroid Build Coastguard Worker return 0;
1767*6236dae4SAndroid Build Coastguard Worker }
1768*6236dae4SAndroid Build Coastguard Worker /* there is data pending, re-invoke wolfSSL_read() */
1769*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> AGAIN", blen);
1770*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_AGAIN;
1771*6236dae4SAndroid Build Coastguard Worker return -1;
1772*6236dae4SAndroid Build Coastguard Worker default:
1773*6236dae4SAndroid Build Coastguard Worker if(backend->io_result == CURLE_AGAIN) {
1774*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> AGAIN", blen);
1775*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_AGAIN;
1776*6236dae4SAndroid Build Coastguard Worker return -1;
1777*6236dae4SAndroid Build Coastguard Worker }
1778*6236dae4SAndroid Build Coastguard Worker else if(!backend->io_result && connssl->peer_closed) {
1779*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> CLOSED", blen);
1780*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_OK;
1781*6236dae4SAndroid Build Coastguard Worker return 0;
1782*6236dae4SAndroid Build Coastguard Worker }
1783*6236dae4SAndroid Build Coastguard Worker else {
1784*6236dae4SAndroid Build Coastguard Worker char error_buffer[256];
1785*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL read: %s, errno %d",
1786*6236dae4SAndroid Build Coastguard Worker wolfssl_strerror((unsigned long)err, error_buffer,
1787*6236dae4SAndroid Build Coastguard Worker sizeof(error_buffer)),
1788*6236dae4SAndroid Build Coastguard Worker SOCKERRNO);
1789*6236dae4SAndroid Build Coastguard Worker }
1790*6236dae4SAndroid Build Coastguard Worker *curlcode = CURLE_RECV_ERROR;
1791*6236dae4SAndroid Build Coastguard Worker return -1;
1792*6236dae4SAndroid Build Coastguard Worker }
1793*6236dae4SAndroid Build Coastguard Worker }
1794*6236dae4SAndroid Build Coastguard Worker CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> %d", blen, nread);
1795*6236dae4SAndroid Build Coastguard Worker return nread;
1796*6236dae4SAndroid Build Coastguard Worker }
1797*6236dae4SAndroid Build Coastguard Worker
1798*6236dae4SAndroid Build Coastguard Worker
wolfssl_version(char * buffer,size_t size)1799*6236dae4SAndroid Build Coastguard Worker static size_t wolfssl_version(char *buffer, size_t size)
1800*6236dae4SAndroid Build Coastguard Worker {
1801*6236dae4SAndroid Build Coastguard Worker #if LIBWOLFSSL_VERSION_HEX >= 0x03006000
1802*6236dae4SAndroid Build Coastguard Worker return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
1803*6236dae4SAndroid Build Coastguard Worker #elif defined(WOLFSSL_VERSION)
1804*6236dae4SAndroid Build Coastguard Worker return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
1805*6236dae4SAndroid Build Coastguard Worker #endif
1806*6236dae4SAndroid Build Coastguard Worker }
1807*6236dae4SAndroid Build Coastguard Worker
1808*6236dae4SAndroid Build Coastguard Worker
wolfssl_init(void)1809*6236dae4SAndroid Build Coastguard Worker static int wolfssl_init(void)
1810*6236dae4SAndroid Build Coastguard Worker {
1811*6236dae4SAndroid Build Coastguard Worker int ret;
1812*6236dae4SAndroid Build Coastguard Worker
1813*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_EXTRA
1814*6236dae4SAndroid Build Coastguard Worker Curl_tls_keylog_open();
1815*6236dae4SAndroid Build Coastguard Worker #endif
1816*6236dae4SAndroid Build Coastguard Worker ret = (wolfSSL_Init() == WOLFSSL_SUCCESS);
1817*6236dae4SAndroid Build Coastguard Worker wolfssl_bio_cf_init_methods();
1818*6236dae4SAndroid Build Coastguard Worker return ret;
1819*6236dae4SAndroid Build Coastguard Worker }
1820*6236dae4SAndroid Build Coastguard Worker
1821*6236dae4SAndroid Build Coastguard Worker
wolfssl_cleanup(void)1822*6236dae4SAndroid Build Coastguard Worker static void wolfssl_cleanup(void)
1823*6236dae4SAndroid Build Coastguard Worker {
1824*6236dae4SAndroid Build Coastguard Worker wolfssl_bio_cf_free_methods();
1825*6236dae4SAndroid Build Coastguard Worker wolfSSL_Cleanup();
1826*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_EXTRA
1827*6236dae4SAndroid Build Coastguard Worker Curl_tls_keylog_close();
1828*6236dae4SAndroid Build Coastguard Worker #endif
1829*6236dae4SAndroid Build Coastguard Worker }
1830*6236dae4SAndroid Build Coastguard Worker
1831*6236dae4SAndroid Build Coastguard Worker
wolfssl_data_pending(struct Curl_cfilter * cf,const struct Curl_easy * data)1832*6236dae4SAndroid Build Coastguard Worker static bool wolfssl_data_pending(struct Curl_cfilter *cf,
1833*6236dae4SAndroid Build Coastguard Worker const struct Curl_easy *data)
1834*6236dae4SAndroid Build Coastguard Worker {
1835*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *ctx = cf->ctx;
1836*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend;
1837*6236dae4SAndroid Build Coastguard Worker
1838*6236dae4SAndroid Build Coastguard Worker (void)data;
1839*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(ctx && ctx->backend);
1840*6236dae4SAndroid Build Coastguard Worker
1841*6236dae4SAndroid Build Coastguard Worker backend = (struct wolfssl_ctx *)ctx->backend;
1842*6236dae4SAndroid Build Coastguard Worker if(backend->handle) /* SSL is in use */
1843*6236dae4SAndroid Build Coastguard Worker return wolfSSL_pending(backend->handle);
1844*6236dae4SAndroid Build Coastguard Worker else
1845*6236dae4SAndroid Build Coastguard Worker return FALSE;
1846*6236dae4SAndroid Build Coastguard Worker }
1847*6236dae4SAndroid Build Coastguard Worker
1848*6236dae4SAndroid Build Coastguard Worker static CURLcode
wolfssl_connect_common(struct Curl_cfilter * cf,struct Curl_easy * data,bool nonblocking,bool * done)1849*6236dae4SAndroid Build Coastguard Worker wolfssl_connect_common(struct Curl_cfilter *cf,
1850*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
1851*6236dae4SAndroid Build Coastguard Worker bool nonblocking,
1852*6236dae4SAndroid Build Coastguard Worker bool *done)
1853*6236dae4SAndroid Build Coastguard Worker {
1854*6236dae4SAndroid Build Coastguard Worker CURLcode result;
1855*6236dae4SAndroid Build Coastguard Worker struct ssl_connect_data *connssl = cf->ctx;
1856*6236dae4SAndroid Build Coastguard Worker curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
1857*6236dae4SAndroid Build Coastguard Worker
1858*6236dae4SAndroid Build Coastguard Worker /* check if the connection has already been established */
1859*6236dae4SAndroid Build Coastguard Worker if(ssl_connection_complete == connssl->state) {
1860*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1861*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1862*6236dae4SAndroid Build Coastguard Worker }
1863*6236dae4SAndroid Build Coastguard Worker
1864*6236dae4SAndroid Build Coastguard Worker if(ssl_connect_1 == connssl->connecting_state) {
1865*6236dae4SAndroid Build Coastguard Worker /* Find out how much more time we are allowed */
1866*6236dae4SAndroid Build Coastguard Worker const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
1867*6236dae4SAndroid Build Coastguard Worker
1868*6236dae4SAndroid Build Coastguard Worker if(timeout_ms < 0) {
1869*6236dae4SAndroid Build Coastguard Worker /* no need to continue if time already is up */
1870*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL connection timeout");
1871*6236dae4SAndroid Build Coastguard Worker return CURLE_OPERATION_TIMEDOUT;
1872*6236dae4SAndroid Build Coastguard Worker }
1873*6236dae4SAndroid Build Coastguard Worker
1874*6236dae4SAndroid Build Coastguard Worker result = wolfssl_connect_step1(cf, data);
1875*6236dae4SAndroid Build Coastguard Worker if(result)
1876*6236dae4SAndroid Build Coastguard Worker return result;
1877*6236dae4SAndroid Build Coastguard Worker }
1878*6236dae4SAndroid Build Coastguard Worker
1879*6236dae4SAndroid Build Coastguard Worker while(ssl_connect_2 == connssl->connecting_state) {
1880*6236dae4SAndroid Build Coastguard Worker
1881*6236dae4SAndroid Build Coastguard Worker /* check allowed time left */
1882*6236dae4SAndroid Build Coastguard Worker const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
1883*6236dae4SAndroid Build Coastguard Worker
1884*6236dae4SAndroid Build Coastguard Worker if(timeout_ms < 0) {
1885*6236dae4SAndroid Build Coastguard Worker /* no need to continue if time already is up */
1886*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL connection timeout");
1887*6236dae4SAndroid Build Coastguard Worker return CURLE_OPERATION_TIMEDOUT;
1888*6236dae4SAndroid Build Coastguard Worker }
1889*6236dae4SAndroid Build Coastguard Worker
1890*6236dae4SAndroid Build Coastguard Worker /* if ssl is expecting something, check if it is available. */
1891*6236dae4SAndroid Build Coastguard Worker if(connssl->io_need) {
1892*6236dae4SAndroid Build Coastguard Worker curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
1893*6236dae4SAndroid Build Coastguard Worker sockfd : CURL_SOCKET_BAD;
1894*6236dae4SAndroid Build Coastguard Worker curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
1895*6236dae4SAndroid Build Coastguard Worker sockfd : CURL_SOCKET_BAD;
1896*6236dae4SAndroid Build Coastguard Worker int what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
1897*6236dae4SAndroid Build Coastguard Worker nonblocking ? 0 : timeout_ms);
1898*6236dae4SAndroid Build Coastguard Worker if(what < 0) {
1899*6236dae4SAndroid Build Coastguard Worker /* fatal error */
1900*6236dae4SAndroid Build Coastguard Worker failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1901*6236dae4SAndroid Build Coastguard Worker return CURLE_SSL_CONNECT_ERROR;
1902*6236dae4SAndroid Build Coastguard Worker }
1903*6236dae4SAndroid Build Coastguard Worker else if(0 == what) {
1904*6236dae4SAndroid Build Coastguard Worker if(nonblocking) {
1905*6236dae4SAndroid Build Coastguard Worker *done = FALSE;
1906*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1907*6236dae4SAndroid Build Coastguard Worker }
1908*6236dae4SAndroid Build Coastguard Worker else {
1909*6236dae4SAndroid Build Coastguard Worker /* timeout */
1910*6236dae4SAndroid Build Coastguard Worker failf(data, "SSL connection timeout");
1911*6236dae4SAndroid Build Coastguard Worker return CURLE_OPERATION_TIMEDOUT;
1912*6236dae4SAndroid Build Coastguard Worker }
1913*6236dae4SAndroid Build Coastguard Worker }
1914*6236dae4SAndroid Build Coastguard Worker /* socket is readable or writable */
1915*6236dae4SAndroid Build Coastguard Worker }
1916*6236dae4SAndroid Build Coastguard Worker
1917*6236dae4SAndroid Build Coastguard Worker /* Run transaction, and return to the caller if it failed or if
1918*6236dae4SAndroid Build Coastguard Worker * this connection is part of a multi handle and this loop would
1919*6236dae4SAndroid Build Coastguard Worker * execute again. This permits the owner of a multi handle to
1920*6236dae4SAndroid Build Coastguard Worker * abort a connection attempt before step2 has completed while
1921*6236dae4SAndroid Build Coastguard Worker * ensuring that a client using select() or epoll() will always
1922*6236dae4SAndroid Build Coastguard Worker * have a valid fdset to wait on.
1923*6236dae4SAndroid Build Coastguard Worker */
1924*6236dae4SAndroid Build Coastguard Worker result = wolfssl_connect_step2(cf, data);
1925*6236dae4SAndroid Build Coastguard Worker if(result || (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
1926*6236dae4SAndroid Build Coastguard Worker return result;
1927*6236dae4SAndroid Build Coastguard Worker } /* repeat step2 until all transactions are done. */
1928*6236dae4SAndroid Build Coastguard Worker
1929*6236dae4SAndroid Build Coastguard Worker if(ssl_connect_3 == connssl->connecting_state) {
1930*6236dae4SAndroid Build Coastguard Worker /* In other backends, this is where we verify the certificate, but
1931*6236dae4SAndroid Build Coastguard Worker * wolfSSL already does that as part of the handshake. */
1932*6236dae4SAndroid Build Coastguard Worker connssl->connecting_state = ssl_connect_done;
1933*6236dae4SAndroid Build Coastguard Worker }
1934*6236dae4SAndroid Build Coastguard Worker
1935*6236dae4SAndroid Build Coastguard Worker if(ssl_connect_done == connssl->connecting_state) {
1936*6236dae4SAndroid Build Coastguard Worker connssl->state = ssl_connection_complete;
1937*6236dae4SAndroid Build Coastguard Worker *done = TRUE;
1938*6236dae4SAndroid Build Coastguard Worker }
1939*6236dae4SAndroid Build Coastguard Worker else
1940*6236dae4SAndroid Build Coastguard Worker *done = FALSE;
1941*6236dae4SAndroid Build Coastguard Worker
1942*6236dae4SAndroid Build Coastguard Worker /* Reset our connect state machine */
1943*6236dae4SAndroid Build Coastguard Worker connssl->connecting_state = ssl_connect_1;
1944*6236dae4SAndroid Build Coastguard Worker
1945*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1946*6236dae4SAndroid Build Coastguard Worker }
1947*6236dae4SAndroid Build Coastguard Worker
1948*6236dae4SAndroid Build Coastguard Worker
wolfssl_connect_nonblocking(struct Curl_cfilter * cf,struct Curl_easy * data,bool * done)1949*6236dae4SAndroid Build Coastguard Worker static CURLcode wolfssl_connect_nonblocking(struct Curl_cfilter *cf,
1950*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data,
1951*6236dae4SAndroid Build Coastguard Worker bool *done)
1952*6236dae4SAndroid Build Coastguard Worker {
1953*6236dae4SAndroid Build Coastguard Worker return wolfssl_connect_common(cf, data, TRUE, done);
1954*6236dae4SAndroid Build Coastguard Worker }
1955*6236dae4SAndroid Build Coastguard Worker
1956*6236dae4SAndroid Build Coastguard Worker
wolfssl_connect(struct Curl_cfilter * cf,struct Curl_easy * data)1957*6236dae4SAndroid Build Coastguard Worker static CURLcode wolfssl_connect(struct Curl_cfilter *cf,
1958*6236dae4SAndroid Build Coastguard Worker struct Curl_easy *data)
1959*6236dae4SAndroid Build Coastguard Worker {
1960*6236dae4SAndroid Build Coastguard Worker CURLcode result;
1961*6236dae4SAndroid Build Coastguard Worker bool done = FALSE;
1962*6236dae4SAndroid Build Coastguard Worker
1963*6236dae4SAndroid Build Coastguard Worker result = wolfssl_connect_common(cf, data, FALSE, &done);
1964*6236dae4SAndroid Build Coastguard Worker if(result)
1965*6236dae4SAndroid Build Coastguard Worker return result;
1966*6236dae4SAndroid Build Coastguard Worker
1967*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(done);
1968*6236dae4SAndroid Build Coastguard Worker
1969*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1970*6236dae4SAndroid Build Coastguard Worker }
1971*6236dae4SAndroid Build Coastguard Worker
wolfssl_random(struct Curl_easy * data,unsigned char * entropy,size_t length)1972*6236dae4SAndroid Build Coastguard Worker static CURLcode wolfssl_random(struct Curl_easy *data,
1973*6236dae4SAndroid Build Coastguard Worker unsigned char *entropy, size_t length)
1974*6236dae4SAndroid Build Coastguard Worker {
1975*6236dae4SAndroid Build Coastguard Worker WC_RNG rng;
1976*6236dae4SAndroid Build Coastguard Worker (void)data;
1977*6236dae4SAndroid Build Coastguard Worker if(wc_InitRng(&rng))
1978*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
1979*6236dae4SAndroid Build Coastguard Worker if(length > UINT_MAX)
1980*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
1981*6236dae4SAndroid Build Coastguard Worker if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length))
1982*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
1983*6236dae4SAndroid Build Coastguard Worker if(wc_FreeRng(&rng))
1984*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
1985*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
1986*6236dae4SAndroid Build Coastguard Worker }
1987*6236dae4SAndroid Build Coastguard Worker
wolfssl_sha256sum(const unsigned char * tmp,size_t tmplen,unsigned char * sha256sum,size_t unused)1988*6236dae4SAndroid Build Coastguard Worker static CURLcode wolfssl_sha256sum(const unsigned char *tmp, /* input */
1989*6236dae4SAndroid Build Coastguard Worker size_t tmplen,
1990*6236dae4SAndroid Build Coastguard Worker unsigned char *sha256sum /* output */,
1991*6236dae4SAndroid Build Coastguard Worker size_t unused)
1992*6236dae4SAndroid Build Coastguard Worker {
1993*6236dae4SAndroid Build Coastguard Worker wc_Sha256 SHA256pw;
1994*6236dae4SAndroid Build Coastguard Worker (void)unused;
1995*6236dae4SAndroid Build Coastguard Worker if(wc_InitSha256(&SHA256pw))
1996*6236dae4SAndroid Build Coastguard Worker return CURLE_FAILED_INIT;
1997*6236dae4SAndroid Build Coastguard Worker wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen);
1998*6236dae4SAndroid Build Coastguard Worker wc_Sha256Final(&SHA256pw, sha256sum);
1999*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
2000*6236dae4SAndroid Build Coastguard Worker }
2001*6236dae4SAndroid Build Coastguard Worker
wolfssl_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)2002*6236dae4SAndroid Build Coastguard Worker static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
2003*6236dae4SAndroid Build Coastguard Worker CURLINFO info UNUSED_PARAM)
2004*6236dae4SAndroid Build Coastguard Worker {
2005*6236dae4SAndroid Build Coastguard Worker struct wolfssl_ctx *backend =
2006*6236dae4SAndroid Build Coastguard Worker (struct wolfssl_ctx *)connssl->backend;
2007*6236dae4SAndroid Build Coastguard Worker (void)info;
2008*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(backend);
2009*6236dae4SAndroid Build Coastguard Worker return backend->handle;
2010*6236dae4SAndroid Build Coastguard Worker }
2011*6236dae4SAndroid Build Coastguard Worker
2012*6236dae4SAndroid Build Coastguard Worker const struct Curl_ssl Curl_ssl_wolfssl = {
2013*6236dae4SAndroid Build Coastguard Worker { CURLSSLBACKEND_WOLFSSL, "wolfssl" }, /* info */
2014*6236dae4SAndroid Build Coastguard Worker
2015*6236dae4SAndroid Build Coastguard Worker #ifdef KEEP_PEER_CERT
2016*6236dae4SAndroid Build Coastguard Worker SSLSUPP_PINNEDPUBKEY |
2017*6236dae4SAndroid Build Coastguard Worker #endif
2018*6236dae4SAndroid Build Coastguard Worker #ifdef USE_BIO_CHAIN
2019*6236dae4SAndroid Build Coastguard Worker SSLSUPP_HTTPS_PROXY |
2020*6236dae4SAndroid Build Coastguard Worker #endif
2021*6236dae4SAndroid Build Coastguard Worker SSLSUPP_CA_PATH |
2022*6236dae4SAndroid Build Coastguard Worker SSLSUPP_CAINFO_BLOB |
2023*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
2024*6236dae4SAndroid Build Coastguard Worker SSLSUPP_ECH |
2025*6236dae4SAndroid Build Coastguard Worker #endif
2026*6236dae4SAndroid Build Coastguard Worker SSLSUPP_SSL_CTX |
2027*6236dae4SAndroid Build Coastguard Worker #ifdef WOLFSSL_TLS13
2028*6236dae4SAndroid Build Coastguard Worker SSLSUPP_TLS13_CIPHERSUITES |
2029*6236dae4SAndroid Build Coastguard Worker #endif
2030*6236dae4SAndroid Build Coastguard Worker SSLSUPP_CA_CACHE |
2031*6236dae4SAndroid Build Coastguard Worker SSLSUPP_CIPHER_LIST,
2032*6236dae4SAndroid Build Coastguard Worker
2033*6236dae4SAndroid Build Coastguard Worker sizeof(struct wolfssl_ctx),
2034*6236dae4SAndroid Build Coastguard Worker
2035*6236dae4SAndroid Build Coastguard Worker wolfssl_init, /* init */
2036*6236dae4SAndroid Build Coastguard Worker wolfssl_cleanup, /* cleanup */
2037*6236dae4SAndroid Build Coastguard Worker wolfssl_version, /* version */
2038*6236dae4SAndroid Build Coastguard Worker Curl_none_check_cxn, /* check_cxn */
2039*6236dae4SAndroid Build Coastguard Worker wolfssl_shutdown, /* shutdown */
2040*6236dae4SAndroid Build Coastguard Worker wolfssl_data_pending, /* data_pending */
2041*6236dae4SAndroid Build Coastguard Worker wolfssl_random, /* random */
2042*6236dae4SAndroid Build Coastguard Worker Curl_none_cert_status_request, /* cert_status_request */
2043*6236dae4SAndroid Build Coastguard Worker wolfssl_connect, /* connect */
2044*6236dae4SAndroid Build Coastguard Worker wolfssl_connect_nonblocking, /* connect_nonblocking */
2045*6236dae4SAndroid Build Coastguard Worker Curl_ssl_adjust_pollset, /* adjust_pollset */
2046*6236dae4SAndroid Build Coastguard Worker wolfssl_get_internals, /* get_internals */
2047*6236dae4SAndroid Build Coastguard Worker wolfssl_close, /* close_one */
2048*6236dae4SAndroid Build Coastguard Worker Curl_none_close_all, /* close_all */
2049*6236dae4SAndroid Build Coastguard Worker Curl_none_set_engine, /* set_engine */
2050*6236dae4SAndroid Build Coastguard Worker Curl_none_set_engine_default, /* set_engine_default */
2051*6236dae4SAndroid Build Coastguard Worker Curl_none_engines_list, /* engines_list */
2052*6236dae4SAndroid Build Coastguard Worker Curl_none_false_start, /* false_start */
2053*6236dae4SAndroid Build Coastguard Worker wolfssl_sha256sum, /* sha256sum */
2054*6236dae4SAndroid Build Coastguard Worker NULL, /* associate_connection */
2055*6236dae4SAndroid Build Coastguard Worker NULL, /* disassociate_connection */
2056*6236dae4SAndroid Build Coastguard Worker wolfssl_recv, /* recv decrypted data */
2057*6236dae4SAndroid Build Coastguard Worker wolfssl_send, /* send data to encrypt */
2058*6236dae4SAndroid Build Coastguard Worker NULL, /* get_channel_binding */
2059*6236dae4SAndroid Build Coastguard Worker };
2060*6236dae4SAndroid Build Coastguard Worker
2061*6236dae4SAndroid Build Coastguard Worker #endif
2062