xref: /aosp_15_r20/external/curl/lib/vtls/openssl.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
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 OpenSSL-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 #include "curl_setup.h"
31*6236dae4SAndroid Build Coastguard Worker 
32*6236dae4SAndroid Build Coastguard Worker #if defined(USE_QUICHE) || defined(USE_OPENSSL)
33*6236dae4SAndroid Build Coastguard Worker 
34*6236dae4SAndroid Build Coastguard Worker #include <limits.h>
35*6236dae4SAndroid Build Coastguard Worker 
36*6236dae4SAndroid Build Coastguard Worker /* Wincrypt must be included before anything that could include OpenSSL. */
37*6236dae4SAndroid Build Coastguard Worker #if defined(USE_WIN32_CRYPTO)
38*6236dae4SAndroid Build Coastguard Worker #include <wincrypt.h>
39*6236dae4SAndroid Build Coastguard Worker /* Undefine wincrypt conflicting symbols for BoringSSL. */
40*6236dae4SAndroid Build Coastguard Worker #undef X509_NAME
41*6236dae4SAndroid Build Coastguard Worker #undef X509_EXTENSIONS
42*6236dae4SAndroid Build Coastguard Worker #undef PKCS7_ISSUER_AND_SERIAL
43*6236dae4SAndroid Build Coastguard Worker #undef PKCS7_SIGNER_INFO
44*6236dae4SAndroid Build Coastguard Worker #undef OCSP_REQUEST
45*6236dae4SAndroid Build Coastguard Worker #undef OCSP_RESPONSE
46*6236dae4SAndroid Build Coastguard Worker #endif
47*6236dae4SAndroid Build Coastguard Worker 
48*6236dae4SAndroid Build Coastguard Worker #include "urldata.h"
49*6236dae4SAndroid Build Coastguard Worker #include "sendf.h"
50*6236dae4SAndroid Build Coastguard Worker #include "formdata.h" /* for the boundary function */
51*6236dae4SAndroid Build Coastguard Worker #include "url.h" /* for the ssl config check function */
52*6236dae4SAndroid Build Coastguard Worker #include "inet_pton.h"
53*6236dae4SAndroid Build Coastguard Worker #include "openssl.h"
54*6236dae4SAndroid Build Coastguard Worker #include "connect.h"
55*6236dae4SAndroid Build Coastguard Worker #include "slist.h"
56*6236dae4SAndroid Build Coastguard Worker #include "select.h"
57*6236dae4SAndroid Build Coastguard Worker #include "vtls.h"
58*6236dae4SAndroid Build Coastguard Worker #include "vtls_int.h"
59*6236dae4SAndroid Build Coastguard Worker #include "vauth/vauth.h"
60*6236dae4SAndroid Build Coastguard Worker #include "keylog.h"
61*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
62*6236dae4SAndroid Build Coastguard Worker #include "hostcheck.h"
63*6236dae4SAndroid Build Coastguard Worker #include "multiif.h"
64*6236dae4SAndroid Build Coastguard Worker #include "strerror.h"
65*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
66*6236dae4SAndroid Build Coastguard Worker 
67*6236dae4SAndroid Build Coastguard Worker #include <openssl/ssl.h>
68*6236dae4SAndroid Build Coastguard Worker #include <openssl/rand.h>
69*6236dae4SAndroid Build Coastguard Worker #include <openssl/x509v3.h>
70*6236dae4SAndroid Build Coastguard Worker #ifndef OPENSSL_NO_DSA
71*6236dae4SAndroid Build Coastguard Worker #include <openssl/dsa.h>
72*6236dae4SAndroid Build Coastguard Worker #endif
73*6236dae4SAndroid Build Coastguard Worker #include <openssl/dh.h>
74*6236dae4SAndroid Build Coastguard Worker #include <openssl/err.h>
75*6236dae4SAndroid Build Coastguard Worker #include <openssl/md5.h>
76*6236dae4SAndroid Build Coastguard Worker #include <openssl/conf.h>
77*6236dae4SAndroid Build Coastguard Worker #include <openssl/bn.h>
78*6236dae4SAndroid Build Coastguard Worker #include <openssl/rsa.h>
79*6236dae4SAndroid Build Coastguard Worker #include <openssl/bio.h>
80*6236dae4SAndroid Build Coastguard Worker #include <openssl/buffer.h>
81*6236dae4SAndroid Build Coastguard Worker #include <openssl/pkcs12.h>
82*6236dae4SAndroid Build Coastguard Worker #include <openssl/tls1.h>
83*6236dae4SAndroid Build Coastguard Worker #include <openssl/evp.h>
84*6236dae4SAndroid Build Coastguard Worker 
85*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
86*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
87*6236dae4SAndroid Build Coastguard Worker #  include <openssl/ech.h>
88*6236dae4SAndroid Build Coastguard Worker # endif
89*6236dae4SAndroid Build Coastguard Worker # include "curl_base64.h"
90*6236dae4SAndroid Build Coastguard Worker # define ECH_ENABLED(__data__) \
91*6236dae4SAndroid Build Coastguard Worker     (__data__->set.tls_ech && \
92*6236dae4SAndroid Build Coastguard Worker      !(__data__->set.tls_ech & CURLECH_DISABLE)\
93*6236dae4SAndroid Build Coastguard Worker     )
94*6236dae4SAndroid Build Coastguard Worker #endif /* USE_ECH */
95*6236dae4SAndroid Build Coastguard Worker 
96*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP)
97*6236dae4SAndroid Build Coastguard Worker #include <openssl/ocsp.h>
98*6236dae4SAndroid Build Coastguard Worker #endif
99*6236dae4SAndroid Build Coastguard Worker 
100*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */     \
101*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE)
102*6236dae4SAndroid Build Coastguard Worker #define USE_OPENSSL_ENGINE
103*6236dae4SAndroid Build Coastguard Worker #include <openssl/engine.h>
104*6236dae4SAndroid Build Coastguard Worker #endif
105*6236dae4SAndroid Build Coastguard Worker 
106*6236dae4SAndroid Build Coastguard Worker #include "warnless.h"
107*6236dae4SAndroid Build Coastguard Worker 
108*6236dae4SAndroid Build Coastguard Worker /* The last #include files should be: */
109*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
110*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
111*6236dae4SAndroid Build Coastguard Worker 
112*6236dae4SAndroid Build Coastguard Worker #ifndef ARRAYSIZE
113*6236dae4SAndroid Build Coastguard Worker #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
114*6236dae4SAndroid Build Coastguard Worker #endif
115*6236dae4SAndroid Build Coastguard Worker 
116*6236dae4SAndroid Build Coastguard Worker /* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS
117*6236dae4SAndroid Build Coastguard Worker    renegotiations when built with BoringSSL. Renegotiating is non-compliant
118*6236dae4SAndroid Build Coastguard Worker    with HTTP/2 and "an extremely dangerous protocol feature". Beware.
119*6236dae4SAndroid Build Coastguard Worker 
120*6236dae4SAndroid Build Coastguard Worker #define ALLOW_RENEG 1
121*6236dae4SAndroid Build Coastguard Worker  */
122*6236dae4SAndroid Build Coastguard Worker 
123*6236dae4SAndroid Build Coastguard Worker #ifndef OPENSSL_VERSION_NUMBER
124*6236dae4SAndroid Build Coastguard Worker #error "OPENSSL_VERSION_NUMBER not defined"
125*6236dae4SAndroid Build Coastguard Worker #endif
126*6236dae4SAndroid Build Coastguard Worker 
127*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
128*6236dae4SAndroid Build Coastguard Worker #include <openssl/ui.h>
129*6236dae4SAndroid Build Coastguard Worker #endif
130*6236dae4SAndroid Build Coastguard Worker 
131*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x00909000L
132*6236dae4SAndroid Build Coastguard Worker #define SSL_METHOD_QUAL const
133*6236dae4SAndroid Build Coastguard Worker #else
134*6236dae4SAndroid Build Coastguard Worker #define SSL_METHOD_QUAL
135*6236dae4SAndroid Build Coastguard Worker #endif
136*6236dae4SAndroid Build Coastguard Worker 
137*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
138*6236dae4SAndroid Build Coastguard Worker #define HAVE_ERR_REMOVE_THREAD_STATE 1
139*6236dae4SAndroid Build Coastguard Worker #endif
140*6236dae4SAndroid Build Coastguard Worker 
141*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \
142*6236dae4SAndroid Build Coastguard Worker     !(defined(LIBRESSL_VERSION_NUMBER) && \
143*6236dae4SAndroid Build Coastguard Worker       LIBRESSL_VERSION_NUMBER < 0x20700000L)
144*6236dae4SAndroid Build Coastguard Worker #define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
145*6236dae4SAndroid Build Coastguard Worker #define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */
146*6236dae4SAndroid Build Coastguard Worker #define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */
147*6236dae4SAndroid Build Coastguard Worker #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */
148*6236dae4SAndroid Build Coastguard Worker #define CONST_EXTS const
149*6236dae4SAndroid Build Coastguard Worker #define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1
150*6236dae4SAndroid Build Coastguard Worker 
151*6236dae4SAndroid Build Coastguard Worker /* funny typecast define due to difference in API */
152*6236dae4SAndroid Build Coastguard Worker #ifdef LIBRESSL_VERSION_NUMBER
153*6236dae4SAndroid Build Coastguard Worker #define ARG2_X509_signature_print (X509_ALGOR *)
154*6236dae4SAndroid Build Coastguard Worker #else
155*6236dae4SAndroid Build Coastguard Worker #define ARG2_X509_signature_print
156*6236dae4SAndroid Build Coastguard Worker #endif
157*6236dae4SAndroid Build Coastguard Worker 
158*6236dae4SAndroid Build Coastguard Worker #else
159*6236dae4SAndroid Build Coastguard Worker /* For OpenSSL before 1.1.0 */
160*6236dae4SAndroid Build Coastguard Worker #define ASN1_STRING_get0_data(x) ASN1_STRING_data(x)
161*6236dae4SAndroid Build Coastguard Worker #define X509_get0_notBefore(x) X509_get_notBefore(x)
162*6236dae4SAndroid Build Coastguard Worker #define X509_get0_notAfter(x) X509_get_notAfter(x)
163*6236dae4SAndroid Build Coastguard Worker #define CONST_EXTS /* nope */
164*6236dae4SAndroid Build Coastguard Worker #ifndef LIBRESSL_VERSION_NUMBER
165*6236dae4SAndroid Build Coastguard Worker #define OpenSSL_version_num() SSLeay()
166*6236dae4SAndroid Build Coastguard Worker #endif
167*6236dae4SAndroid Build Coastguard Worker #endif
168*6236dae4SAndroid Build Coastguard Worker 
169*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
170*6236dae4SAndroid Build Coastguard Worker     !(defined(LIBRESSL_VERSION_NUMBER) && \
171*6236dae4SAndroid Build Coastguard Worker       LIBRESSL_VERSION_NUMBER < 0x20700000L)
172*6236dae4SAndroid Build Coastguard Worker #define HAVE_X509_GET0_SIGNATURE 1
173*6236dae4SAndroid Build Coastguard Worker #endif
174*6236dae4SAndroid Build Coastguard Worker 
175*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */
176*6236dae4SAndroid Build Coastguard Worker #define HAVE_SSL_GET_SHUTDOWN 1
177*6236dae4SAndroid Build Coastguard Worker #endif
178*6236dae4SAndroid Build Coastguard Worker 
179*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x10002003L && \
180*6236dae4SAndroid Build Coastguard Worker   OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \
181*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_COMP)
182*6236dae4SAndroid Build Coastguard Worker #define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1
183*6236dae4SAndroid Build Coastguard Worker #endif
184*6236dae4SAndroid Build Coastguard Worker 
185*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER < 0x0090808fL)
186*6236dae4SAndroid Build Coastguard Worker /* not present in older OpenSSL */
187*6236dae4SAndroid Build Coastguard Worker #define OPENSSL_load_builtin_modules(x)
188*6236dae4SAndroid Build Coastguard Worker #endif
189*6236dae4SAndroid Build Coastguard Worker 
190*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
191*6236dae4SAndroid Build Coastguard Worker #define HAVE_EVP_PKEY_GET_PARAMS 1
192*6236dae4SAndroid Build Coastguard Worker #endif
193*6236dae4SAndroid Build Coastguard Worker 
194*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_EVP_PKEY_GET_PARAMS
195*6236dae4SAndroid Build Coastguard Worker #include <openssl/core_names.h>
196*6236dae4SAndroid Build Coastguard Worker #define DECLARE_PKEY_PARAM_BIGNUM(name) BIGNUM *name = NULL
197*6236dae4SAndroid Build Coastguard Worker #define FREE_PKEY_PARAM_BIGNUM(name) BN_clear_free(name)
198*6236dae4SAndroid Build Coastguard Worker #else
199*6236dae4SAndroid Build Coastguard Worker #define DECLARE_PKEY_PARAM_BIGNUM(name) const BIGNUM *name
200*6236dae4SAndroid Build Coastguard Worker #define FREE_PKEY_PARAM_BIGNUM(name)
201*6236dae4SAndroid Build Coastguard Worker #endif
202*6236dae4SAndroid Build Coastguard Worker 
203*6236dae4SAndroid Build Coastguard Worker /*
204*6236dae4SAndroid Build Coastguard Worker  * Whether SSL_CTX_set_keylog_callback is available.
205*6236dae4SAndroid Build Coastguard Worker  * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287
206*6236dae4SAndroid Build Coastguard Worker  * BoringSSL: supported since d28f59c27bac (committed 2015-11-19)
207*6236dae4SAndroid Build Coastguard Worker  * LibreSSL: not supported. 3.5.0+ has a stub function that does nothing.
208*6236dae4SAndroid Build Coastguard Worker  */
209*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
210*6236dae4SAndroid Build Coastguard Worker      !defined(LIBRESSL_VERSION_NUMBER)) || \
211*6236dae4SAndroid Build Coastguard Worker     defined(OPENSSL_IS_BORINGSSL)
212*6236dae4SAndroid Build Coastguard Worker #define HAVE_KEYLOG_CALLBACK
213*6236dae4SAndroid Build Coastguard Worker #endif
214*6236dae4SAndroid Build Coastguard Worker 
215*6236dae4SAndroid Build Coastguard Worker /* Whether SSL_CTX_set_ciphersuites is available.
216*6236dae4SAndroid Build Coastguard Worker  * OpenSSL: supported since 1.1.1 (commit a53b5be6a05)
217*6236dae4SAndroid Build Coastguard Worker  * BoringSSL: no
218*6236dae4SAndroid Build Coastguard Worker  * LibreSSL: supported since 3.4.1 (released 2021-10-14)
219*6236dae4SAndroid Build Coastguard Worker  */
220*6236dae4SAndroid Build Coastguard Worker #if ((OPENSSL_VERSION_NUMBER >= 0x10101000L && \
221*6236dae4SAndroid Build Coastguard Worker       !defined(LIBRESSL_VERSION_NUMBER)) || \
222*6236dae4SAndroid Build Coastguard Worker      (defined(LIBRESSL_VERSION_NUMBER) && \
223*6236dae4SAndroid Build Coastguard Worker       LIBRESSL_VERSION_NUMBER >= 0x3040100fL)) && \
224*6236dae4SAndroid Build Coastguard Worker     !defined(OPENSSL_IS_BORINGSSL)
225*6236dae4SAndroid Build Coastguard Worker   #define HAVE_SSL_CTX_SET_CIPHERSUITES
226*6236dae4SAndroid Build Coastguard Worker   #if !defined(OPENSSL_IS_AWSLC)
227*6236dae4SAndroid Build Coastguard Worker     #define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
228*6236dae4SAndroid Build Coastguard Worker   #endif
229*6236dae4SAndroid Build Coastguard Worker #endif
230*6236dae4SAndroid Build Coastguard Worker 
231*6236dae4SAndroid Build Coastguard Worker /*
232*6236dae4SAndroid Build Coastguard Worker  * Whether SSL_CTX_set1_curves_list is available.
233*6236dae4SAndroid Build Coastguard Worker  * OpenSSL: supported since 1.0.2, see
234*6236dae4SAndroid Build Coastguard Worker  *   https://docs.openssl.org/master/man3/SSL_CTX_set1_curves/
235*6236dae4SAndroid Build Coastguard Worker  * BoringSSL: supported since 5fd1807d95f7 (committed 2016-09-30)
236*6236dae4SAndroid Build Coastguard Worker  * LibreSSL: since 2.5.3 (April 12, 2017)
237*6236dae4SAndroid Build Coastguard Worker  */
238*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10002000L) ||  \
239*6236dae4SAndroid Build Coastguard Worker   defined(OPENSSL_IS_BORINGSSL)
240*6236dae4SAndroid Build Coastguard Worker #define HAVE_SSL_CTX_SET_EC_CURVES
241*6236dae4SAndroid Build Coastguard Worker #endif
242*6236dae4SAndroid Build Coastguard Worker 
243*6236dae4SAndroid Build Coastguard Worker #if defined(LIBRESSL_VERSION_NUMBER)
244*6236dae4SAndroid Build Coastguard Worker #define OSSL_PACKAGE "LibreSSL"
245*6236dae4SAndroid Build Coastguard Worker #elif defined(OPENSSL_IS_BORINGSSL)
246*6236dae4SAndroid Build Coastguard Worker #define OSSL_PACKAGE "BoringSSL"
247*6236dae4SAndroid Build Coastguard Worker #elif defined(OPENSSL_IS_AWSLC)
248*6236dae4SAndroid Build Coastguard Worker #define OSSL_PACKAGE "AWS-LC"
249*6236dae4SAndroid Build Coastguard Worker #else
250*6236dae4SAndroid Build Coastguard Worker # if (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || defined(USE_MSH3)
251*6236dae4SAndroid Build Coastguard Worker #   define OSSL_PACKAGE "quictls"
252*6236dae4SAndroid Build Coastguard Worker # else
253*6236dae4SAndroid Build Coastguard Worker #   define OSSL_PACKAGE "OpenSSL"
254*6236dae4SAndroid Build Coastguard Worker #endif
255*6236dae4SAndroid Build Coastguard Worker #endif
256*6236dae4SAndroid Build Coastguard Worker 
257*6236dae4SAndroid Build Coastguard Worker #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
258*6236dae4SAndroid Build Coastguard Worker typedef size_t numcert_t;
259*6236dae4SAndroid Build Coastguard Worker #else
260*6236dae4SAndroid Build Coastguard Worker typedef int numcert_t;
261*6236dae4SAndroid Build Coastguard Worker #endif
262*6236dae4SAndroid Build Coastguard Worker #define ossl_valsize_t numcert_t
263*6236dae4SAndroid Build Coastguard Worker 
264*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
265*6236dae4SAndroid Build Coastguard Worker /* up2date versions of OpenSSL maintain reasonably secure defaults without
266*6236dae4SAndroid Build Coastguard Worker  * breaking compatibility, so it is better not to override the defaults in curl
267*6236dae4SAndroid Build Coastguard Worker  */
268*6236dae4SAndroid Build Coastguard Worker #define DEFAULT_CIPHER_SELECTION NULL
269*6236dae4SAndroid Build Coastguard Worker #else
270*6236dae4SAndroid Build Coastguard Worker /* not the case with old versions of OpenSSL */
271*6236dae4SAndroid Build Coastguard Worker #define DEFAULT_CIPHER_SELECTION \
272*6236dae4SAndroid Build Coastguard Worker   "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
273*6236dae4SAndroid Build Coastguard Worker #endif
274*6236dae4SAndroid Build Coastguard Worker 
275*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPENSSL_SRP
276*6236dae4SAndroid Build Coastguard Worker /* the function exists */
277*6236dae4SAndroid Build Coastguard Worker #ifdef USE_TLS_SRP
278*6236dae4SAndroid Build Coastguard Worker /* the functionality is not disabled */
279*6236dae4SAndroid Build Coastguard Worker #define USE_OPENSSL_SRP
280*6236dae4SAndroid Build Coastguard Worker #endif
281*6236dae4SAndroid Build Coastguard Worker #endif
282*6236dae4SAndroid Build Coastguard Worker 
283*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
284*6236dae4SAndroid Build Coastguard Worker #define HAVE_RANDOM_INIT_BY_DEFAULT 1
285*6236dae4SAndroid Build Coastguard Worker #endif
286*6236dae4SAndroid Build Coastguard Worker 
287*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
288*6236dae4SAndroid Build Coastguard Worker     !(defined(LIBRESSL_VERSION_NUMBER) && \
289*6236dae4SAndroid Build Coastguard Worker       LIBRESSL_VERSION_NUMBER < 0x2070100fL) && \
290*6236dae4SAndroid Build Coastguard Worker     !defined(OPENSSL_IS_BORINGSSL) && \
291*6236dae4SAndroid Build Coastguard Worker     !defined(OPENSSL_IS_AWSLC)
292*6236dae4SAndroid Build Coastguard Worker #define HAVE_OPENSSL_VERSION
293*6236dae4SAndroid Build Coastguard Worker #endif
294*6236dae4SAndroid Build Coastguard Worker 
295*6236dae4SAndroid Build Coastguard Worker #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
296*6236dae4SAndroid Build Coastguard Worker typedef uint32_t sslerr_t;
297*6236dae4SAndroid Build Coastguard Worker #else
298*6236dae4SAndroid Build Coastguard Worker typedef unsigned long sslerr_t;
299*6236dae4SAndroid Build Coastguard Worker #endif
300*6236dae4SAndroid Build Coastguard Worker 
301*6236dae4SAndroid Build Coastguard Worker /*
302*6236dae4SAndroid Build Coastguard Worker  * Whether the OpenSSL version has the API needed to support sharing an
303*6236dae4SAndroid Build Coastguard Worker  * X509_STORE between connections. The API is:
304*6236dae4SAndroid Build Coastguard Worker  * * `X509_STORE_up_ref`       -- Introduced: OpenSSL 1.1.0.
305*6236dae4SAndroid Build Coastguard Worker  */
306*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* OpenSSL >= 1.1.0 */
307*6236dae4SAndroid Build Coastguard Worker #define HAVE_SSL_X509_STORE_SHARE
308*6236dae4SAndroid Build Coastguard Worker #endif
309*6236dae4SAndroid Build Coastguard Worker 
310*6236dae4SAndroid Build Coastguard Worker /* What API version do we use? */
311*6236dae4SAndroid Build Coastguard Worker #if defined(LIBRESSL_VERSION_NUMBER)
312*6236dae4SAndroid Build Coastguard Worker #define USE_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f)
313*6236dae4SAndroid Build Coastguard Worker #else /* !LIBRESSL_VERSION_NUMBER */
314*6236dae4SAndroid Build Coastguard Worker #define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
315*6236dae4SAndroid Build Coastguard Worker #endif /* !LIBRESSL_VERSION_NUMBER */
316*6236dae4SAndroid Build Coastguard Worker 
317*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl);
318*6236dae4SAndroid Build Coastguard Worker 
319*6236dae4SAndroid Build Coastguard Worker static CURLcode push_certinfo(struct Curl_easy *data,
320*6236dae4SAndroid Build Coastguard Worker                               BIO *mem, const char *label, int num)
321*6236dae4SAndroid Build Coastguard Worker   WARN_UNUSED_RESULT;
322*6236dae4SAndroid Build Coastguard Worker 
push_certinfo(struct Curl_easy * data,BIO * mem,const char * label,int num)323*6236dae4SAndroid Build Coastguard Worker static CURLcode push_certinfo(struct Curl_easy *data,
324*6236dae4SAndroid Build Coastguard Worker                               BIO *mem, const char *label, int num)
325*6236dae4SAndroid Build Coastguard Worker {
326*6236dae4SAndroid Build Coastguard Worker   char *ptr;
327*6236dae4SAndroid Build Coastguard Worker   long len = BIO_get_mem_data(mem, &ptr);
328*6236dae4SAndroid Build Coastguard Worker   CURLcode result = Curl_ssl_push_certinfo_len(data, num, label, ptr, len);
329*6236dae4SAndroid Build Coastguard Worker   (void)BIO_reset(mem);
330*6236dae4SAndroid Build Coastguard Worker   return result;
331*6236dae4SAndroid Build Coastguard Worker }
332*6236dae4SAndroid Build Coastguard Worker 
pubkey_show(struct Curl_easy * data,BIO * mem,int num,const char * type,const char * name,const BIGNUM * bn)333*6236dae4SAndroid Build Coastguard Worker static CURLcode pubkey_show(struct Curl_easy *data,
334*6236dae4SAndroid Build Coastguard Worker                             BIO *mem,
335*6236dae4SAndroid Build Coastguard Worker                             int num,
336*6236dae4SAndroid Build Coastguard Worker                             const char *type,
337*6236dae4SAndroid Build Coastguard Worker                             const char *name,
338*6236dae4SAndroid Build Coastguard Worker                             const BIGNUM *bn)
339*6236dae4SAndroid Build Coastguard Worker {
340*6236dae4SAndroid Build Coastguard Worker   char namebuf[32];
341*6236dae4SAndroid Build Coastguard Worker 
342*6236dae4SAndroid Build Coastguard Worker   msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
343*6236dae4SAndroid Build Coastguard Worker 
344*6236dae4SAndroid Build Coastguard Worker   if(bn)
345*6236dae4SAndroid Build Coastguard Worker     BN_print(mem, bn);
346*6236dae4SAndroid Build Coastguard Worker   return push_certinfo(data, mem, namebuf, num);
347*6236dae4SAndroid Build Coastguard Worker }
348*6236dae4SAndroid Build Coastguard Worker 
349*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_RSA_DSA_DH
350*6236dae4SAndroid Build Coastguard Worker #define print_pubkey_BN(_type, _name, _num)              \
351*6236dae4SAndroid Build Coastguard Worker   pubkey_show(data, mem, _num, #_type, #_name, _name)
352*6236dae4SAndroid Build Coastguard Worker 
353*6236dae4SAndroid Build Coastguard Worker #else
354*6236dae4SAndroid Build Coastguard Worker #define print_pubkey_BN(_type, _name, _num)    \
355*6236dae4SAndroid Build Coastguard Worker do {                              \
356*6236dae4SAndroid Build Coastguard Worker   if(_type->_name) { \
357*6236dae4SAndroid Build Coastguard Worker     pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
358*6236dae4SAndroid Build Coastguard Worker   } \
359*6236dae4SAndroid Build Coastguard Worker } while(0)
360*6236dae4SAndroid Build Coastguard Worker #endif
361*6236dae4SAndroid Build Coastguard Worker 
asn1_object_dump(ASN1_OBJECT * a,char * buf,size_t len)362*6236dae4SAndroid Build Coastguard Worker static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
363*6236dae4SAndroid Build Coastguard Worker {
364*6236dae4SAndroid Build Coastguard Worker   int i, ilen;
365*6236dae4SAndroid Build Coastguard Worker 
366*6236dae4SAndroid Build Coastguard Worker   ilen = (int)len;
367*6236dae4SAndroid Build Coastguard Worker   if(ilen < 0)
368*6236dae4SAndroid Build Coastguard Worker     return 1; /* buffer too big */
369*6236dae4SAndroid Build Coastguard Worker 
370*6236dae4SAndroid Build Coastguard Worker   i = i2t_ASN1_OBJECT(buf, ilen, a);
371*6236dae4SAndroid Build Coastguard Worker 
372*6236dae4SAndroid Build Coastguard Worker   if(i >= ilen)
373*6236dae4SAndroid Build Coastguard Worker     return 1; /* buffer too small */
374*6236dae4SAndroid Build Coastguard Worker 
375*6236dae4SAndroid Build Coastguard Worker   return 0;
376*6236dae4SAndroid Build Coastguard Worker }
377*6236dae4SAndroid Build Coastguard Worker 
X509V3_ext(struct Curl_easy * data,int certnum,CONST_EXTS STACK_OF (X509_EXTENSION)* exts)378*6236dae4SAndroid Build Coastguard Worker static CURLcode X509V3_ext(struct Curl_easy *data,
379*6236dae4SAndroid Build Coastguard Worker                            int certnum,
380*6236dae4SAndroid Build Coastguard Worker                            CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
381*6236dae4SAndroid Build Coastguard Worker {
382*6236dae4SAndroid Build Coastguard Worker   int i;
383*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
384*6236dae4SAndroid Build Coastguard Worker 
385*6236dae4SAndroid Build Coastguard Worker   if((int)sk_X509_EXTENSION_num(exts) <= 0)
386*6236dae4SAndroid Build Coastguard Worker     /* no extensions, bail out */
387*6236dae4SAndroid Build Coastguard Worker     return result;
388*6236dae4SAndroid Build Coastguard Worker 
389*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
390*6236dae4SAndroid Build Coastguard Worker     ASN1_OBJECT *obj;
391*6236dae4SAndroid Build Coastguard Worker     X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, (ossl_valsize_t)i);
392*6236dae4SAndroid Build Coastguard Worker     BUF_MEM *biomem;
393*6236dae4SAndroid Build Coastguard Worker     char namebuf[128];
394*6236dae4SAndroid Build Coastguard Worker     BIO *bio_out = BIO_new(BIO_s_mem());
395*6236dae4SAndroid Build Coastguard Worker 
396*6236dae4SAndroid Build Coastguard Worker     if(!bio_out)
397*6236dae4SAndroid Build Coastguard Worker       return result;
398*6236dae4SAndroid Build Coastguard Worker 
399*6236dae4SAndroid Build Coastguard Worker     obj = X509_EXTENSION_get_object(ext);
400*6236dae4SAndroid Build Coastguard Worker 
401*6236dae4SAndroid Build Coastguard Worker     asn1_object_dump(obj, namebuf, sizeof(namebuf));
402*6236dae4SAndroid Build Coastguard Worker 
403*6236dae4SAndroid Build Coastguard Worker     if(!X509V3_EXT_print(bio_out, ext, 0, 0))
404*6236dae4SAndroid Build Coastguard Worker       ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
405*6236dae4SAndroid Build Coastguard Worker 
406*6236dae4SAndroid Build Coastguard Worker     BIO_get_mem_ptr(bio_out, &biomem);
407*6236dae4SAndroid Build Coastguard Worker     result = Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
408*6236dae4SAndroid Build Coastguard Worker                                         biomem->length);
409*6236dae4SAndroid Build Coastguard Worker     BIO_free(bio_out);
410*6236dae4SAndroid Build Coastguard Worker     if(result)
411*6236dae4SAndroid Build Coastguard Worker       break;
412*6236dae4SAndroid Build Coastguard Worker   }
413*6236dae4SAndroid Build Coastguard Worker   return result;
414*6236dae4SAndroid Build Coastguard Worker }
415*6236dae4SAndroid Build Coastguard Worker 
ossl_certchain(struct Curl_easy * data,SSL * ssl)416*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
417*6236dae4SAndroid Build Coastguard Worker {
418*6236dae4SAndroid Build Coastguard Worker   CURLcode result;
419*6236dae4SAndroid Build Coastguard Worker   STACK_OF(X509) *sk;
420*6236dae4SAndroid Build Coastguard Worker   int i;
421*6236dae4SAndroid Build Coastguard Worker   numcert_t numcerts;
422*6236dae4SAndroid Build Coastguard Worker   BIO *mem;
423*6236dae4SAndroid Build Coastguard Worker 
424*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(ssl);
425*6236dae4SAndroid Build Coastguard Worker 
426*6236dae4SAndroid Build Coastguard Worker   sk = SSL_get_peer_cert_chain(ssl);
427*6236dae4SAndroid Build Coastguard Worker   if(!sk) {
428*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
429*6236dae4SAndroid Build Coastguard Worker   }
430*6236dae4SAndroid Build Coastguard Worker 
431*6236dae4SAndroid Build Coastguard Worker   numcerts = sk_X509_num(sk);
432*6236dae4SAndroid Build Coastguard Worker 
433*6236dae4SAndroid Build Coastguard Worker   result = Curl_ssl_init_certinfo(data, (int)numcerts);
434*6236dae4SAndroid Build Coastguard Worker   if(result)
435*6236dae4SAndroid Build Coastguard Worker     return result;
436*6236dae4SAndroid Build Coastguard Worker 
437*6236dae4SAndroid Build Coastguard Worker   mem = BIO_new(BIO_s_mem());
438*6236dae4SAndroid Build Coastguard Worker   if(!mem)
439*6236dae4SAndroid Build Coastguard Worker     result = CURLE_OUT_OF_MEMORY;
440*6236dae4SAndroid Build Coastguard Worker 
441*6236dae4SAndroid Build Coastguard Worker   for(i = 0; !result && (i < (int)numcerts); i++) {
442*6236dae4SAndroid Build Coastguard Worker     ASN1_INTEGER *num;
443*6236dae4SAndroid Build Coastguard Worker     X509 *x = sk_X509_value(sk, (ossl_valsize_t)i);
444*6236dae4SAndroid Build Coastguard Worker     EVP_PKEY *pubkey = NULL;
445*6236dae4SAndroid Build Coastguard Worker     int j;
446*6236dae4SAndroid Build Coastguard Worker     const ASN1_BIT_STRING *psig = NULL;
447*6236dae4SAndroid Build Coastguard Worker 
448*6236dae4SAndroid Build Coastguard Worker     X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
449*6236dae4SAndroid Build Coastguard Worker     result = push_certinfo(data, mem, "Subject", i);
450*6236dae4SAndroid Build Coastguard Worker     if(result)
451*6236dae4SAndroid Build Coastguard Worker       break;
452*6236dae4SAndroid Build Coastguard Worker 
453*6236dae4SAndroid Build Coastguard Worker     X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
454*6236dae4SAndroid Build Coastguard Worker     result = push_certinfo(data, mem, "Issuer", i);
455*6236dae4SAndroid Build Coastguard Worker     if(result)
456*6236dae4SAndroid Build Coastguard Worker       break;
457*6236dae4SAndroid Build Coastguard Worker 
458*6236dae4SAndroid Build Coastguard Worker     BIO_printf(mem, "%lx", X509_get_version(x));
459*6236dae4SAndroid Build Coastguard Worker     result = push_certinfo(data, mem, "Version", i);
460*6236dae4SAndroid Build Coastguard Worker     if(result)
461*6236dae4SAndroid Build Coastguard Worker       break;
462*6236dae4SAndroid Build Coastguard Worker 
463*6236dae4SAndroid Build Coastguard Worker     num = X509_get_serialNumber(x);
464*6236dae4SAndroid Build Coastguard Worker     if(num->type == V_ASN1_NEG_INTEGER)
465*6236dae4SAndroid Build Coastguard Worker       BIO_puts(mem, "-");
466*6236dae4SAndroid Build Coastguard Worker     for(j = 0; j < num->length; j++)
467*6236dae4SAndroid Build Coastguard Worker       BIO_printf(mem, "%02x", num->data[j]);
468*6236dae4SAndroid Build Coastguard Worker     result = push_certinfo(data, mem, "Serial Number", i);
469*6236dae4SAndroid Build Coastguard Worker     if(result)
470*6236dae4SAndroid Build Coastguard Worker       break;
471*6236dae4SAndroid Build Coastguard Worker 
472*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
473*6236dae4SAndroid Build Coastguard Worker     {
474*6236dae4SAndroid Build Coastguard Worker       const X509_ALGOR *sigalg = NULL;
475*6236dae4SAndroid Build Coastguard Worker       X509_PUBKEY *xpubkey = NULL;
476*6236dae4SAndroid Build Coastguard Worker       ASN1_OBJECT *pubkeyoid = NULL;
477*6236dae4SAndroid Build Coastguard Worker 
478*6236dae4SAndroid Build Coastguard Worker       X509_get0_signature(&psig, &sigalg, x);
479*6236dae4SAndroid Build Coastguard Worker       if(sigalg) {
480*6236dae4SAndroid Build Coastguard Worker         const ASN1_OBJECT *sigalgoid = NULL;
481*6236dae4SAndroid Build Coastguard Worker         X509_ALGOR_get0(&sigalgoid, NULL, NULL, sigalg);
482*6236dae4SAndroid Build Coastguard Worker         i2a_ASN1_OBJECT(mem, sigalgoid);
483*6236dae4SAndroid Build Coastguard Worker         result = push_certinfo(data, mem, "Signature Algorithm", i);
484*6236dae4SAndroid Build Coastguard Worker         if(result)
485*6236dae4SAndroid Build Coastguard Worker           break;
486*6236dae4SAndroid Build Coastguard Worker       }
487*6236dae4SAndroid Build Coastguard Worker 
488*6236dae4SAndroid Build Coastguard Worker       xpubkey = X509_get_X509_PUBKEY(x);
489*6236dae4SAndroid Build Coastguard Worker       if(xpubkey) {
490*6236dae4SAndroid Build Coastguard Worker         X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey);
491*6236dae4SAndroid Build Coastguard Worker         if(pubkeyoid) {
492*6236dae4SAndroid Build Coastguard Worker           i2a_ASN1_OBJECT(mem, pubkeyoid);
493*6236dae4SAndroid Build Coastguard Worker           result = push_certinfo(data, mem, "Public Key Algorithm", i);
494*6236dae4SAndroid Build Coastguard Worker           if(result)
495*6236dae4SAndroid Build Coastguard Worker             break;
496*6236dae4SAndroid Build Coastguard Worker         }
497*6236dae4SAndroid Build Coastguard Worker       }
498*6236dae4SAndroid Build Coastguard Worker 
499*6236dae4SAndroid Build Coastguard Worker       result = X509V3_ext(data, i, X509_get0_extensions(x));
500*6236dae4SAndroid Build Coastguard Worker       if(result)
501*6236dae4SAndroid Build Coastguard Worker         break;
502*6236dae4SAndroid Build Coastguard Worker     }
503*6236dae4SAndroid Build Coastguard Worker #else
504*6236dae4SAndroid Build Coastguard Worker     {
505*6236dae4SAndroid Build Coastguard Worker       /* before OpenSSL 1.0.2 */
506*6236dae4SAndroid Build Coastguard Worker       X509_CINF *cinf = x->cert_info;
507*6236dae4SAndroid Build Coastguard Worker 
508*6236dae4SAndroid Build Coastguard Worker       i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
509*6236dae4SAndroid Build Coastguard Worker       result = push_certinfo(data, mem, "Signature Algorithm", i);
510*6236dae4SAndroid Build Coastguard Worker 
511*6236dae4SAndroid Build Coastguard Worker       if(!result) {
512*6236dae4SAndroid Build Coastguard Worker         i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
513*6236dae4SAndroid Build Coastguard Worker         result = push_certinfo(data, mem, "Public Key Algorithm", i);
514*6236dae4SAndroid Build Coastguard Worker       }
515*6236dae4SAndroid Build Coastguard Worker 
516*6236dae4SAndroid Build Coastguard Worker       if(!result)
517*6236dae4SAndroid Build Coastguard Worker         result = X509V3_ext(data, i, cinf->extensions);
518*6236dae4SAndroid Build Coastguard Worker 
519*6236dae4SAndroid Build Coastguard Worker       if(result)
520*6236dae4SAndroid Build Coastguard Worker         break;
521*6236dae4SAndroid Build Coastguard Worker 
522*6236dae4SAndroid Build Coastguard Worker       psig = x->signature;
523*6236dae4SAndroid Build Coastguard Worker     }
524*6236dae4SAndroid Build Coastguard Worker #endif
525*6236dae4SAndroid Build Coastguard Worker 
526*6236dae4SAndroid Build Coastguard Worker     ASN1_TIME_print(mem, X509_get0_notBefore(x));
527*6236dae4SAndroid Build Coastguard Worker     result = push_certinfo(data, mem, "Start date", i);
528*6236dae4SAndroid Build Coastguard Worker     if(result)
529*6236dae4SAndroid Build Coastguard Worker       break;
530*6236dae4SAndroid Build Coastguard Worker 
531*6236dae4SAndroid Build Coastguard Worker     ASN1_TIME_print(mem, X509_get0_notAfter(x));
532*6236dae4SAndroid Build Coastguard Worker     result = push_certinfo(data, mem, "Expire date", i);
533*6236dae4SAndroid Build Coastguard Worker     if(result)
534*6236dae4SAndroid Build Coastguard Worker       break;
535*6236dae4SAndroid Build Coastguard Worker 
536*6236dae4SAndroid Build Coastguard Worker     pubkey = X509_get_pubkey(x);
537*6236dae4SAndroid Build Coastguard Worker     if(!pubkey)
538*6236dae4SAndroid Build Coastguard Worker       infof(data, "   Unable to load public key");
539*6236dae4SAndroid Build Coastguard Worker     else {
540*6236dae4SAndroid Build Coastguard Worker       int pktype;
541*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_EVP_PKEY
542*6236dae4SAndroid Build Coastguard Worker       pktype = EVP_PKEY_id(pubkey);
543*6236dae4SAndroid Build Coastguard Worker #else
544*6236dae4SAndroid Build Coastguard Worker       pktype = pubkey->type;
545*6236dae4SAndroid Build Coastguard Worker #endif
546*6236dae4SAndroid Build Coastguard Worker       switch(pktype) {
547*6236dae4SAndroid Build Coastguard Worker       case EVP_PKEY_RSA: {
548*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_EVP_PKEY_GET_PARAMS
549*6236dae4SAndroid Build Coastguard Worker         RSA *rsa;
550*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_EVP_PKEY
551*6236dae4SAndroid Build Coastguard Worker         rsa = EVP_PKEY_get0_RSA(pubkey);
552*6236dae4SAndroid Build Coastguard Worker #else
553*6236dae4SAndroid Build Coastguard Worker         rsa = pubkey->pkey.rsa;
554*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_OPAQUE_EVP_PKEY */
555*6236dae4SAndroid Build Coastguard Worker #endif /* !HAVE_EVP_PKEY_GET_PARAMS */
556*6236dae4SAndroid Build Coastguard Worker 
557*6236dae4SAndroid Build Coastguard Worker         {
558*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_RSA_DSA_DH
559*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(n);
560*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(e);
561*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_EVP_PKEY_GET_PARAMS
562*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
563*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
564*6236dae4SAndroid Build Coastguard Worker #else
565*6236dae4SAndroid Build Coastguard Worker           RSA_get0_key(rsa, &n, &e, NULL);
566*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_EVP_PKEY_GET_PARAMS */
567*6236dae4SAndroid Build Coastguard Worker           BIO_printf(mem, "%d", n ? BN_num_bits(n) : 0);
568*6236dae4SAndroid Build Coastguard Worker #else
569*6236dae4SAndroid Build Coastguard Worker           BIO_printf(mem, "%d", rsa->n ? BN_num_bits(rsa->n) : 0);
570*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_OPAQUE_RSA_DSA_DH */
571*6236dae4SAndroid Build Coastguard Worker           result = push_certinfo(data, mem, "RSA Public Key", i);
572*6236dae4SAndroid Build Coastguard Worker           if(result)
573*6236dae4SAndroid Build Coastguard Worker             break;
574*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(rsa, n, i);
575*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(rsa, e, i);
576*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(n);
577*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(e);
578*6236dae4SAndroid Build Coastguard Worker         }
579*6236dae4SAndroid Build Coastguard Worker 
580*6236dae4SAndroid Build Coastguard Worker         break;
581*6236dae4SAndroid Build Coastguard Worker       }
582*6236dae4SAndroid Build Coastguard Worker       case EVP_PKEY_DSA:
583*6236dae4SAndroid Build Coastguard Worker       {
584*6236dae4SAndroid Build Coastguard Worker #ifndef OPENSSL_NO_DSA
585*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_EVP_PKEY_GET_PARAMS
586*6236dae4SAndroid Build Coastguard Worker         DSA *dsa;
587*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_EVP_PKEY
588*6236dae4SAndroid Build Coastguard Worker         dsa = EVP_PKEY_get0_DSA(pubkey);
589*6236dae4SAndroid Build Coastguard Worker #else
590*6236dae4SAndroid Build Coastguard Worker         dsa = pubkey->pkey.dsa;
591*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_OPAQUE_EVP_PKEY */
592*6236dae4SAndroid Build Coastguard Worker #endif /* !HAVE_EVP_PKEY_GET_PARAMS */
593*6236dae4SAndroid Build Coastguard Worker         {
594*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_RSA_DSA_DH
595*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(p);
596*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(q);
597*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(g);
598*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(pub_key);
599*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_EVP_PKEY_GET_PARAMS
600*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
601*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
602*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
603*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
604*6236dae4SAndroid Build Coastguard Worker #else
605*6236dae4SAndroid Build Coastguard Worker           DSA_get0_pqg(dsa, &p, &q, &g);
606*6236dae4SAndroid Build Coastguard Worker           DSA_get0_key(dsa, &pub_key, NULL);
607*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_EVP_PKEY_GET_PARAMS */
608*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_OPAQUE_RSA_DSA_DH */
609*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dsa, p, i);
610*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dsa, q, i);
611*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dsa, g, i);
612*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dsa, pub_key, i);
613*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(p);
614*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(q);
615*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(g);
616*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(pub_key);
617*6236dae4SAndroid Build Coastguard Worker         }
618*6236dae4SAndroid Build Coastguard Worker #endif /* !OPENSSL_NO_DSA */
619*6236dae4SAndroid Build Coastguard Worker         break;
620*6236dae4SAndroid Build Coastguard Worker       }
621*6236dae4SAndroid Build Coastguard Worker       case EVP_PKEY_DH: {
622*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_EVP_PKEY_GET_PARAMS
623*6236dae4SAndroid Build Coastguard Worker         DH *dh;
624*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_EVP_PKEY
625*6236dae4SAndroid Build Coastguard Worker         dh = EVP_PKEY_get0_DH(pubkey);
626*6236dae4SAndroid Build Coastguard Worker #else
627*6236dae4SAndroid Build Coastguard Worker         dh = pubkey->pkey.dh;
628*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_OPAQUE_EVP_PKEY */
629*6236dae4SAndroid Build Coastguard Worker #endif /* !HAVE_EVP_PKEY_GET_PARAMS */
630*6236dae4SAndroid Build Coastguard Worker         {
631*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_RSA_DSA_DH
632*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(p);
633*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(q);
634*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(g);
635*6236dae4SAndroid Build Coastguard Worker           DECLARE_PKEY_PARAM_BIGNUM(pub_key);
636*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_EVP_PKEY_GET_PARAMS
637*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
638*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
639*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
640*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
641*6236dae4SAndroid Build Coastguard Worker #else
642*6236dae4SAndroid Build Coastguard Worker           DH_get0_pqg(dh, &p, &q, &g);
643*6236dae4SAndroid Build Coastguard Worker           DH_get0_key(dh, &pub_key, NULL);
644*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_EVP_PKEY_GET_PARAMS */
645*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dh, p, i);
646*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dh, q, i);
647*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dh, g, i);
648*6236dae4SAndroid Build Coastguard Worker #else
649*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dh, p, i);
650*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dh, g, i);
651*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_OPAQUE_RSA_DSA_DH */
652*6236dae4SAndroid Build Coastguard Worker           print_pubkey_BN(dh, pub_key, i);
653*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(p);
654*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(q);
655*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(g);
656*6236dae4SAndroid Build Coastguard Worker           FREE_PKEY_PARAM_BIGNUM(pub_key);
657*6236dae4SAndroid Build Coastguard Worker         }
658*6236dae4SAndroid Build Coastguard Worker         break;
659*6236dae4SAndroid Build Coastguard Worker       }
660*6236dae4SAndroid Build Coastguard Worker       }
661*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY_free(pubkey);
662*6236dae4SAndroid Build Coastguard Worker     }
663*6236dae4SAndroid Build Coastguard Worker 
664*6236dae4SAndroid Build Coastguard Worker     if(!result && psig) {
665*6236dae4SAndroid Build Coastguard Worker       for(j = 0; j < psig->length; j++)
666*6236dae4SAndroid Build Coastguard Worker         BIO_printf(mem, "%02x:", psig->data[j]);
667*6236dae4SAndroid Build Coastguard Worker       result = push_certinfo(data, mem, "Signature", i);
668*6236dae4SAndroid Build Coastguard Worker     }
669*6236dae4SAndroid Build Coastguard Worker 
670*6236dae4SAndroid Build Coastguard Worker     if(!result) {
671*6236dae4SAndroid Build Coastguard Worker       PEM_write_bio_X509(mem, x);
672*6236dae4SAndroid Build Coastguard Worker       result = push_certinfo(data, mem, "Cert", i);
673*6236dae4SAndroid Build Coastguard Worker     }
674*6236dae4SAndroid Build Coastguard Worker   }
675*6236dae4SAndroid Build Coastguard Worker 
676*6236dae4SAndroid Build Coastguard Worker   BIO_free(mem);
677*6236dae4SAndroid Build Coastguard Worker 
678*6236dae4SAndroid Build Coastguard Worker   if(result)
679*6236dae4SAndroid Build Coastguard Worker     /* cleanup all leftovers */
680*6236dae4SAndroid Build Coastguard Worker     Curl_ssl_free_certinfo(data);
681*6236dae4SAndroid Build Coastguard Worker 
682*6236dae4SAndroid Build Coastguard Worker   return result;
683*6236dae4SAndroid Build Coastguard Worker }
684*6236dae4SAndroid Build Coastguard Worker 
685*6236dae4SAndroid Build Coastguard Worker #endif /* quiche or OpenSSL */
686*6236dae4SAndroid Build Coastguard Worker 
687*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL
688*6236dae4SAndroid Build Coastguard Worker 
689*6236dae4SAndroid Build Coastguard Worker #if USE_PRE_1_1_API
690*6236dae4SAndroid Build Coastguard Worker #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x2070000fL
691*6236dae4SAndroid Build Coastguard Worker #define BIO_set_init(x,v)          ((x)->init=(v))
692*6236dae4SAndroid Build Coastguard Worker #define BIO_get_data(x)            ((x)->ptr)
693*6236dae4SAndroid Build Coastguard Worker #define BIO_set_data(x,v)          ((x)->ptr=(v))
694*6236dae4SAndroid Build Coastguard Worker #endif
695*6236dae4SAndroid Build Coastguard Worker #define BIO_get_shutdown(x)        ((x)->shutdown)
696*6236dae4SAndroid Build Coastguard Worker #define BIO_set_shutdown(x,v)      ((x)->shutdown=(v))
697*6236dae4SAndroid Build Coastguard Worker #endif /* USE_PRE_1_1_API */
698*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_create(BIO * bio)699*6236dae4SAndroid Build Coastguard Worker static int ossl_bio_cf_create(BIO *bio)
700*6236dae4SAndroid Build Coastguard Worker {
701*6236dae4SAndroid Build Coastguard Worker   BIO_set_shutdown(bio, 1);
702*6236dae4SAndroid Build Coastguard Worker   BIO_set_init(bio, 1);
703*6236dae4SAndroid Build Coastguard Worker #if USE_PRE_1_1_API
704*6236dae4SAndroid Build Coastguard Worker   bio->num = -1;
705*6236dae4SAndroid Build Coastguard Worker #endif
706*6236dae4SAndroid Build Coastguard Worker   BIO_set_data(bio, NULL);
707*6236dae4SAndroid Build Coastguard Worker   return 1;
708*6236dae4SAndroid Build Coastguard Worker }
709*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_destroy(BIO * bio)710*6236dae4SAndroid Build Coastguard Worker static int ossl_bio_cf_destroy(BIO *bio)
711*6236dae4SAndroid Build Coastguard Worker {
712*6236dae4SAndroid Build Coastguard Worker   if(!bio)
713*6236dae4SAndroid Build Coastguard Worker     return 0;
714*6236dae4SAndroid Build Coastguard Worker   return 1;
715*6236dae4SAndroid Build Coastguard Worker }
716*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_ctrl(BIO * bio,int cmd,long num,void * ptr)717*6236dae4SAndroid Build Coastguard Worker static long ossl_bio_cf_ctrl(BIO *bio, int cmd, long num, void *ptr)
718*6236dae4SAndroid Build Coastguard Worker {
719*6236dae4SAndroid Build Coastguard Worker   struct Curl_cfilter *cf = BIO_get_data(bio);
720*6236dae4SAndroid Build Coastguard Worker   long ret = 1;
721*6236dae4SAndroid Build Coastguard Worker 
722*6236dae4SAndroid Build Coastguard Worker   (void)cf;
723*6236dae4SAndroid Build Coastguard Worker   (void)ptr;
724*6236dae4SAndroid Build Coastguard Worker   switch(cmd) {
725*6236dae4SAndroid Build Coastguard Worker   case BIO_CTRL_GET_CLOSE:
726*6236dae4SAndroid Build Coastguard Worker     ret = (long)BIO_get_shutdown(bio);
727*6236dae4SAndroid Build Coastguard Worker     break;
728*6236dae4SAndroid Build Coastguard Worker   case BIO_CTRL_SET_CLOSE:
729*6236dae4SAndroid Build Coastguard Worker     BIO_set_shutdown(bio, (int)num);
730*6236dae4SAndroid Build Coastguard Worker     break;
731*6236dae4SAndroid Build Coastguard Worker   case BIO_CTRL_FLUSH:
732*6236dae4SAndroid Build Coastguard Worker     /* we do no delayed writes, but if we ever would, this
733*6236dae4SAndroid Build Coastguard Worker      * needs to trigger it. */
734*6236dae4SAndroid Build Coastguard Worker     ret = 1;
735*6236dae4SAndroid Build Coastguard Worker     break;
736*6236dae4SAndroid Build Coastguard Worker   case BIO_CTRL_DUP:
737*6236dae4SAndroid Build Coastguard Worker     ret = 1;
738*6236dae4SAndroid Build Coastguard Worker     break;
739*6236dae4SAndroid Build Coastguard Worker #ifdef BIO_CTRL_EOF
740*6236dae4SAndroid Build Coastguard Worker   case BIO_CTRL_EOF:
741*6236dae4SAndroid Build Coastguard Worker     /* EOF has been reached on input? */
742*6236dae4SAndroid Build Coastguard Worker     return (!cf->next || !cf->next->connected);
743*6236dae4SAndroid Build Coastguard Worker #endif
744*6236dae4SAndroid Build Coastguard Worker   default:
745*6236dae4SAndroid Build Coastguard Worker     ret = 0;
746*6236dae4SAndroid Build Coastguard Worker     break;
747*6236dae4SAndroid Build Coastguard Worker   }
748*6236dae4SAndroid Build Coastguard Worker   return ret;
749*6236dae4SAndroid Build Coastguard Worker }
750*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_out_write(BIO * bio,const char * buf,int blen)751*6236dae4SAndroid Build Coastguard Worker static int ossl_bio_cf_out_write(BIO *bio, const char *buf, int blen)
752*6236dae4SAndroid Build Coastguard Worker {
753*6236dae4SAndroid Build Coastguard Worker   struct Curl_cfilter *cf = BIO_get_data(bio);
754*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
755*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
756*6236dae4SAndroid Build Coastguard Worker   struct Curl_easy *data = CF_DATA_CURRENT(cf);
757*6236dae4SAndroid Build Coastguard Worker   ssize_t nwritten;
758*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_SEND_ERROR;
759*6236dae4SAndroid Build Coastguard Worker 
760*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(data);
761*6236dae4SAndroid Build Coastguard Worker   if(blen < 0)
762*6236dae4SAndroid Build Coastguard Worker     return 0;
763*6236dae4SAndroid Build Coastguard Worker 
764*6236dae4SAndroid Build Coastguard Worker   nwritten = Curl_conn_cf_send(cf->next, data, buf, (size_t)blen, FALSE,
765*6236dae4SAndroid Build Coastguard Worker                                &result);
766*6236dae4SAndroid Build Coastguard Worker   CURL_TRC_CF(data, cf, "ossl_bio_cf_out_write(len=%d) -> %d, err=%d",
767*6236dae4SAndroid Build Coastguard Worker               blen, (int)nwritten, result);
768*6236dae4SAndroid Build Coastguard Worker   BIO_clear_retry_flags(bio);
769*6236dae4SAndroid Build Coastguard Worker   octx->io_result = result;
770*6236dae4SAndroid Build Coastguard Worker   if(nwritten < 0) {
771*6236dae4SAndroid Build Coastguard Worker     if(CURLE_AGAIN == result)
772*6236dae4SAndroid Build Coastguard Worker       BIO_set_retry_write(bio);
773*6236dae4SAndroid Build Coastguard Worker   }
774*6236dae4SAndroid Build Coastguard Worker   return (int)nwritten;
775*6236dae4SAndroid Build Coastguard Worker }
776*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_in_read(BIO * bio,char * buf,int blen)777*6236dae4SAndroid Build Coastguard Worker static int ossl_bio_cf_in_read(BIO *bio, char *buf, int blen)
778*6236dae4SAndroid Build Coastguard Worker {
779*6236dae4SAndroid Build Coastguard Worker   struct Curl_cfilter *cf = BIO_get_data(bio);
780*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
781*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
782*6236dae4SAndroid Build Coastguard Worker   struct Curl_easy *data = CF_DATA_CURRENT(cf);
783*6236dae4SAndroid Build Coastguard Worker   ssize_t nread;
784*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_RECV_ERROR;
785*6236dae4SAndroid Build Coastguard Worker 
786*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(data);
787*6236dae4SAndroid Build Coastguard Worker   /* OpenSSL catches this case, so should we. */
788*6236dae4SAndroid Build Coastguard Worker   if(!buf)
789*6236dae4SAndroid Build Coastguard Worker     return 0;
790*6236dae4SAndroid Build Coastguard Worker   if(blen < 0)
791*6236dae4SAndroid Build Coastguard Worker     return 0;
792*6236dae4SAndroid Build Coastguard Worker 
793*6236dae4SAndroid Build Coastguard Worker   nread = Curl_conn_cf_recv(cf->next, data, buf, (size_t)blen, &result);
794*6236dae4SAndroid Build Coastguard Worker   CURL_TRC_CF(data, cf, "ossl_bio_cf_in_read(len=%d) -> %d, err=%d",
795*6236dae4SAndroid Build Coastguard Worker               blen, (int)nread, result);
796*6236dae4SAndroid Build Coastguard Worker   BIO_clear_retry_flags(bio);
797*6236dae4SAndroid Build Coastguard Worker   octx->io_result = result;
798*6236dae4SAndroid Build Coastguard Worker   if(nread < 0) {
799*6236dae4SAndroid Build Coastguard Worker     if(CURLE_AGAIN == result)
800*6236dae4SAndroid Build Coastguard Worker       BIO_set_retry_read(bio);
801*6236dae4SAndroid Build Coastguard Worker   }
802*6236dae4SAndroid Build Coastguard Worker   else if(nread == 0) {
803*6236dae4SAndroid Build Coastguard Worker     connssl->peer_closed = TRUE;
804*6236dae4SAndroid Build Coastguard Worker   }
805*6236dae4SAndroid Build Coastguard Worker 
806*6236dae4SAndroid Build Coastguard Worker   /* Before returning server replies to the SSL instance, we need
807*6236dae4SAndroid Build Coastguard Worker    * to have setup the x509 store or verification will fail. */
808*6236dae4SAndroid Build Coastguard Worker   if(!octx->x509_store_setup) {
809*6236dae4SAndroid Build Coastguard Worker     result = Curl_ssl_setup_x509_store(cf, data, octx->ssl_ctx);
810*6236dae4SAndroid Build Coastguard Worker     if(result) {
811*6236dae4SAndroid Build Coastguard Worker       octx->io_result = result;
812*6236dae4SAndroid Build Coastguard Worker       return -1;
813*6236dae4SAndroid Build Coastguard Worker     }
814*6236dae4SAndroid Build Coastguard Worker     octx->x509_store_setup = TRUE;
815*6236dae4SAndroid Build Coastguard Worker   }
816*6236dae4SAndroid Build Coastguard Worker 
817*6236dae4SAndroid Build Coastguard Worker   return (int)nread;
818*6236dae4SAndroid Build Coastguard Worker }
819*6236dae4SAndroid Build Coastguard Worker 
820*6236dae4SAndroid Build Coastguard Worker #if USE_PRE_1_1_API
821*6236dae4SAndroid Build Coastguard Worker 
822*6236dae4SAndroid Build Coastguard Worker static BIO_METHOD ossl_bio_cf_meth_1_0 = {
823*6236dae4SAndroid Build Coastguard Worker   BIO_TYPE_MEM,
824*6236dae4SAndroid Build Coastguard Worker   "OpenSSL CF BIO",
825*6236dae4SAndroid Build Coastguard Worker   ossl_bio_cf_out_write,
826*6236dae4SAndroid Build Coastguard Worker   ossl_bio_cf_in_read,
827*6236dae4SAndroid Build Coastguard Worker   NULL,                    /* puts is never called */
828*6236dae4SAndroid Build Coastguard Worker   NULL,                    /* gets is never called */
829*6236dae4SAndroid Build Coastguard Worker   ossl_bio_cf_ctrl,
830*6236dae4SAndroid Build Coastguard Worker   ossl_bio_cf_create,
831*6236dae4SAndroid Build Coastguard Worker   ossl_bio_cf_destroy,
832*6236dae4SAndroid Build Coastguard Worker   NULL
833*6236dae4SAndroid Build Coastguard Worker };
834*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_method_create(void)835*6236dae4SAndroid Build Coastguard Worker static BIO_METHOD *ossl_bio_cf_method_create(void)
836*6236dae4SAndroid Build Coastguard Worker {
837*6236dae4SAndroid Build Coastguard Worker   return &ossl_bio_cf_meth_1_0;
838*6236dae4SAndroid Build Coastguard Worker }
839*6236dae4SAndroid Build Coastguard Worker 
840*6236dae4SAndroid Build Coastguard Worker #define ossl_bio_cf_method_free(m) Curl_nop_stmt
841*6236dae4SAndroid Build Coastguard Worker 
842*6236dae4SAndroid Build Coastguard Worker #else
843*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_method_create(void)844*6236dae4SAndroid Build Coastguard Worker static BIO_METHOD *ossl_bio_cf_method_create(void)
845*6236dae4SAndroid Build Coastguard Worker {
846*6236dae4SAndroid Build Coastguard Worker   BIO_METHOD *m = BIO_meth_new(BIO_TYPE_MEM, "OpenSSL CF BIO");
847*6236dae4SAndroid Build Coastguard Worker   if(m) {
848*6236dae4SAndroid Build Coastguard Worker     BIO_meth_set_write(m, &ossl_bio_cf_out_write);
849*6236dae4SAndroid Build Coastguard Worker     BIO_meth_set_read(m, &ossl_bio_cf_in_read);
850*6236dae4SAndroid Build Coastguard Worker     BIO_meth_set_ctrl(m, &ossl_bio_cf_ctrl);
851*6236dae4SAndroid Build Coastguard Worker     BIO_meth_set_create(m, &ossl_bio_cf_create);
852*6236dae4SAndroid Build Coastguard Worker     BIO_meth_set_destroy(m, &ossl_bio_cf_destroy);
853*6236dae4SAndroid Build Coastguard Worker   }
854*6236dae4SAndroid Build Coastguard Worker   return m;
855*6236dae4SAndroid Build Coastguard Worker }
856*6236dae4SAndroid Build Coastguard Worker 
ossl_bio_cf_method_free(BIO_METHOD * m)857*6236dae4SAndroid Build Coastguard Worker static void ossl_bio_cf_method_free(BIO_METHOD *m)
858*6236dae4SAndroid Build Coastguard Worker {
859*6236dae4SAndroid Build Coastguard Worker   if(m)
860*6236dae4SAndroid Build Coastguard Worker     BIO_meth_free(m);
861*6236dae4SAndroid Build Coastguard Worker }
862*6236dae4SAndroid Build Coastguard Worker 
863*6236dae4SAndroid Build Coastguard Worker #endif
864*6236dae4SAndroid Build Coastguard Worker 
865*6236dae4SAndroid Build Coastguard Worker 
866*6236dae4SAndroid Build Coastguard Worker /*
867*6236dae4SAndroid Build Coastguard Worker  * Number of bytes to read from the random number seed file. This must be
868*6236dae4SAndroid Build Coastguard Worker  * a finite value (because some entropy "files" like /dev/urandom have
869*6236dae4SAndroid Build Coastguard Worker  * an infinite length), but must be large enough to provide enough
870*6236dae4SAndroid Build Coastguard Worker  * entropy to properly seed OpenSSL's PRNG.
871*6236dae4SAndroid Build Coastguard Worker  */
872*6236dae4SAndroid Build Coastguard Worker #define RAND_LOAD_LENGTH 1024
873*6236dae4SAndroid Build Coastguard Worker 
874*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_KEYLOG_CALLBACK
ossl_keylog_callback(const SSL * ssl,const char * line)875*6236dae4SAndroid Build Coastguard Worker static void ossl_keylog_callback(const SSL *ssl, const char *line)
876*6236dae4SAndroid Build Coastguard Worker {
877*6236dae4SAndroid Build Coastguard Worker   (void)ssl;
878*6236dae4SAndroid Build Coastguard Worker 
879*6236dae4SAndroid Build Coastguard Worker   Curl_tls_keylog_write_line(line);
880*6236dae4SAndroid Build Coastguard Worker }
881*6236dae4SAndroid Build Coastguard Worker #else
882*6236dae4SAndroid Build Coastguard Worker /*
883*6236dae4SAndroid Build Coastguard Worker  * ossl_log_tls12_secret is called by libcurl to make the CLIENT_RANDOMs if the
884*6236dae4SAndroid Build Coastguard Worker  * OpenSSL being used does not have native support for doing that.
885*6236dae4SAndroid Build Coastguard Worker  */
886*6236dae4SAndroid Build Coastguard Worker static void
ossl_log_tls12_secret(const SSL * ssl,bool * keylog_done)887*6236dae4SAndroid Build Coastguard Worker ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done)
888*6236dae4SAndroid Build Coastguard Worker {
889*6236dae4SAndroid Build Coastguard Worker   const SSL_SESSION *session = SSL_get_session(ssl);
890*6236dae4SAndroid Build Coastguard Worker   unsigned char client_random[SSL3_RANDOM_SIZE];
891*6236dae4SAndroid Build Coastguard Worker   unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
892*6236dae4SAndroid Build Coastguard Worker   int master_key_length = 0;
893*6236dae4SAndroid Build Coastguard Worker 
894*6236dae4SAndroid Build Coastguard Worker   if(!session || *keylog_done)
895*6236dae4SAndroid Build Coastguard Worker     return;
896*6236dae4SAndroid Build Coastguard Worker 
897*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x10100000L &&    \
898*6236dae4SAndroid Build Coastguard Worker   !(defined(LIBRESSL_VERSION_NUMBER) &&         \
899*6236dae4SAndroid Build Coastguard Worker     LIBRESSL_VERSION_NUMBER < 0x20700000L)
900*6236dae4SAndroid Build Coastguard Worker   /* ssl->s3 is not checked in OpenSSL 1.1.0-pre6, but let's assume that
901*6236dae4SAndroid Build Coastguard Worker    * we have a valid SSL context if we have a non-NULL session. */
902*6236dae4SAndroid Build Coastguard Worker   SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE);
903*6236dae4SAndroid Build Coastguard Worker   master_key_length = (int)
904*6236dae4SAndroid Build Coastguard Worker     SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH);
905*6236dae4SAndroid Build Coastguard Worker #else
906*6236dae4SAndroid Build Coastguard Worker   if(ssl->s3 && session->master_key_length > 0) {
907*6236dae4SAndroid Build Coastguard Worker     master_key_length = session->master_key_length;
908*6236dae4SAndroid Build Coastguard Worker     memcpy(master_key, session->master_key, session->master_key_length);
909*6236dae4SAndroid Build Coastguard Worker     memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE);
910*6236dae4SAndroid Build Coastguard Worker   }
911*6236dae4SAndroid Build Coastguard Worker #endif
912*6236dae4SAndroid Build Coastguard Worker 
913*6236dae4SAndroid Build Coastguard Worker   /* The handshake has not progressed sufficiently yet, or this is a TLS 1.3
914*6236dae4SAndroid Build Coastguard Worker    * session (when curl was built with older OpenSSL headers and running with
915*6236dae4SAndroid Build Coastguard Worker    * newer OpenSSL runtime libraries). */
916*6236dae4SAndroid Build Coastguard Worker   if(master_key_length <= 0)
917*6236dae4SAndroid Build Coastguard Worker     return;
918*6236dae4SAndroid Build Coastguard Worker 
919*6236dae4SAndroid Build Coastguard Worker   *keylog_done = TRUE;
920*6236dae4SAndroid Build Coastguard Worker   Curl_tls_keylog_write("CLIENT_RANDOM", client_random,
921*6236dae4SAndroid Build Coastguard Worker                         master_key, master_key_length);
922*6236dae4SAndroid Build Coastguard Worker }
923*6236dae4SAndroid Build Coastguard Worker #endif /* !HAVE_KEYLOG_CALLBACK */
924*6236dae4SAndroid Build Coastguard Worker 
SSL_ERROR_to_str(int err)925*6236dae4SAndroid Build Coastguard Worker static const char *SSL_ERROR_to_str(int err)
926*6236dae4SAndroid Build Coastguard Worker {
927*6236dae4SAndroid Build Coastguard Worker   switch(err) {
928*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_NONE:
929*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_NONE";
930*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_SSL:
931*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_SSL";
932*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_READ:
933*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_READ";
934*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_WRITE:
935*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_WRITE";
936*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_X509_LOOKUP:
937*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_X509_LOOKUP";
938*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_SYSCALL:
939*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_SYSCALL";
940*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_ZERO_RETURN:
941*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_ZERO_RETURN";
942*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_CONNECT:
943*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_CONNECT";
944*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_ACCEPT:
945*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_ACCEPT";
946*6236dae4SAndroid Build Coastguard Worker #if defined(SSL_ERROR_WANT_ASYNC)
947*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_ASYNC:
948*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_ASYNC";
949*6236dae4SAndroid Build Coastguard Worker #endif
950*6236dae4SAndroid Build Coastguard Worker #if defined(SSL_ERROR_WANT_ASYNC_JOB)
951*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_ASYNC_JOB:
952*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_ASYNC_JOB";
953*6236dae4SAndroid Build Coastguard Worker #endif
954*6236dae4SAndroid Build Coastguard Worker #if defined(SSL_ERROR_WANT_EARLY)
955*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_EARLY:
956*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR_WANT_EARLY";
957*6236dae4SAndroid Build Coastguard Worker #endif
958*6236dae4SAndroid Build Coastguard Worker   default:
959*6236dae4SAndroid Build Coastguard Worker     return "SSL_ERROR unknown";
960*6236dae4SAndroid Build Coastguard Worker   }
961*6236dae4SAndroid Build Coastguard Worker }
962*6236dae4SAndroid Build Coastguard Worker 
963*6236dae4SAndroid Build Coastguard Worker static size_t ossl_version(char *buffer, size_t size);
964*6236dae4SAndroid Build Coastguard Worker 
965*6236dae4SAndroid Build Coastguard Worker /* Return error string for last OpenSSL error
966*6236dae4SAndroid Build Coastguard Worker  */
ossl_strerror(unsigned long error,char * buf,size_t size)967*6236dae4SAndroid Build Coastguard Worker static char *ossl_strerror(unsigned long error, char *buf, size_t size)
968*6236dae4SAndroid Build Coastguard Worker {
969*6236dae4SAndroid Build Coastguard Worker   size_t len;
970*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(size);
971*6236dae4SAndroid Build Coastguard Worker   *buf = '\0';
972*6236dae4SAndroid Build Coastguard Worker 
973*6236dae4SAndroid Build Coastguard Worker   len = ossl_version(buf, size);
974*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(len < (size - 2));
975*6236dae4SAndroid Build Coastguard Worker   if(len < (size - 2)) {
976*6236dae4SAndroid Build Coastguard Worker     buf += len;
977*6236dae4SAndroid Build Coastguard Worker     size -= (len + 2);
978*6236dae4SAndroid Build Coastguard Worker     *buf++ = ':';
979*6236dae4SAndroid Build Coastguard Worker     *buf++ = ' ';
980*6236dae4SAndroid Build Coastguard Worker     *buf = '\0';
981*6236dae4SAndroid Build Coastguard Worker   }
982*6236dae4SAndroid Build Coastguard Worker 
983*6236dae4SAndroid Build Coastguard Worker #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
984*6236dae4SAndroid Build Coastguard Worker   ERR_error_string_n((uint32_t)error, buf, size);
985*6236dae4SAndroid Build Coastguard Worker #else
986*6236dae4SAndroid Build Coastguard Worker   ERR_error_string_n(error, buf, size);
987*6236dae4SAndroid Build Coastguard Worker #endif
988*6236dae4SAndroid Build Coastguard Worker 
989*6236dae4SAndroid Build Coastguard Worker   if(!*buf) {
990*6236dae4SAndroid Build Coastguard Worker     const char *msg = error ? "Unknown error" : "No error";
991*6236dae4SAndroid Build Coastguard Worker     if(strlen(msg) < size)
992*6236dae4SAndroid Build Coastguard Worker       strcpy(buf, msg);
993*6236dae4SAndroid Build Coastguard Worker   }
994*6236dae4SAndroid Build Coastguard Worker 
995*6236dae4SAndroid Build Coastguard Worker   return buf;
996*6236dae4SAndroid Build Coastguard Worker }
997*6236dae4SAndroid Build Coastguard Worker 
passwd_callback(char * buf,int num,int encrypting,void * global_passwd)998*6236dae4SAndroid Build Coastguard Worker static int passwd_callback(char *buf, int num, int encrypting,
999*6236dae4SAndroid Build Coastguard Worker                            void *global_passwd)
1000*6236dae4SAndroid Build Coastguard Worker {
1001*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(0 == encrypting);
1002*6236dae4SAndroid Build Coastguard Worker 
1003*6236dae4SAndroid Build Coastguard Worker   if(!encrypting && num >= 0) {
1004*6236dae4SAndroid Build Coastguard Worker     int klen = curlx_uztosi(strlen((char *)global_passwd));
1005*6236dae4SAndroid Build Coastguard Worker     if(num > klen) {
1006*6236dae4SAndroid Build Coastguard Worker       memcpy(buf, global_passwd, klen + 1);
1007*6236dae4SAndroid Build Coastguard Worker       return klen;
1008*6236dae4SAndroid Build Coastguard Worker     }
1009*6236dae4SAndroid Build Coastguard Worker   }
1010*6236dae4SAndroid Build Coastguard Worker   return 0;
1011*6236dae4SAndroid Build Coastguard Worker }
1012*6236dae4SAndroid Build Coastguard Worker 
1013*6236dae4SAndroid Build Coastguard Worker /*
1014*6236dae4SAndroid Build Coastguard Worker  * rand_enough() returns TRUE if we have seeded the random engine properly.
1015*6236dae4SAndroid Build Coastguard Worker  */
rand_enough(void)1016*6236dae4SAndroid Build Coastguard Worker static bool rand_enough(void)
1017*6236dae4SAndroid Build Coastguard Worker {
1018*6236dae4SAndroid Build Coastguard Worker   return (0 != RAND_status());
1019*6236dae4SAndroid Build Coastguard Worker }
1020*6236dae4SAndroid Build Coastguard Worker 
ossl_seed(struct Curl_easy * data)1021*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_seed(struct Curl_easy *data)
1022*6236dae4SAndroid Build Coastguard Worker {
1023*6236dae4SAndroid Build Coastguard Worker   /* This might get called before it has been added to a multi handle */
1024*6236dae4SAndroid Build Coastguard Worker   if(data->multi && data->multi->ssl_seeded)
1025*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
1026*6236dae4SAndroid Build Coastguard Worker 
1027*6236dae4SAndroid Build Coastguard Worker   if(rand_enough()) {
1028*6236dae4SAndroid Build Coastguard Worker     /* OpenSSL 1.1.0+ should return here */
1029*6236dae4SAndroid Build Coastguard Worker     if(data->multi)
1030*6236dae4SAndroid Build Coastguard Worker       data->multi->ssl_seeded = TRUE;
1031*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
1032*6236dae4SAndroid Build Coastguard Worker   }
1033*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_RANDOM_INIT_BY_DEFAULT
1034*6236dae4SAndroid Build Coastguard Worker   /* with OpenSSL 1.1.0+, a failed RAND_status is a showstopper */
1035*6236dae4SAndroid Build Coastguard Worker   failf(data, "Insufficient randomness");
1036*6236dae4SAndroid Build Coastguard Worker   return CURLE_SSL_CONNECT_ERROR;
1037*6236dae4SAndroid Build Coastguard Worker #else
1038*6236dae4SAndroid Build Coastguard Worker 
1039*6236dae4SAndroid Build Coastguard Worker   /* fallback to a custom seeding of the PRNG using a hash based on a current
1040*6236dae4SAndroid Build Coastguard Worker      time */
1041*6236dae4SAndroid Build Coastguard Worker   do {
1042*6236dae4SAndroid Build Coastguard Worker     unsigned char randb[64];
1043*6236dae4SAndroid Build Coastguard Worker     size_t len = sizeof(randb);
1044*6236dae4SAndroid Build Coastguard Worker     size_t i, i_max;
1045*6236dae4SAndroid Build Coastguard Worker     for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
1046*6236dae4SAndroid Build Coastguard Worker       struct curltime tv = Curl_now();
1047*6236dae4SAndroid Build Coastguard Worker       Curl_wait_ms(1);
1048*6236dae4SAndroid Build Coastguard Worker       tv.tv_sec *= (time_t)i + 1;
1049*6236dae4SAndroid Build Coastguard Worker       tv.tv_usec *= (int)i + 2;
1050*6236dae4SAndroid Build Coastguard Worker       tv.tv_sec ^= ((Curl_now().tv_sec + (time_t)Curl_now().tv_usec) *
1051*6236dae4SAndroid Build Coastguard Worker                     (time_t)(i + 3)) << 8;
1052*6236dae4SAndroid Build Coastguard Worker       tv.tv_usec ^= (int) ((Curl_now().tv_sec + (time_t)Curl_now().tv_usec) *
1053*6236dae4SAndroid Build Coastguard Worker                            (time_t)(i + 4)) << 16;
1054*6236dae4SAndroid Build Coastguard Worker       memcpy(&randb[i * sizeof(struct curltime)], &tv,
1055*6236dae4SAndroid Build Coastguard Worker              sizeof(struct curltime));
1056*6236dae4SAndroid Build Coastguard Worker     }
1057*6236dae4SAndroid Build Coastguard Worker     RAND_add(randb, (int)len, (double)len/2);
1058*6236dae4SAndroid Build Coastguard Worker   } while(!rand_enough());
1059*6236dae4SAndroid Build Coastguard Worker 
1060*6236dae4SAndroid Build Coastguard Worker   {
1061*6236dae4SAndroid Build Coastguard Worker     /* generates a default path for the random seed file */
1062*6236dae4SAndroid Build Coastguard Worker     char fname[256];
1063*6236dae4SAndroid Build Coastguard Worker     fname[0] = 0; /* blank it first */
1064*6236dae4SAndroid Build Coastguard Worker     RAND_file_name(fname, sizeof(fname));
1065*6236dae4SAndroid Build Coastguard Worker     if(fname[0]) {
1066*6236dae4SAndroid Build Coastguard Worker       /* we got a filename to try */
1067*6236dae4SAndroid Build Coastguard Worker       RAND_load_file(fname, RAND_LOAD_LENGTH);
1068*6236dae4SAndroid Build Coastguard Worker       if(rand_enough())
1069*6236dae4SAndroid Build Coastguard Worker         return CURLE_OK;
1070*6236dae4SAndroid Build Coastguard Worker     }
1071*6236dae4SAndroid Build Coastguard Worker   }
1072*6236dae4SAndroid Build Coastguard Worker 
1073*6236dae4SAndroid Build Coastguard Worker   infof(data, "libcurl is now using a weak random seed");
1074*6236dae4SAndroid Build Coastguard Worker   return (rand_enough() ? CURLE_OK :
1075*6236dae4SAndroid Build Coastguard Worker           CURLE_SSL_CONNECT_ERROR /* confusing error code */);
1076*6236dae4SAndroid Build Coastguard Worker #endif
1077*6236dae4SAndroid Build Coastguard Worker }
1078*6236dae4SAndroid Build Coastguard Worker 
1079*6236dae4SAndroid Build Coastguard Worker #ifndef SSL_FILETYPE_ENGINE
1080*6236dae4SAndroid Build Coastguard Worker #define SSL_FILETYPE_ENGINE 42
1081*6236dae4SAndroid Build Coastguard Worker #endif
1082*6236dae4SAndroid Build Coastguard Worker #ifndef SSL_FILETYPE_PKCS12
1083*6236dae4SAndroid Build Coastguard Worker #define SSL_FILETYPE_PKCS12 43
1084*6236dae4SAndroid Build Coastguard Worker #endif
ossl_do_file_type(const char * type)1085*6236dae4SAndroid Build Coastguard Worker static int ossl_do_file_type(const char *type)
1086*6236dae4SAndroid Build Coastguard Worker {
1087*6236dae4SAndroid Build Coastguard Worker   if(!type || !type[0])
1088*6236dae4SAndroid Build Coastguard Worker     return SSL_FILETYPE_PEM;
1089*6236dae4SAndroid Build Coastguard Worker   if(strcasecompare(type, "PEM"))
1090*6236dae4SAndroid Build Coastguard Worker     return SSL_FILETYPE_PEM;
1091*6236dae4SAndroid Build Coastguard Worker   if(strcasecompare(type, "DER"))
1092*6236dae4SAndroid Build Coastguard Worker     return SSL_FILETYPE_ASN1;
1093*6236dae4SAndroid Build Coastguard Worker   if(strcasecompare(type, "ENG"))
1094*6236dae4SAndroid Build Coastguard Worker     return SSL_FILETYPE_ENGINE;
1095*6236dae4SAndroid Build Coastguard Worker   if(strcasecompare(type, "P12"))
1096*6236dae4SAndroid Build Coastguard Worker     return SSL_FILETYPE_PKCS12;
1097*6236dae4SAndroid Build Coastguard Worker   return -1;
1098*6236dae4SAndroid Build Coastguard Worker }
1099*6236dae4SAndroid Build Coastguard Worker 
1100*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1101*6236dae4SAndroid Build Coastguard Worker /*
1102*6236dae4SAndroid Build Coastguard Worker  * Supply default password to the engine user interface conversation.
1103*6236dae4SAndroid Build Coastguard Worker  * The password is passed by OpenSSL engine from ENGINE_load_private_key()
1104*6236dae4SAndroid Build Coastguard Worker  * last argument to the ui and can be obtained by UI_get0_user_data(ui) here.
1105*6236dae4SAndroid Build Coastguard Worker  */
ssl_ui_reader(UI * ui,UI_STRING * uis)1106*6236dae4SAndroid Build Coastguard Worker static int ssl_ui_reader(UI *ui, UI_STRING *uis)
1107*6236dae4SAndroid Build Coastguard Worker {
1108*6236dae4SAndroid Build Coastguard Worker   const char *password;
1109*6236dae4SAndroid Build Coastguard Worker   switch(UI_get_string_type(uis)) {
1110*6236dae4SAndroid Build Coastguard Worker   case UIT_PROMPT:
1111*6236dae4SAndroid Build Coastguard Worker   case UIT_VERIFY:
1112*6236dae4SAndroid Build Coastguard Worker     password = (const char *)UI_get0_user_data(ui);
1113*6236dae4SAndroid Build Coastguard Worker     if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
1114*6236dae4SAndroid Build Coastguard Worker       UI_set_result(ui, uis, password);
1115*6236dae4SAndroid Build Coastguard Worker       return 1;
1116*6236dae4SAndroid Build Coastguard Worker     }
1117*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
1118*6236dae4SAndroid Build Coastguard Worker   default:
1119*6236dae4SAndroid Build Coastguard Worker     break;
1120*6236dae4SAndroid Build Coastguard Worker   }
1121*6236dae4SAndroid Build Coastguard Worker   return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
1122*6236dae4SAndroid Build Coastguard Worker }
1123*6236dae4SAndroid Build Coastguard Worker 
1124*6236dae4SAndroid Build Coastguard Worker /*
1125*6236dae4SAndroid Build Coastguard Worker  * Suppress interactive request for a default password if available.
1126*6236dae4SAndroid Build Coastguard Worker  */
ssl_ui_writer(UI * ui,UI_STRING * uis)1127*6236dae4SAndroid Build Coastguard Worker static int ssl_ui_writer(UI *ui, UI_STRING *uis)
1128*6236dae4SAndroid Build Coastguard Worker {
1129*6236dae4SAndroid Build Coastguard Worker   switch(UI_get_string_type(uis)) {
1130*6236dae4SAndroid Build Coastguard Worker   case UIT_PROMPT:
1131*6236dae4SAndroid Build Coastguard Worker   case UIT_VERIFY:
1132*6236dae4SAndroid Build Coastguard Worker     if(UI_get0_user_data(ui) &&
1133*6236dae4SAndroid Build Coastguard Worker        (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
1134*6236dae4SAndroid Build Coastguard Worker       return 1;
1135*6236dae4SAndroid Build Coastguard Worker     }
1136*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
1137*6236dae4SAndroid Build Coastguard Worker   default:
1138*6236dae4SAndroid Build Coastguard Worker     break;
1139*6236dae4SAndroid Build Coastguard Worker   }
1140*6236dae4SAndroid Build Coastguard Worker   return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
1141*6236dae4SAndroid Build Coastguard Worker }
1142*6236dae4SAndroid Build Coastguard Worker 
1143*6236dae4SAndroid Build Coastguard Worker /*
1144*6236dae4SAndroid Build Coastguard Worker  * Check if a given string is a PKCS#11 URI
1145*6236dae4SAndroid Build Coastguard Worker  */
is_pkcs11_uri(const char * string)1146*6236dae4SAndroid Build Coastguard Worker static bool is_pkcs11_uri(const char *string)
1147*6236dae4SAndroid Build Coastguard Worker {
1148*6236dae4SAndroid Build Coastguard Worker   return (string && strncasecompare(string, "pkcs11:", 7));
1149*6236dae4SAndroid Build Coastguard Worker }
1150*6236dae4SAndroid Build Coastguard Worker 
1151*6236dae4SAndroid Build Coastguard Worker #endif
1152*6236dae4SAndroid Build Coastguard Worker 
1153*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_set_engine(struct Curl_easy *data, const char *engine);
1154*6236dae4SAndroid Build Coastguard Worker 
1155*6236dae4SAndroid Build Coastguard Worker static int
SSL_CTX_use_certificate_blob(SSL_CTX * ctx,const struct curl_blob * blob,int type,const char * key_passwd)1156*6236dae4SAndroid Build Coastguard Worker SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
1157*6236dae4SAndroid Build Coastguard Worker                              int type, const char *key_passwd)
1158*6236dae4SAndroid Build Coastguard Worker {
1159*6236dae4SAndroid Build Coastguard Worker   int ret = 0;
1160*6236dae4SAndroid Build Coastguard Worker   X509 *x = NULL;
1161*6236dae4SAndroid Build Coastguard Worker   /* the typecast of blob->len is fine since it is guaranteed to never be
1162*6236dae4SAndroid Build Coastguard Worker      larger than CURL_MAX_INPUT_LENGTH */
1163*6236dae4SAndroid Build Coastguard Worker   BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
1164*6236dae4SAndroid Build Coastguard Worker   if(!in)
1165*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
1166*6236dae4SAndroid Build Coastguard Worker 
1167*6236dae4SAndroid Build Coastguard Worker   if(type == SSL_FILETYPE_ASN1) {
1168*6236dae4SAndroid Build Coastguard Worker     /* j = ERR_R_ASN1_LIB; */
1169*6236dae4SAndroid Build Coastguard Worker     x = d2i_X509_bio(in, NULL);
1170*6236dae4SAndroid Build Coastguard Worker   }
1171*6236dae4SAndroid Build Coastguard Worker   else if(type == SSL_FILETYPE_PEM) {
1172*6236dae4SAndroid Build Coastguard Worker     /* ERR_R_PEM_LIB; */
1173*6236dae4SAndroid Build Coastguard Worker     x = PEM_read_bio_X509(in, NULL,
1174*6236dae4SAndroid Build Coastguard Worker                           passwd_callback, (void *)key_passwd);
1175*6236dae4SAndroid Build Coastguard Worker   }
1176*6236dae4SAndroid Build Coastguard Worker   else {
1177*6236dae4SAndroid Build Coastguard Worker     ret = 0;
1178*6236dae4SAndroid Build Coastguard Worker     goto end;
1179*6236dae4SAndroid Build Coastguard Worker   }
1180*6236dae4SAndroid Build Coastguard Worker 
1181*6236dae4SAndroid Build Coastguard Worker   if(!x) {
1182*6236dae4SAndroid Build Coastguard Worker     ret = 0;
1183*6236dae4SAndroid Build Coastguard Worker     goto end;
1184*6236dae4SAndroid Build Coastguard Worker   }
1185*6236dae4SAndroid Build Coastguard Worker 
1186*6236dae4SAndroid Build Coastguard Worker   ret = SSL_CTX_use_certificate(ctx, x);
1187*6236dae4SAndroid Build Coastguard Worker end:
1188*6236dae4SAndroid Build Coastguard Worker   X509_free(x);
1189*6236dae4SAndroid Build Coastguard Worker   BIO_free(in);
1190*6236dae4SAndroid Build Coastguard Worker   return ret;
1191*6236dae4SAndroid Build Coastguard Worker }
1192*6236dae4SAndroid Build Coastguard Worker 
1193*6236dae4SAndroid Build Coastguard Worker static int
SSL_CTX_use_PrivateKey_blob(SSL_CTX * ctx,const struct curl_blob * blob,int type,const char * key_passwd)1194*6236dae4SAndroid Build Coastguard Worker SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
1195*6236dae4SAndroid Build Coastguard Worker                             int type, const char *key_passwd)
1196*6236dae4SAndroid Build Coastguard Worker {
1197*6236dae4SAndroid Build Coastguard Worker   int ret = 0;
1198*6236dae4SAndroid Build Coastguard Worker   EVP_PKEY *pkey = NULL;
1199*6236dae4SAndroid Build Coastguard Worker   BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
1200*6236dae4SAndroid Build Coastguard Worker   if(!in)
1201*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
1202*6236dae4SAndroid Build Coastguard Worker 
1203*6236dae4SAndroid Build Coastguard Worker   if(type == SSL_FILETYPE_PEM)
1204*6236dae4SAndroid Build Coastguard Worker     pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback,
1205*6236dae4SAndroid Build Coastguard Worker                                    (void *)key_passwd);
1206*6236dae4SAndroid Build Coastguard Worker   else if(type == SSL_FILETYPE_ASN1)
1207*6236dae4SAndroid Build Coastguard Worker     pkey = d2i_PrivateKey_bio(in, NULL);
1208*6236dae4SAndroid Build Coastguard Worker   else {
1209*6236dae4SAndroid Build Coastguard Worker     ret = 0;
1210*6236dae4SAndroid Build Coastguard Worker     goto end;
1211*6236dae4SAndroid Build Coastguard Worker   }
1212*6236dae4SAndroid Build Coastguard Worker   if(!pkey) {
1213*6236dae4SAndroid Build Coastguard Worker     ret = 0;
1214*6236dae4SAndroid Build Coastguard Worker     goto end;
1215*6236dae4SAndroid Build Coastguard Worker   }
1216*6236dae4SAndroid Build Coastguard Worker   ret = SSL_CTX_use_PrivateKey(ctx, pkey);
1217*6236dae4SAndroid Build Coastguard Worker   EVP_PKEY_free(pkey);
1218*6236dae4SAndroid Build Coastguard Worker end:
1219*6236dae4SAndroid Build Coastguard Worker   BIO_free(in);
1220*6236dae4SAndroid Build Coastguard Worker   return ret;
1221*6236dae4SAndroid Build Coastguard Worker }
1222*6236dae4SAndroid Build Coastguard Worker 
1223*6236dae4SAndroid Build Coastguard Worker static int
SSL_CTX_use_certificate_chain_blob(SSL_CTX * ctx,const struct curl_blob * blob,const char * key_passwd)1224*6236dae4SAndroid Build Coastguard Worker SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
1225*6236dae4SAndroid Build Coastguard Worker                                    const char *key_passwd)
1226*6236dae4SAndroid Build Coastguard Worker {
1227*6236dae4SAndroid Build Coastguard Worker /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
1228*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \
1229*6236dae4SAndroid Build Coastguard Worker   !(defined(LIBRESSL_VERSION_NUMBER) &&                                     \
1230*6236dae4SAndroid Build Coastguard Worker     (LIBRESSL_VERSION_NUMBER < 0x2090100fL)) /* LibreSSL 2.9.1 or later */
1231*6236dae4SAndroid Build Coastguard Worker   int ret = 0;
1232*6236dae4SAndroid Build Coastguard Worker   X509 *x = NULL;
1233*6236dae4SAndroid Build Coastguard Worker   void *passwd_callback_userdata = (void *)key_passwd;
1234*6236dae4SAndroid Build Coastguard Worker   BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
1235*6236dae4SAndroid Build Coastguard Worker   if(!in)
1236*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
1237*6236dae4SAndroid Build Coastguard Worker 
1238*6236dae4SAndroid Build Coastguard Worker   ERR_clear_error();
1239*6236dae4SAndroid Build Coastguard Worker 
1240*6236dae4SAndroid Build Coastguard Worker   x = PEM_read_bio_X509_AUX(in, NULL,
1241*6236dae4SAndroid Build Coastguard Worker                             passwd_callback, (void *)key_passwd);
1242*6236dae4SAndroid Build Coastguard Worker 
1243*6236dae4SAndroid Build Coastguard Worker   if(!x) {
1244*6236dae4SAndroid Build Coastguard Worker     ret = 0;
1245*6236dae4SAndroid Build Coastguard Worker     goto end;
1246*6236dae4SAndroid Build Coastguard Worker   }
1247*6236dae4SAndroid Build Coastguard Worker 
1248*6236dae4SAndroid Build Coastguard Worker   ret = SSL_CTX_use_certificate(ctx, x);
1249*6236dae4SAndroid Build Coastguard Worker 
1250*6236dae4SAndroid Build Coastguard Worker   if(ERR_peek_error() != 0)
1251*6236dae4SAndroid Build Coastguard Worker     ret = 0;
1252*6236dae4SAndroid Build Coastguard Worker 
1253*6236dae4SAndroid Build Coastguard Worker   if(ret) {
1254*6236dae4SAndroid Build Coastguard Worker     X509 *ca;
1255*6236dae4SAndroid Build Coastguard Worker     sslerr_t err;
1256*6236dae4SAndroid Build Coastguard Worker 
1257*6236dae4SAndroid Build Coastguard Worker     if(!SSL_CTX_clear_chain_certs(ctx)) {
1258*6236dae4SAndroid Build Coastguard Worker       ret = 0;
1259*6236dae4SAndroid Build Coastguard Worker       goto end;
1260*6236dae4SAndroid Build Coastguard Worker     }
1261*6236dae4SAndroid Build Coastguard Worker 
1262*6236dae4SAndroid Build Coastguard Worker     while((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
1263*6236dae4SAndroid Build Coastguard Worker                                   passwd_callback_userdata))
1264*6236dae4SAndroid Build Coastguard Worker           != NULL) {
1265*6236dae4SAndroid Build Coastguard Worker 
1266*6236dae4SAndroid Build Coastguard Worker       if(!SSL_CTX_add0_chain_cert(ctx, ca)) {
1267*6236dae4SAndroid Build Coastguard Worker         X509_free(ca);
1268*6236dae4SAndroid Build Coastguard Worker         ret = 0;
1269*6236dae4SAndroid Build Coastguard Worker         goto end;
1270*6236dae4SAndroid Build Coastguard Worker       }
1271*6236dae4SAndroid Build Coastguard Worker     }
1272*6236dae4SAndroid Build Coastguard Worker 
1273*6236dae4SAndroid Build Coastguard Worker     err = ERR_peek_last_error();
1274*6236dae4SAndroid Build Coastguard Worker     if((ERR_GET_LIB(err) == ERR_LIB_PEM) &&
1275*6236dae4SAndroid Build Coastguard Worker        (ERR_GET_REASON(err) == PEM_R_NO_START_LINE))
1276*6236dae4SAndroid Build Coastguard Worker       ERR_clear_error();
1277*6236dae4SAndroid Build Coastguard Worker     else
1278*6236dae4SAndroid Build Coastguard Worker       ret = 0;
1279*6236dae4SAndroid Build Coastguard Worker   }
1280*6236dae4SAndroid Build Coastguard Worker 
1281*6236dae4SAndroid Build Coastguard Worker end:
1282*6236dae4SAndroid Build Coastguard Worker   X509_free(x);
1283*6236dae4SAndroid Build Coastguard Worker   BIO_free(in);
1284*6236dae4SAndroid Build Coastguard Worker   return ret;
1285*6236dae4SAndroid Build Coastguard Worker #else
1286*6236dae4SAndroid Build Coastguard Worker   (void)ctx; /* unused */
1287*6236dae4SAndroid Build Coastguard Worker   (void)blob; /* unused */
1288*6236dae4SAndroid Build Coastguard Worker   (void)key_passwd; /* unused */
1289*6236dae4SAndroid Build Coastguard Worker   return 0;
1290*6236dae4SAndroid Build Coastguard Worker #endif
1291*6236dae4SAndroid Build Coastguard Worker }
1292*6236dae4SAndroid Build Coastguard Worker 
1293*6236dae4SAndroid Build Coastguard Worker static
cert_stuff(struct Curl_easy * data,SSL_CTX * ctx,char * cert_file,const struct curl_blob * cert_blob,const char * cert_type,char * key_file,const struct curl_blob * key_blob,const char * key_type,char * key_passwd)1294*6236dae4SAndroid Build Coastguard Worker int cert_stuff(struct Curl_easy *data,
1295*6236dae4SAndroid Build Coastguard Worker                SSL_CTX* ctx,
1296*6236dae4SAndroid Build Coastguard Worker                char *cert_file,
1297*6236dae4SAndroid Build Coastguard Worker                const struct curl_blob *cert_blob,
1298*6236dae4SAndroid Build Coastguard Worker                const char *cert_type,
1299*6236dae4SAndroid Build Coastguard Worker                char *key_file,
1300*6236dae4SAndroid Build Coastguard Worker                const struct curl_blob *key_blob,
1301*6236dae4SAndroid Build Coastguard Worker                const char *key_type,
1302*6236dae4SAndroid Build Coastguard Worker                char *key_passwd)
1303*6236dae4SAndroid Build Coastguard Worker {
1304*6236dae4SAndroid Build Coastguard Worker   char error_buffer[256];
1305*6236dae4SAndroid Build Coastguard Worker   bool check_privkey = TRUE;
1306*6236dae4SAndroid Build Coastguard Worker 
1307*6236dae4SAndroid Build Coastguard Worker   int file_type = ossl_do_file_type(cert_type);
1308*6236dae4SAndroid Build Coastguard Worker 
1309*6236dae4SAndroid Build Coastguard Worker   if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE)) {
1310*6236dae4SAndroid Build Coastguard Worker     SSL *ssl;
1311*6236dae4SAndroid Build Coastguard Worker     X509 *x509;
1312*6236dae4SAndroid Build Coastguard Worker     int cert_done = 0;
1313*6236dae4SAndroid Build Coastguard Worker     int cert_use_result;
1314*6236dae4SAndroid Build Coastguard Worker 
1315*6236dae4SAndroid Build Coastguard Worker     if(key_passwd) {
1316*6236dae4SAndroid Build Coastguard Worker       /* set the password in the callback userdata */
1317*6236dae4SAndroid Build Coastguard Worker       SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd);
1318*6236dae4SAndroid Build Coastguard Worker       /* Set passwd callback: */
1319*6236dae4SAndroid Build Coastguard Worker       SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
1320*6236dae4SAndroid Build Coastguard Worker     }
1321*6236dae4SAndroid Build Coastguard Worker 
1322*6236dae4SAndroid Build Coastguard Worker 
1323*6236dae4SAndroid Build Coastguard Worker     switch(file_type) {
1324*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_PEM:
1325*6236dae4SAndroid Build Coastguard Worker       /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
1326*6236dae4SAndroid Build Coastguard Worker       cert_use_result = cert_blob ?
1327*6236dae4SAndroid Build Coastguard Worker         SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) :
1328*6236dae4SAndroid Build Coastguard Worker         SSL_CTX_use_certificate_chain_file(ctx, cert_file);
1329*6236dae4SAndroid Build Coastguard Worker       if(cert_use_result != 1) {
1330*6236dae4SAndroid Build Coastguard Worker         failf(data,
1331*6236dae4SAndroid Build Coastguard Worker               "could not load PEM client certificate from %s, " OSSL_PACKAGE
1332*6236dae4SAndroid Build Coastguard Worker               " error %s, "
1333*6236dae4SAndroid Build Coastguard Worker               "(no key found, wrong pass phrase, or wrong file format?)",
1334*6236dae4SAndroid Build Coastguard Worker               (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file),
1335*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(ERR_get_error(), error_buffer,
1336*6236dae4SAndroid Build Coastguard Worker                             sizeof(error_buffer)) );
1337*6236dae4SAndroid Build Coastguard Worker         return 0;
1338*6236dae4SAndroid Build Coastguard Worker       }
1339*6236dae4SAndroid Build Coastguard Worker       break;
1340*6236dae4SAndroid Build Coastguard Worker 
1341*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_ASN1:
1342*6236dae4SAndroid Build Coastguard Worker       /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
1343*6236dae4SAndroid Build Coastguard Worker          we use the case above for PEM so this can only be performed with
1344*6236dae4SAndroid Build Coastguard Worker          ASN1 files. */
1345*6236dae4SAndroid Build Coastguard Worker 
1346*6236dae4SAndroid Build Coastguard Worker       cert_use_result = cert_blob ?
1347*6236dae4SAndroid Build Coastguard Worker         SSL_CTX_use_certificate_blob(ctx, cert_blob,
1348*6236dae4SAndroid Build Coastguard Worker                                      file_type, key_passwd) :
1349*6236dae4SAndroid Build Coastguard Worker       SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
1350*6236dae4SAndroid Build Coastguard Worker       if(cert_use_result != 1) {
1351*6236dae4SAndroid Build Coastguard Worker         failf(data,
1352*6236dae4SAndroid Build Coastguard Worker               "could not load ASN1 client certificate from %s, " OSSL_PACKAGE
1353*6236dae4SAndroid Build Coastguard Worker               " error %s, "
1354*6236dae4SAndroid Build Coastguard Worker               "(no key found, wrong pass phrase, or wrong file format?)",
1355*6236dae4SAndroid Build Coastguard Worker               (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file),
1356*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(ERR_get_error(), error_buffer,
1357*6236dae4SAndroid Build Coastguard Worker                             sizeof(error_buffer)) );
1358*6236dae4SAndroid Build Coastguard Worker         return 0;
1359*6236dae4SAndroid Build Coastguard Worker       }
1360*6236dae4SAndroid Build Coastguard Worker       break;
1361*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_ENGINE:
1362*6236dae4SAndroid Build Coastguard Worker #if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
1363*6236dae4SAndroid Build Coastguard Worker     {
1364*6236dae4SAndroid Build Coastguard Worker       /* Implicitly use pkcs11 engine if none was provided and the
1365*6236dae4SAndroid Build Coastguard Worker        * cert_file is a PKCS#11 URI */
1366*6236dae4SAndroid Build Coastguard Worker       if(!data->state.engine) {
1367*6236dae4SAndroid Build Coastguard Worker         if(is_pkcs11_uri(cert_file)) {
1368*6236dae4SAndroid Build Coastguard Worker           if(ossl_set_engine(data, "pkcs11") != CURLE_OK) {
1369*6236dae4SAndroid Build Coastguard Worker             return 0;
1370*6236dae4SAndroid Build Coastguard Worker           }
1371*6236dae4SAndroid Build Coastguard Worker         }
1372*6236dae4SAndroid Build Coastguard Worker       }
1373*6236dae4SAndroid Build Coastguard Worker 
1374*6236dae4SAndroid Build Coastguard Worker       if(data->state.engine) {
1375*6236dae4SAndroid Build Coastguard Worker         const char *cmd_name = "LOAD_CERT_CTRL";
1376*6236dae4SAndroid Build Coastguard Worker         struct {
1377*6236dae4SAndroid Build Coastguard Worker           const char *cert_id;
1378*6236dae4SAndroid Build Coastguard Worker           X509 *cert;
1379*6236dae4SAndroid Build Coastguard Worker         } params;
1380*6236dae4SAndroid Build Coastguard Worker 
1381*6236dae4SAndroid Build Coastguard Worker         params.cert_id = cert_file;
1382*6236dae4SAndroid Build Coastguard Worker         params.cert = NULL;
1383*6236dae4SAndroid Build Coastguard Worker 
1384*6236dae4SAndroid Build Coastguard Worker         /* Does the engine supports LOAD_CERT_CTRL ? */
1385*6236dae4SAndroid Build Coastguard Worker         if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
1386*6236dae4SAndroid Build Coastguard Worker                         0, (void *)cmd_name, NULL)) {
1387*6236dae4SAndroid Build Coastguard Worker           failf(data, "ssl engine does not support loading certificates");
1388*6236dae4SAndroid Build Coastguard Worker           return 0;
1389*6236dae4SAndroid Build Coastguard Worker         }
1390*6236dae4SAndroid Build Coastguard Worker 
1391*6236dae4SAndroid Build Coastguard Worker         /* Load the certificate from the engine */
1392*6236dae4SAndroid Build Coastguard Worker         if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
1393*6236dae4SAndroid Build Coastguard Worker                             0, &params, NULL, 1)) {
1394*6236dae4SAndroid Build Coastguard Worker           failf(data, "ssl engine cannot load client cert with id"
1395*6236dae4SAndroid Build Coastguard Worker                 " '%s' [%s]", cert_file,
1396*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
1397*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)));
1398*6236dae4SAndroid Build Coastguard Worker           return 0;
1399*6236dae4SAndroid Build Coastguard Worker         }
1400*6236dae4SAndroid Build Coastguard Worker 
1401*6236dae4SAndroid Build Coastguard Worker         if(!params.cert) {
1402*6236dae4SAndroid Build Coastguard Worker           failf(data, "ssl engine did not initialized the certificate "
1403*6236dae4SAndroid Build Coastguard Worker                 "properly.");
1404*6236dae4SAndroid Build Coastguard Worker           return 0;
1405*6236dae4SAndroid Build Coastguard Worker         }
1406*6236dae4SAndroid Build Coastguard Worker 
1407*6236dae4SAndroid Build Coastguard Worker         if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
1408*6236dae4SAndroid Build Coastguard Worker           failf(data, "unable to set client certificate [%s]",
1409*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
1410*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)));
1411*6236dae4SAndroid Build Coastguard Worker           return 0;
1412*6236dae4SAndroid Build Coastguard Worker         }
1413*6236dae4SAndroid Build Coastguard Worker         X509_free(params.cert); /* we do not need the handle any more... */
1414*6236dae4SAndroid Build Coastguard Worker       }
1415*6236dae4SAndroid Build Coastguard Worker       else {
1416*6236dae4SAndroid Build Coastguard Worker         failf(data, "crypto engine not set, cannot load certificate");
1417*6236dae4SAndroid Build Coastguard Worker         return 0;
1418*6236dae4SAndroid Build Coastguard Worker       }
1419*6236dae4SAndroid Build Coastguard Worker     }
1420*6236dae4SAndroid Build Coastguard Worker     break;
1421*6236dae4SAndroid Build Coastguard Worker #else
1422*6236dae4SAndroid Build Coastguard Worker     failf(data, "file type ENG for certificate not implemented");
1423*6236dae4SAndroid Build Coastguard Worker     return 0;
1424*6236dae4SAndroid Build Coastguard Worker #endif
1425*6236dae4SAndroid Build Coastguard Worker 
1426*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_PKCS12:
1427*6236dae4SAndroid Build Coastguard Worker     {
1428*6236dae4SAndroid Build Coastguard Worker       BIO *cert_bio = NULL;
1429*6236dae4SAndroid Build Coastguard Worker       PKCS12 *p12 = NULL;
1430*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY *pri;
1431*6236dae4SAndroid Build Coastguard Worker       STACK_OF(X509) *ca = NULL;
1432*6236dae4SAndroid Build Coastguard Worker       if(cert_blob) {
1433*6236dae4SAndroid Build Coastguard Worker         cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len));
1434*6236dae4SAndroid Build Coastguard Worker         if(!cert_bio) {
1435*6236dae4SAndroid Build Coastguard Worker           failf(data,
1436*6236dae4SAndroid Build Coastguard Worker                 "BIO_new_mem_buf NULL, " OSSL_PACKAGE
1437*6236dae4SAndroid Build Coastguard Worker                 " error %s",
1438*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
1439*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)) );
1440*6236dae4SAndroid Build Coastguard Worker           return 0;
1441*6236dae4SAndroid Build Coastguard Worker         }
1442*6236dae4SAndroid Build Coastguard Worker       }
1443*6236dae4SAndroid Build Coastguard Worker       else {
1444*6236dae4SAndroid Build Coastguard Worker         cert_bio = BIO_new(BIO_s_file());
1445*6236dae4SAndroid Build Coastguard Worker         if(!cert_bio) {
1446*6236dae4SAndroid Build Coastguard Worker           failf(data,
1447*6236dae4SAndroid Build Coastguard Worker                 "BIO_new return NULL, " OSSL_PACKAGE
1448*6236dae4SAndroid Build Coastguard Worker                 " error %s",
1449*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
1450*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)) );
1451*6236dae4SAndroid Build Coastguard Worker           return 0;
1452*6236dae4SAndroid Build Coastguard Worker         }
1453*6236dae4SAndroid Build Coastguard Worker 
1454*6236dae4SAndroid Build Coastguard Worker         if(BIO_read_filename(cert_bio, cert_file) <= 0) {
1455*6236dae4SAndroid Build Coastguard Worker           failf(data, "could not open PKCS12 file '%s'", cert_file);
1456*6236dae4SAndroid Build Coastguard Worker           BIO_free(cert_bio);
1457*6236dae4SAndroid Build Coastguard Worker           return 0;
1458*6236dae4SAndroid Build Coastguard Worker         }
1459*6236dae4SAndroid Build Coastguard Worker       }
1460*6236dae4SAndroid Build Coastguard Worker 
1461*6236dae4SAndroid Build Coastguard Worker       p12 = d2i_PKCS12_bio(cert_bio, NULL);
1462*6236dae4SAndroid Build Coastguard Worker       BIO_free(cert_bio);
1463*6236dae4SAndroid Build Coastguard Worker 
1464*6236dae4SAndroid Build Coastguard Worker       if(!p12) {
1465*6236dae4SAndroid Build Coastguard Worker         failf(data, "error reading PKCS12 file '%s'",
1466*6236dae4SAndroid Build Coastguard Worker               cert_blob ? "(memory blob)" : cert_file);
1467*6236dae4SAndroid Build Coastguard Worker         return 0;
1468*6236dae4SAndroid Build Coastguard Worker       }
1469*6236dae4SAndroid Build Coastguard Worker 
1470*6236dae4SAndroid Build Coastguard Worker       PKCS12_PBE_add();
1471*6236dae4SAndroid Build Coastguard Worker 
1472*6236dae4SAndroid Build Coastguard Worker       if(!PKCS12_parse(p12, key_passwd, &pri, &x509,
1473*6236dae4SAndroid Build Coastguard Worker                        &ca)) {
1474*6236dae4SAndroid Build Coastguard Worker         failf(data,
1475*6236dae4SAndroid Build Coastguard Worker               "could not parse PKCS12 file, check password, " OSSL_PACKAGE
1476*6236dae4SAndroid Build Coastguard Worker               " error %s",
1477*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(ERR_get_error(), error_buffer,
1478*6236dae4SAndroid Build Coastguard Worker                             sizeof(error_buffer)) );
1479*6236dae4SAndroid Build Coastguard Worker         PKCS12_free(p12);
1480*6236dae4SAndroid Build Coastguard Worker         return 0;
1481*6236dae4SAndroid Build Coastguard Worker       }
1482*6236dae4SAndroid Build Coastguard Worker 
1483*6236dae4SAndroid Build Coastguard Worker       PKCS12_free(p12);
1484*6236dae4SAndroid Build Coastguard Worker 
1485*6236dae4SAndroid Build Coastguard Worker       if(SSL_CTX_use_certificate(ctx, x509) != 1) {
1486*6236dae4SAndroid Build Coastguard Worker         failf(data,
1487*6236dae4SAndroid Build Coastguard Worker               "could not load PKCS12 client certificate, " OSSL_PACKAGE
1488*6236dae4SAndroid Build Coastguard Worker               " error %s",
1489*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(ERR_get_error(), error_buffer,
1490*6236dae4SAndroid Build Coastguard Worker                             sizeof(error_buffer)) );
1491*6236dae4SAndroid Build Coastguard Worker         goto fail;
1492*6236dae4SAndroid Build Coastguard Worker       }
1493*6236dae4SAndroid Build Coastguard Worker 
1494*6236dae4SAndroid Build Coastguard Worker       if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
1495*6236dae4SAndroid Build Coastguard Worker         failf(data, "unable to use private key from PKCS12 file '%s'",
1496*6236dae4SAndroid Build Coastguard Worker               cert_file);
1497*6236dae4SAndroid Build Coastguard Worker         goto fail;
1498*6236dae4SAndroid Build Coastguard Worker       }
1499*6236dae4SAndroid Build Coastguard Worker 
1500*6236dae4SAndroid Build Coastguard Worker       if(!SSL_CTX_check_private_key (ctx)) {
1501*6236dae4SAndroid Build Coastguard Worker         failf(data, "private key from PKCS12 file '%s' "
1502*6236dae4SAndroid Build Coastguard Worker               "does not match certificate in same file", cert_file);
1503*6236dae4SAndroid Build Coastguard Worker         goto fail;
1504*6236dae4SAndroid Build Coastguard Worker       }
1505*6236dae4SAndroid Build Coastguard Worker       /* Set Certificate Verification chain */
1506*6236dae4SAndroid Build Coastguard Worker       if(ca) {
1507*6236dae4SAndroid Build Coastguard Worker         while(sk_X509_num(ca)) {
1508*6236dae4SAndroid Build Coastguard Worker           /*
1509*6236dae4SAndroid Build Coastguard Worker            * Note that sk_X509_pop() is used below to make sure the cert is
1510*6236dae4SAndroid Build Coastguard Worker            * removed from the stack properly before getting passed to
1511*6236dae4SAndroid Build Coastguard Worker            * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously
1512*6236dae4SAndroid Build Coastguard Worker            * we used sk_X509_value() instead, but then we would clean it in the
1513*6236dae4SAndroid Build Coastguard Worker            * subsequent sk_X509_pop_free() call.
1514*6236dae4SAndroid Build Coastguard Worker            */
1515*6236dae4SAndroid Build Coastguard Worker           X509 *x = sk_X509_pop(ca);
1516*6236dae4SAndroid Build Coastguard Worker           if(!SSL_CTX_add_client_CA(ctx, x)) {
1517*6236dae4SAndroid Build Coastguard Worker             X509_free(x);
1518*6236dae4SAndroid Build Coastguard Worker             failf(data, "cannot add certificate to client CA list");
1519*6236dae4SAndroid Build Coastguard Worker             goto fail;
1520*6236dae4SAndroid Build Coastguard Worker           }
1521*6236dae4SAndroid Build Coastguard Worker           if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
1522*6236dae4SAndroid Build Coastguard Worker             X509_free(x);
1523*6236dae4SAndroid Build Coastguard Worker             failf(data, "cannot add certificate to certificate chain");
1524*6236dae4SAndroid Build Coastguard Worker             goto fail;
1525*6236dae4SAndroid Build Coastguard Worker           }
1526*6236dae4SAndroid Build Coastguard Worker         }
1527*6236dae4SAndroid Build Coastguard Worker       }
1528*6236dae4SAndroid Build Coastguard Worker 
1529*6236dae4SAndroid Build Coastguard Worker       cert_done = 1;
1530*6236dae4SAndroid Build Coastguard Worker fail:
1531*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY_free(pri);
1532*6236dae4SAndroid Build Coastguard Worker       X509_free(x509);
1533*6236dae4SAndroid Build Coastguard Worker       sk_X509_pop_free(ca, X509_free);
1534*6236dae4SAndroid Build Coastguard Worker       if(!cert_done)
1535*6236dae4SAndroid Build Coastguard Worker         return 0; /* failure! */
1536*6236dae4SAndroid Build Coastguard Worker       break;
1537*6236dae4SAndroid Build Coastguard Worker     }
1538*6236dae4SAndroid Build Coastguard Worker     default:
1539*6236dae4SAndroid Build Coastguard Worker       failf(data, "not supported file type '%s' for certificate", cert_type);
1540*6236dae4SAndroid Build Coastguard Worker       return 0;
1541*6236dae4SAndroid Build Coastguard Worker     }
1542*6236dae4SAndroid Build Coastguard Worker 
1543*6236dae4SAndroid Build Coastguard Worker     if((!key_file) && (!key_blob)) {
1544*6236dae4SAndroid Build Coastguard Worker       key_file = cert_file;
1545*6236dae4SAndroid Build Coastguard Worker       key_blob = cert_blob;
1546*6236dae4SAndroid Build Coastguard Worker     }
1547*6236dae4SAndroid Build Coastguard Worker     else
1548*6236dae4SAndroid Build Coastguard Worker       file_type = ossl_do_file_type(key_type);
1549*6236dae4SAndroid Build Coastguard Worker 
1550*6236dae4SAndroid Build Coastguard Worker     switch(file_type) {
1551*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_PEM:
1552*6236dae4SAndroid Build Coastguard Worker       if(cert_done)
1553*6236dae4SAndroid Build Coastguard Worker         break;
1554*6236dae4SAndroid Build Coastguard Worker       FALLTHROUGH();
1555*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_ASN1:
1556*6236dae4SAndroid Build Coastguard Worker       cert_use_result = key_blob ?
1557*6236dae4SAndroid Build Coastguard Worker         SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) :
1558*6236dae4SAndroid Build Coastguard Worker       SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type);
1559*6236dae4SAndroid Build Coastguard Worker       if(cert_use_result != 1) {
1560*6236dae4SAndroid Build Coastguard Worker         failf(data, "unable to set private key file: '%s' type %s",
1561*6236dae4SAndroid Build Coastguard Worker               key_file ? key_file : "(memory blob)",
1562*6236dae4SAndroid Build Coastguard Worker               key_type ? key_type : "PEM");
1563*6236dae4SAndroid Build Coastguard Worker         return 0;
1564*6236dae4SAndroid Build Coastguard Worker       }
1565*6236dae4SAndroid Build Coastguard Worker       break;
1566*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_ENGINE:
1567*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1568*6236dae4SAndroid Build Coastguard Worker     {
1569*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY *priv_key = NULL;
1570*6236dae4SAndroid Build Coastguard Worker 
1571*6236dae4SAndroid Build Coastguard Worker       /* Implicitly use pkcs11 engine if none was provided and the
1572*6236dae4SAndroid Build Coastguard Worker        * key_file is a PKCS#11 URI */
1573*6236dae4SAndroid Build Coastguard Worker       if(!data->state.engine) {
1574*6236dae4SAndroid Build Coastguard Worker         if(is_pkcs11_uri(key_file)) {
1575*6236dae4SAndroid Build Coastguard Worker           if(ossl_set_engine(data, "pkcs11") != CURLE_OK) {
1576*6236dae4SAndroid Build Coastguard Worker             return 0;
1577*6236dae4SAndroid Build Coastguard Worker           }
1578*6236dae4SAndroid Build Coastguard Worker         }
1579*6236dae4SAndroid Build Coastguard Worker       }
1580*6236dae4SAndroid Build Coastguard Worker 
1581*6236dae4SAndroid Build Coastguard Worker       if(data->state.engine) {
1582*6236dae4SAndroid Build Coastguard Worker         UI_METHOD *ui_method =
1583*6236dae4SAndroid Build Coastguard Worker           UI_create_method((char *)"curl user interface");
1584*6236dae4SAndroid Build Coastguard Worker         if(!ui_method) {
1585*6236dae4SAndroid Build Coastguard Worker           failf(data, "unable do create " OSSL_PACKAGE
1586*6236dae4SAndroid Build Coastguard Worker                 " user-interface method");
1587*6236dae4SAndroid Build Coastguard Worker           return 0;
1588*6236dae4SAndroid Build Coastguard Worker         }
1589*6236dae4SAndroid Build Coastguard Worker         UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
1590*6236dae4SAndroid Build Coastguard Worker         UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
1591*6236dae4SAndroid Build Coastguard Worker         UI_method_set_reader(ui_method, ssl_ui_reader);
1592*6236dae4SAndroid Build Coastguard Worker         UI_method_set_writer(ui_method, ssl_ui_writer);
1593*6236dae4SAndroid Build Coastguard Worker         priv_key = ENGINE_load_private_key(data->state.engine, key_file,
1594*6236dae4SAndroid Build Coastguard Worker                                            ui_method,
1595*6236dae4SAndroid Build Coastguard Worker                                            key_passwd);
1596*6236dae4SAndroid Build Coastguard Worker         UI_destroy_method(ui_method);
1597*6236dae4SAndroid Build Coastguard Worker         if(!priv_key) {
1598*6236dae4SAndroid Build Coastguard Worker           failf(data, "failed to load private key from crypto engine");
1599*6236dae4SAndroid Build Coastguard Worker           return 0;
1600*6236dae4SAndroid Build Coastguard Worker         }
1601*6236dae4SAndroid Build Coastguard Worker         if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
1602*6236dae4SAndroid Build Coastguard Worker           failf(data, "unable to set private key");
1603*6236dae4SAndroid Build Coastguard Worker           EVP_PKEY_free(priv_key);
1604*6236dae4SAndroid Build Coastguard Worker           return 0;
1605*6236dae4SAndroid Build Coastguard Worker         }
1606*6236dae4SAndroid Build Coastguard Worker         EVP_PKEY_free(priv_key);  /* we do not need the handle any more... */
1607*6236dae4SAndroid Build Coastguard Worker       }
1608*6236dae4SAndroid Build Coastguard Worker       else {
1609*6236dae4SAndroid Build Coastguard Worker         failf(data, "crypto engine not set, cannot load private key");
1610*6236dae4SAndroid Build Coastguard Worker         return 0;
1611*6236dae4SAndroid Build Coastguard Worker       }
1612*6236dae4SAndroid Build Coastguard Worker     }
1613*6236dae4SAndroid Build Coastguard Worker     break;
1614*6236dae4SAndroid Build Coastguard Worker #else
1615*6236dae4SAndroid Build Coastguard Worker     failf(data, "file type ENG for private key not supported");
1616*6236dae4SAndroid Build Coastguard Worker     return 0;
1617*6236dae4SAndroid Build Coastguard Worker #endif
1618*6236dae4SAndroid Build Coastguard Worker     case SSL_FILETYPE_PKCS12:
1619*6236dae4SAndroid Build Coastguard Worker       if(!cert_done) {
1620*6236dae4SAndroid Build Coastguard Worker         failf(data, "file type P12 for private key not supported");
1621*6236dae4SAndroid Build Coastguard Worker         return 0;
1622*6236dae4SAndroid Build Coastguard Worker       }
1623*6236dae4SAndroid Build Coastguard Worker       break;
1624*6236dae4SAndroid Build Coastguard Worker     default:
1625*6236dae4SAndroid Build Coastguard Worker       failf(data, "not supported file type for private key");
1626*6236dae4SAndroid Build Coastguard Worker       return 0;
1627*6236dae4SAndroid Build Coastguard Worker     }
1628*6236dae4SAndroid Build Coastguard Worker 
1629*6236dae4SAndroid Build Coastguard Worker     ssl = SSL_new(ctx);
1630*6236dae4SAndroid Build Coastguard Worker     if(!ssl) {
1631*6236dae4SAndroid Build Coastguard Worker       failf(data, "unable to create an SSL structure");
1632*6236dae4SAndroid Build Coastguard Worker       return 0;
1633*6236dae4SAndroid Build Coastguard Worker     }
1634*6236dae4SAndroid Build Coastguard Worker 
1635*6236dae4SAndroid Build Coastguard Worker     x509 = SSL_get_certificate(ssl);
1636*6236dae4SAndroid Build Coastguard Worker 
1637*6236dae4SAndroid Build Coastguard Worker     /* This version was provided by Evan Jordan and is supposed to not
1638*6236dae4SAndroid Build Coastguard Worker        leak memory as the previous version: */
1639*6236dae4SAndroid Build Coastguard Worker     if(x509) {
1640*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY *pktmp = X509_get_pubkey(x509);
1641*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl));
1642*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY_free(pktmp);
1643*6236dae4SAndroid Build Coastguard Worker     }
1644*6236dae4SAndroid Build Coastguard Worker 
1645*6236dae4SAndroid Build Coastguard Worker #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL) &&       \
1646*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_DEPRECATED_3_0)
1647*6236dae4SAndroid Build Coastguard Worker     {
1648*6236dae4SAndroid Build Coastguard Worker       /* If RSA is used, do not check the private key if its flags indicate
1649*6236dae4SAndroid Build Coastguard Worker        * it does not support it. */
1650*6236dae4SAndroid Build Coastguard Worker       EVP_PKEY *priv_key = SSL_get_privatekey(ssl);
1651*6236dae4SAndroid Build Coastguard Worker       int pktype;
1652*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPAQUE_EVP_PKEY
1653*6236dae4SAndroid Build Coastguard Worker       pktype = EVP_PKEY_id(priv_key);
1654*6236dae4SAndroid Build Coastguard Worker #else
1655*6236dae4SAndroid Build Coastguard Worker       pktype = priv_key->type;
1656*6236dae4SAndroid Build Coastguard Worker #endif
1657*6236dae4SAndroid Build Coastguard Worker       if(pktype == EVP_PKEY_RSA) {
1658*6236dae4SAndroid Build Coastguard Worker         RSA *rsa = EVP_PKEY_get1_RSA(priv_key);
1659*6236dae4SAndroid Build Coastguard Worker         if(RSA_flags(rsa) & RSA_METHOD_FLAG_NO_CHECK)
1660*6236dae4SAndroid Build Coastguard Worker           check_privkey = FALSE;
1661*6236dae4SAndroid Build Coastguard Worker         RSA_free(rsa); /* Decrement reference count */
1662*6236dae4SAndroid Build Coastguard Worker       }
1663*6236dae4SAndroid Build Coastguard Worker     }
1664*6236dae4SAndroid Build Coastguard Worker #endif
1665*6236dae4SAndroid Build Coastguard Worker 
1666*6236dae4SAndroid Build Coastguard Worker     SSL_free(ssl);
1667*6236dae4SAndroid Build Coastguard Worker 
1668*6236dae4SAndroid Build Coastguard Worker     /* If we are using DSA, we can copy the parameters from
1669*6236dae4SAndroid Build Coastguard Worker      * the private key */
1670*6236dae4SAndroid Build Coastguard Worker 
1671*6236dae4SAndroid Build Coastguard Worker     if(check_privkey == TRUE) {
1672*6236dae4SAndroid Build Coastguard Worker       /* Now we know that a key and cert have been set against
1673*6236dae4SAndroid Build Coastguard Worker        * the SSL context */
1674*6236dae4SAndroid Build Coastguard Worker       if(!SSL_CTX_check_private_key(ctx)) {
1675*6236dae4SAndroid Build Coastguard Worker         failf(data, "Private key does not match the certificate public key");
1676*6236dae4SAndroid Build Coastguard Worker         return 0;
1677*6236dae4SAndroid Build Coastguard Worker       }
1678*6236dae4SAndroid Build Coastguard Worker     }
1679*6236dae4SAndroid Build Coastguard Worker   }
1680*6236dae4SAndroid Build Coastguard Worker   return 1;
1681*6236dae4SAndroid Build Coastguard Worker }
1682*6236dae4SAndroid Build Coastguard Worker 
1683*6236dae4SAndroid Build Coastguard Worker /* returns non-zero on failure */
x509_name_oneline(X509_NAME * a,struct dynbuf * d)1684*6236dae4SAndroid Build Coastguard Worker static CURLcode x509_name_oneline(X509_NAME *a, struct dynbuf *d)
1685*6236dae4SAndroid Build Coastguard Worker {
1686*6236dae4SAndroid Build Coastguard Worker   BIO *bio_out = BIO_new(BIO_s_mem());
1687*6236dae4SAndroid Build Coastguard Worker   BUF_MEM *biomem;
1688*6236dae4SAndroid Build Coastguard Worker   int rc;
1689*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OUT_OF_MEMORY;
1690*6236dae4SAndroid Build Coastguard Worker 
1691*6236dae4SAndroid Build Coastguard Worker   if(bio_out) {
1692*6236dae4SAndroid Build Coastguard Worker     Curl_dyn_reset(d);
1693*6236dae4SAndroid Build Coastguard Worker     rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
1694*6236dae4SAndroid Build Coastguard Worker     if(rc != -1) {
1695*6236dae4SAndroid Build Coastguard Worker       BIO_get_mem_ptr(bio_out, &biomem);
1696*6236dae4SAndroid Build Coastguard Worker       result = Curl_dyn_addn(d, biomem->data, biomem->length);
1697*6236dae4SAndroid Build Coastguard Worker       BIO_free(bio_out);
1698*6236dae4SAndroid Build Coastguard Worker     }
1699*6236dae4SAndroid Build Coastguard Worker   }
1700*6236dae4SAndroid Build Coastguard Worker   return result;
1701*6236dae4SAndroid Build Coastguard Worker }
1702*6236dae4SAndroid Build Coastguard Worker 
1703*6236dae4SAndroid Build Coastguard Worker /**
1704*6236dae4SAndroid Build Coastguard Worker  * Global SSL init
1705*6236dae4SAndroid Build Coastguard Worker  *
1706*6236dae4SAndroid Build Coastguard Worker  * @retval 0 error initializing SSL
1707*6236dae4SAndroid Build Coastguard Worker  * @retval 1 SSL initialized successfully
1708*6236dae4SAndroid Build Coastguard Worker  */
ossl_init(void)1709*6236dae4SAndroid Build Coastguard Worker static int ossl_init(void)
1710*6236dae4SAndroid Build Coastguard Worker {
1711*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) &&  \
1712*6236dae4SAndroid Build Coastguard Worker   (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
1713*6236dae4SAndroid Build Coastguard Worker   const uint64_t flags =
1714*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN
1715*6236dae4SAndroid Build Coastguard Worker     /* not present in BoringSSL */
1716*6236dae4SAndroid Build Coastguard Worker     OPENSSL_INIT_ENGINE_ALL_BUILTIN |
1717*6236dae4SAndroid Build Coastguard Worker #endif
1718*6236dae4SAndroid Build Coastguard Worker #ifdef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
1719*6236dae4SAndroid Build Coastguard Worker     OPENSSL_INIT_NO_LOAD_CONFIG |
1720*6236dae4SAndroid Build Coastguard Worker #else
1721*6236dae4SAndroid Build Coastguard Worker     OPENSSL_INIT_LOAD_CONFIG |
1722*6236dae4SAndroid Build Coastguard Worker #endif
1723*6236dae4SAndroid Build Coastguard Worker     0;
1724*6236dae4SAndroid Build Coastguard Worker   OPENSSL_init_ssl(flags, NULL);
1725*6236dae4SAndroid Build Coastguard Worker #else
1726*6236dae4SAndroid Build Coastguard Worker   OPENSSL_load_builtin_modules();
1727*6236dae4SAndroid Build Coastguard Worker 
1728*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1729*6236dae4SAndroid Build Coastguard Worker   ENGINE_load_builtin_engines();
1730*6236dae4SAndroid Build Coastguard Worker #endif
1731*6236dae4SAndroid Build Coastguard Worker 
1732*6236dae4SAndroid Build Coastguard Worker /* CONF_MFLAGS_DEFAULT_SECTION was introduced some time between 0.9.8b and
1733*6236dae4SAndroid Build Coastguard Worker    0.9.8e */
1734*6236dae4SAndroid Build Coastguard Worker #ifndef CONF_MFLAGS_DEFAULT_SECTION
1735*6236dae4SAndroid Build Coastguard Worker #define CONF_MFLAGS_DEFAULT_SECTION 0x0
1736*6236dae4SAndroid Build Coastguard Worker #endif
1737*6236dae4SAndroid Build Coastguard Worker 
1738*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
1739*6236dae4SAndroid Build Coastguard Worker   CONF_modules_load_file(NULL, NULL,
1740*6236dae4SAndroid Build Coastguard Worker                          CONF_MFLAGS_DEFAULT_SECTION|
1741*6236dae4SAndroid Build Coastguard Worker                          CONF_MFLAGS_IGNORE_MISSING_FILE);
1742*6236dae4SAndroid Build Coastguard Worker #endif
1743*6236dae4SAndroid Build Coastguard Worker 
1744*6236dae4SAndroid Build Coastguard Worker   /* Let's get nice error messages */
1745*6236dae4SAndroid Build Coastguard Worker   SSL_load_error_strings();
1746*6236dae4SAndroid Build Coastguard Worker 
1747*6236dae4SAndroid Build Coastguard Worker   /* Init the global ciphers and digests */
1748*6236dae4SAndroid Build Coastguard Worker   if(!SSLeay_add_ssl_algorithms())
1749*6236dae4SAndroid Build Coastguard Worker     return 0;
1750*6236dae4SAndroid Build Coastguard Worker 
1751*6236dae4SAndroid Build Coastguard Worker   OpenSSL_add_all_algorithms();
1752*6236dae4SAndroid Build Coastguard Worker #endif
1753*6236dae4SAndroid Build Coastguard Worker 
1754*6236dae4SAndroid Build Coastguard Worker   Curl_tls_keylog_open();
1755*6236dae4SAndroid Build Coastguard Worker 
1756*6236dae4SAndroid Build Coastguard Worker   return 1;
1757*6236dae4SAndroid Build Coastguard Worker }
1758*6236dae4SAndroid Build Coastguard Worker 
1759*6236dae4SAndroid Build Coastguard Worker /* Global cleanup */
ossl_cleanup(void)1760*6236dae4SAndroid Build Coastguard Worker static void ossl_cleanup(void)
1761*6236dae4SAndroid Build Coastguard Worker {
1762*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) &&  \
1763*6236dae4SAndroid Build Coastguard Worker   (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
1764*6236dae4SAndroid Build Coastguard Worker   /* OpenSSL 1.1 deprecates all these cleanup functions and
1765*6236dae4SAndroid Build Coastguard Worker      turns them into no-ops in OpenSSL 1.0 compatibility mode */
1766*6236dae4SAndroid Build Coastguard Worker #else
1767*6236dae4SAndroid Build Coastguard Worker   /* Free ciphers and digests lists */
1768*6236dae4SAndroid Build Coastguard Worker   EVP_cleanup();
1769*6236dae4SAndroid Build Coastguard Worker 
1770*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1771*6236dae4SAndroid Build Coastguard Worker   /* Free engine list */
1772*6236dae4SAndroid Build Coastguard Worker   ENGINE_cleanup();
1773*6236dae4SAndroid Build Coastguard Worker #endif
1774*6236dae4SAndroid Build Coastguard Worker 
1775*6236dae4SAndroid Build Coastguard Worker   /* Free OpenSSL error strings */
1776*6236dae4SAndroid Build Coastguard Worker   ERR_free_strings();
1777*6236dae4SAndroid Build Coastguard Worker 
1778*6236dae4SAndroid Build Coastguard Worker   /* Free thread local error state, destroying hash upon zero refcount */
1779*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_ERR_REMOVE_THREAD_STATE
1780*6236dae4SAndroid Build Coastguard Worker   ERR_remove_thread_state(NULL);
1781*6236dae4SAndroid Build Coastguard Worker #else
1782*6236dae4SAndroid Build Coastguard Worker   ERR_remove_state(0);
1783*6236dae4SAndroid Build Coastguard Worker #endif
1784*6236dae4SAndroid Build Coastguard Worker 
1785*6236dae4SAndroid Build Coastguard Worker   /* Free all memory allocated by all configuration modules */
1786*6236dae4SAndroid Build Coastguard Worker   CONF_modules_free();
1787*6236dae4SAndroid Build Coastguard Worker 
1788*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS
1789*6236dae4SAndroid Build Coastguard Worker   SSL_COMP_free_compression_methods();
1790*6236dae4SAndroid Build Coastguard Worker #endif
1791*6236dae4SAndroid Build Coastguard Worker #endif
1792*6236dae4SAndroid Build Coastguard Worker 
1793*6236dae4SAndroid Build Coastguard Worker   Curl_tls_keylog_close();
1794*6236dae4SAndroid Build Coastguard Worker }
1795*6236dae4SAndroid Build Coastguard Worker 
1796*6236dae4SAndroid Build Coastguard Worker /* Selects an OpenSSL crypto engine
1797*6236dae4SAndroid Build Coastguard Worker  */
ossl_set_engine(struct Curl_easy * data,const char * engine)1798*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_set_engine(struct Curl_easy *data, const char *engine)
1799*6236dae4SAndroid Build Coastguard Worker {
1800*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1801*6236dae4SAndroid Build Coastguard Worker   ENGINE *e;
1802*6236dae4SAndroid Build Coastguard Worker 
1803*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x00909000L
1804*6236dae4SAndroid Build Coastguard Worker   e = ENGINE_by_id(engine);
1805*6236dae4SAndroid Build Coastguard Worker #else
1806*6236dae4SAndroid Build Coastguard Worker   /* avoid memory leak */
1807*6236dae4SAndroid Build Coastguard Worker   for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
1808*6236dae4SAndroid Build Coastguard Worker     const char *e_id = ENGINE_get_id(e);
1809*6236dae4SAndroid Build Coastguard Worker     if(!strcmp(engine, e_id))
1810*6236dae4SAndroid Build Coastguard Worker       break;
1811*6236dae4SAndroid Build Coastguard Worker   }
1812*6236dae4SAndroid Build Coastguard Worker #endif
1813*6236dae4SAndroid Build Coastguard Worker 
1814*6236dae4SAndroid Build Coastguard Worker   if(!e) {
1815*6236dae4SAndroid Build Coastguard Worker     failf(data, "SSL Engine '%s' not found", engine);
1816*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_ENGINE_NOTFOUND;
1817*6236dae4SAndroid Build Coastguard Worker   }
1818*6236dae4SAndroid Build Coastguard Worker 
1819*6236dae4SAndroid Build Coastguard Worker   if(data->state.engine) {
1820*6236dae4SAndroid Build Coastguard Worker     ENGINE_finish(data->state.engine);
1821*6236dae4SAndroid Build Coastguard Worker     ENGINE_free(data->state.engine);
1822*6236dae4SAndroid Build Coastguard Worker     data->state.engine = NULL;
1823*6236dae4SAndroid Build Coastguard Worker   }
1824*6236dae4SAndroid Build Coastguard Worker   if(!ENGINE_init(e)) {
1825*6236dae4SAndroid Build Coastguard Worker     char buf[256];
1826*6236dae4SAndroid Build Coastguard Worker 
1827*6236dae4SAndroid Build Coastguard Worker     ENGINE_free(e);
1828*6236dae4SAndroid Build Coastguard Worker     failf(data, "Failed to initialise SSL Engine '%s': %s",
1829*6236dae4SAndroid Build Coastguard Worker           engine, ossl_strerror(ERR_get_error(), buf, sizeof(buf)));
1830*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_ENGINE_INITFAILED;
1831*6236dae4SAndroid Build Coastguard Worker   }
1832*6236dae4SAndroid Build Coastguard Worker   data->state.engine = e;
1833*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
1834*6236dae4SAndroid Build Coastguard Worker #else
1835*6236dae4SAndroid Build Coastguard Worker   (void)engine;
1836*6236dae4SAndroid Build Coastguard Worker   failf(data, "SSL Engine not supported");
1837*6236dae4SAndroid Build Coastguard Worker   return CURLE_SSL_ENGINE_NOTFOUND;
1838*6236dae4SAndroid Build Coastguard Worker #endif
1839*6236dae4SAndroid Build Coastguard Worker }
1840*6236dae4SAndroid Build Coastguard Worker 
1841*6236dae4SAndroid Build Coastguard Worker /* Sets engine as default for all SSL operations
1842*6236dae4SAndroid Build Coastguard Worker  */
ossl_set_engine_default(struct Curl_easy * data)1843*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_set_engine_default(struct Curl_easy *data)
1844*6236dae4SAndroid Build Coastguard Worker {
1845*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1846*6236dae4SAndroid Build Coastguard Worker   if(data->state.engine) {
1847*6236dae4SAndroid Build Coastguard Worker     if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
1848*6236dae4SAndroid Build Coastguard Worker       infof(data, "set default crypto engine '%s'",
1849*6236dae4SAndroid Build Coastguard Worker             ENGINE_get_id(data->state.engine));
1850*6236dae4SAndroid Build Coastguard Worker     }
1851*6236dae4SAndroid Build Coastguard Worker     else {
1852*6236dae4SAndroid Build Coastguard Worker       failf(data, "set default crypto engine '%s' failed",
1853*6236dae4SAndroid Build Coastguard Worker             ENGINE_get_id(data->state.engine));
1854*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_ENGINE_SETFAILED;
1855*6236dae4SAndroid Build Coastguard Worker     }
1856*6236dae4SAndroid Build Coastguard Worker   }
1857*6236dae4SAndroid Build Coastguard Worker #else
1858*6236dae4SAndroid Build Coastguard Worker   (void) data;
1859*6236dae4SAndroid Build Coastguard Worker #endif
1860*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
1861*6236dae4SAndroid Build Coastguard Worker }
1862*6236dae4SAndroid Build Coastguard Worker 
1863*6236dae4SAndroid Build Coastguard Worker /* Return list of OpenSSL crypto engine names.
1864*6236dae4SAndroid Build Coastguard Worker  */
ossl_engines_list(struct Curl_easy * data)1865*6236dae4SAndroid Build Coastguard Worker static struct curl_slist *ossl_engines_list(struct Curl_easy *data)
1866*6236dae4SAndroid Build Coastguard Worker {
1867*6236dae4SAndroid Build Coastguard Worker   struct curl_slist *list = NULL;
1868*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
1869*6236dae4SAndroid Build Coastguard Worker   struct curl_slist *beg;
1870*6236dae4SAndroid Build Coastguard Worker   ENGINE *e;
1871*6236dae4SAndroid Build Coastguard Worker 
1872*6236dae4SAndroid Build Coastguard Worker   for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
1873*6236dae4SAndroid Build Coastguard Worker     beg = curl_slist_append(list, ENGINE_get_id(e));
1874*6236dae4SAndroid Build Coastguard Worker     if(!beg) {
1875*6236dae4SAndroid Build Coastguard Worker       curl_slist_free_all(list);
1876*6236dae4SAndroid Build Coastguard Worker       return NULL;
1877*6236dae4SAndroid Build Coastguard Worker     }
1878*6236dae4SAndroid Build Coastguard Worker     list = beg;
1879*6236dae4SAndroid Build Coastguard Worker   }
1880*6236dae4SAndroid Build Coastguard Worker #endif
1881*6236dae4SAndroid Build Coastguard Worker   (void) data;
1882*6236dae4SAndroid Build Coastguard Worker   return list;
1883*6236dae4SAndroid Build Coastguard Worker }
1884*6236dae4SAndroid Build Coastguard Worker 
ossl_shutdown(struct Curl_cfilter * cf,struct Curl_easy * data,bool send_shutdown,bool * done)1885*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_shutdown(struct Curl_cfilter *cf,
1886*6236dae4SAndroid Build Coastguard Worker                               struct Curl_easy *data,
1887*6236dae4SAndroid Build Coastguard Worker                               bool send_shutdown, bool *done)
1888*6236dae4SAndroid Build Coastguard Worker {
1889*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
1890*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
1891*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
1892*6236dae4SAndroid Build Coastguard Worker   char buf[1024];
1893*6236dae4SAndroid Build Coastguard Worker   int nread = -1, err;
1894*6236dae4SAndroid Build Coastguard Worker   unsigned long sslerr;
1895*6236dae4SAndroid Build Coastguard Worker   size_t i;
1896*6236dae4SAndroid Build Coastguard Worker 
1897*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
1898*6236dae4SAndroid Build Coastguard Worker   if(!octx->ssl || cf->shutdown) {
1899*6236dae4SAndroid Build Coastguard Worker     *done = TRUE;
1900*6236dae4SAndroid Build Coastguard Worker     goto out;
1901*6236dae4SAndroid Build Coastguard Worker   }
1902*6236dae4SAndroid Build Coastguard Worker 
1903*6236dae4SAndroid Build Coastguard Worker   connssl->io_need = CURL_SSL_IO_NEED_NONE;
1904*6236dae4SAndroid Build Coastguard Worker   *done = FALSE;
1905*6236dae4SAndroid Build Coastguard Worker   if(!(SSL_get_shutdown(octx->ssl) & SSL_SENT_SHUTDOWN)) {
1906*6236dae4SAndroid Build Coastguard Worker     /* We have not started the shutdown from our side yet. Check
1907*6236dae4SAndroid Build Coastguard Worker      * if the server already sent us one. */
1908*6236dae4SAndroid Build Coastguard Worker     ERR_clear_error();
1909*6236dae4SAndroid Build Coastguard Worker     for(i = 0; i < 10; ++i) {
1910*6236dae4SAndroid Build Coastguard Worker       nread = SSL_read(octx->ssl, buf, (int)sizeof(buf));
1911*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL shutdown not sent, read -> %d", nread);
1912*6236dae4SAndroid Build Coastguard Worker       if(nread <= 0)
1913*6236dae4SAndroid Build Coastguard Worker         break;
1914*6236dae4SAndroid Build Coastguard Worker     }
1915*6236dae4SAndroid Build Coastguard Worker     err = SSL_get_error(octx->ssl, nread);
1916*6236dae4SAndroid Build Coastguard Worker     if(!nread && err == SSL_ERROR_ZERO_RETURN) {
1917*6236dae4SAndroid Build Coastguard Worker       bool input_pending;
1918*6236dae4SAndroid Build Coastguard Worker       /* Yes, it did. */
1919*6236dae4SAndroid Build Coastguard Worker       if(!send_shutdown) {
1920*6236dae4SAndroid Build Coastguard Worker         CURL_TRC_CF(data, cf, "SSL shutdown received, not sending");
1921*6236dae4SAndroid Build Coastguard Worker         *done = TRUE;
1922*6236dae4SAndroid Build Coastguard Worker         goto out;
1923*6236dae4SAndroid Build Coastguard Worker       }
1924*6236dae4SAndroid Build Coastguard Worker       else if(!cf->next->cft->is_alive(cf->next, data, &input_pending)) {
1925*6236dae4SAndroid Build Coastguard Worker         /* Server closed the connection after its closy notify. It
1926*6236dae4SAndroid Build Coastguard Worker          * seems not interested to see our close notify, so do not
1927*6236dae4SAndroid Build Coastguard Worker          * send it. We are done. */
1928*6236dae4SAndroid Build Coastguard Worker         connssl->peer_closed = TRUE;
1929*6236dae4SAndroid Build Coastguard Worker         CURL_TRC_CF(data, cf, "peer closed connection");
1930*6236dae4SAndroid Build Coastguard Worker         *done = TRUE;
1931*6236dae4SAndroid Build Coastguard Worker         goto out;
1932*6236dae4SAndroid Build Coastguard Worker       }
1933*6236dae4SAndroid Build Coastguard Worker     }
1934*6236dae4SAndroid Build Coastguard Worker   }
1935*6236dae4SAndroid Build Coastguard Worker 
1936*6236dae4SAndroid Build Coastguard Worker   /* SSL should now have started the shutdown from our side. Since it
1937*6236dae4SAndroid Build Coastguard Worker    * was not complete, we are lacking the close notify from the server. */
1938*6236dae4SAndroid Build Coastguard Worker   if(send_shutdown && !(SSL_get_shutdown(octx->ssl) & SSL_SENT_SHUTDOWN)) {
1939*6236dae4SAndroid Build Coastguard Worker     ERR_clear_error();
1940*6236dae4SAndroid Build Coastguard Worker     CURL_TRC_CF(data, cf, "send SSL close notify");
1941*6236dae4SAndroid Build Coastguard Worker     if(SSL_shutdown(octx->ssl) == 1) {
1942*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL shutdown finished");
1943*6236dae4SAndroid Build Coastguard Worker       *done = TRUE;
1944*6236dae4SAndroid Build Coastguard Worker       goto out;
1945*6236dae4SAndroid Build Coastguard Worker     }
1946*6236dae4SAndroid Build Coastguard Worker     if(SSL_ERROR_WANT_WRITE == SSL_get_error(octx->ssl, nread)) {
1947*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL shutdown still wants to send");
1948*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_SEND;
1949*6236dae4SAndroid Build Coastguard Worker       goto out;
1950*6236dae4SAndroid Build Coastguard Worker     }
1951*6236dae4SAndroid Build Coastguard Worker     /* Having sent the close notify, we use SSL_read() to get the
1952*6236dae4SAndroid Build Coastguard Worker      * missing close notify from the server. */
1953*6236dae4SAndroid Build Coastguard Worker   }
1954*6236dae4SAndroid Build Coastguard Worker 
1955*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < 10; ++i) {
1956*6236dae4SAndroid Build Coastguard Worker     ERR_clear_error();
1957*6236dae4SAndroid Build Coastguard Worker     nread = SSL_read(octx->ssl, buf, (int)sizeof(buf));
1958*6236dae4SAndroid Build Coastguard Worker     CURL_TRC_CF(data, cf, "SSL shutdown read -> %d", nread);
1959*6236dae4SAndroid Build Coastguard Worker     if(nread <= 0)
1960*6236dae4SAndroid Build Coastguard Worker       break;
1961*6236dae4SAndroid Build Coastguard Worker   }
1962*6236dae4SAndroid Build Coastguard Worker   err = SSL_get_error(octx->ssl, nread);
1963*6236dae4SAndroid Build Coastguard Worker   switch(err) {
1964*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_ZERO_RETURN: /* no more data */
1965*6236dae4SAndroid Build Coastguard Worker     if(SSL_shutdown(octx->ssl) == 1)
1966*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL shutdown finished");
1967*6236dae4SAndroid Build Coastguard Worker     else
1968*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL shutdown not received, but closed");
1969*6236dae4SAndroid Build Coastguard Worker     *done = TRUE;
1970*6236dae4SAndroid Build Coastguard Worker     break;
1971*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_NONE: /* just did not get anything */
1972*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_READ:
1973*6236dae4SAndroid Build Coastguard Worker     /* SSL has send its notify and now wants to read the reply
1974*6236dae4SAndroid Build Coastguard Worker      * from the server. We are not really interested in that. */
1975*6236dae4SAndroid Build Coastguard Worker     CURL_TRC_CF(data, cf, "SSL shutdown sent, want receive");
1976*6236dae4SAndroid Build Coastguard Worker     connssl->io_need = CURL_SSL_IO_NEED_RECV;
1977*6236dae4SAndroid Build Coastguard Worker     break;
1978*6236dae4SAndroid Build Coastguard Worker   case SSL_ERROR_WANT_WRITE:
1979*6236dae4SAndroid Build Coastguard Worker     CURL_TRC_CF(data, cf, "SSL shutdown send blocked");
1980*6236dae4SAndroid Build Coastguard Worker     connssl->io_need = CURL_SSL_IO_NEED_SEND;
1981*6236dae4SAndroid Build Coastguard Worker     break;
1982*6236dae4SAndroid Build Coastguard Worker   default:
1983*6236dae4SAndroid Build Coastguard Worker     /* Server seems to have closed the connection without sending us
1984*6236dae4SAndroid Build Coastguard Worker      * a close notify. */
1985*6236dae4SAndroid Build Coastguard Worker     sslerr = ERR_get_error();
1986*6236dae4SAndroid Build Coastguard Worker     CURL_TRC_CF(data, cf, "SSL shutdown, ignore recv error: '%s', errno %d",
1987*6236dae4SAndroid Build Coastguard Worker                 (sslerr ?
1988*6236dae4SAndroid Build Coastguard Worker                  ossl_strerror(sslerr, buf, sizeof(buf)) :
1989*6236dae4SAndroid Build Coastguard Worker                  SSL_ERROR_to_str(err)),
1990*6236dae4SAndroid Build Coastguard Worker                 SOCKERRNO);
1991*6236dae4SAndroid Build Coastguard Worker     *done = TRUE;
1992*6236dae4SAndroid Build Coastguard Worker     result = CURLE_OK;
1993*6236dae4SAndroid Build Coastguard Worker     break;
1994*6236dae4SAndroid Build Coastguard Worker   }
1995*6236dae4SAndroid Build Coastguard Worker 
1996*6236dae4SAndroid Build Coastguard Worker out:
1997*6236dae4SAndroid Build Coastguard Worker   cf->shutdown = (result || *done);
1998*6236dae4SAndroid Build Coastguard Worker   return result;
1999*6236dae4SAndroid Build Coastguard Worker }
2000*6236dae4SAndroid Build Coastguard Worker 
ossl_close(struct Curl_cfilter * cf,struct Curl_easy * data)2001*6236dae4SAndroid Build Coastguard Worker static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
2002*6236dae4SAndroid Build Coastguard Worker {
2003*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
2004*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
2005*6236dae4SAndroid Build Coastguard Worker 
2006*6236dae4SAndroid Build Coastguard Worker   (void)data;
2007*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
2008*6236dae4SAndroid Build Coastguard Worker 
2009*6236dae4SAndroid Build Coastguard Worker   if(octx->ssl) {
2010*6236dae4SAndroid Build Coastguard Worker     SSL_free(octx->ssl);
2011*6236dae4SAndroid Build Coastguard Worker     octx->ssl = NULL;
2012*6236dae4SAndroid Build Coastguard Worker   }
2013*6236dae4SAndroid Build Coastguard Worker   if(octx->ssl_ctx) {
2014*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_free(octx->ssl_ctx);
2015*6236dae4SAndroid Build Coastguard Worker     octx->ssl_ctx = NULL;
2016*6236dae4SAndroid Build Coastguard Worker     octx->x509_store_setup = FALSE;
2017*6236dae4SAndroid Build Coastguard Worker   }
2018*6236dae4SAndroid Build Coastguard Worker   if(octx->bio_method) {
2019*6236dae4SAndroid Build Coastguard Worker     ossl_bio_cf_method_free(octx->bio_method);
2020*6236dae4SAndroid Build Coastguard Worker     octx->bio_method = NULL;
2021*6236dae4SAndroid Build Coastguard Worker   }
2022*6236dae4SAndroid Build Coastguard Worker }
2023*6236dae4SAndroid Build Coastguard Worker 
ossl_session_free(void * sessionid,size_t idsize)2024*6236dae4SAndroid Build Coastguard Worker static void ossl_session_free(void *sessionid, size_t idsize)
2025*6236dae4SAndroid Build Coastguard Worker {
2026*6236dae4SAndroid Build Coastguard Worker   /* free the ID */
2027*6236dae4SAndroid Build Coastguard Worker   (void)idsize;
2028*6236dae4SAndroid Build Coastguard Worker   free(sessionid);
2029*6236dae4SAndroid Build Coastguard Worker }
2030*6236dae4SAndroid Build Coastguard Worker 
2031*6236dae4SAndroid Build Coastguard Worker /*
2032*6236dae4SAndroid Build Coastguard Worker  * This function is called when the 'data' struct is going away. Close
2033*6236dae4SAndroid Build Coastguard Worker  * down everything and free all resources!
2034*6236dae4SAndroid Build Coastguard Worker  */
ossl_close_all(struct Curl_easy * data)2035*6236dae4SAndroid Build Coastguard Worker static void ossl_close_all(struct Curl_easy *data)
2036*6236dae4SAndroid Build Coastguard Worker {
2037*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_ENGINE
2038*6236dae4SAndroid Build Coastguard Worker   if(data->state.engine) {
2039*6236dae4SAndroid Build Coastguard Worker     ENGINE_finish(data->state.engine);
2040*6236dae4SAndroid Build Coastguard Worker     ENGINE_free(data->state.engine);
2041*6236dae4SAndroid Build Coastguard Worker     data->state.engine = NULL;
2042*6236dae4SAndroid Build Coastguard Worker   }
2043*6236dae4SAndroid Build Coastguard Worker #else
2044*6236dae4SAndroid Build Coastguard Worker   (void)data;
2045*6236dae4SAndroid Build Coastguard Worker #endif
2046*6236dae4SAndroid Build Coastguard Worker #if !defined(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED) &&        \
2047*6236dae4SAndroid Build Coastguard Worker   defined(HAVE_ERR_REMOVE_THREAD_STATE)
2048*6236dae4SAndroid Build Coastguard Worker   /* OpenSSL 1.0.1 and 1.0.2 build an error queue that is stored per-thread
2049*6236dae4SAndroid Build Coastguard Worker      so we need to clean it here in case the thread will be killed. All OpenSSL
2050*6236dae4SAndroid Build Coastguard Worker      code should extract the error in association with the error so clearing
2051*6236dae4SAndroid Build Coastguard Worker      this queue here should be harmless at worst. */
2052*6236dae4SAndroid Build Coastguard Worker   ERR_remove_thread_state(NULL);
2053*6236dae4SAndroid Build Coastguard Worker #endif
2054*6236dae4SAndroid Build Coastguard Worker }
2055*6236dae4SAndroid Build Coastguard Worker 
2056*6236dae4SAndroid Build Coastguard Worker /* ====================================================== */
2057*6236dae4SAndroid Build Coastguard Worker 
2058*6236dae4SAndroid Build Coastguard Worker /*
2059*6236dae4SAndroid Build Coastguard Worker  * Match subjectAltName against the hostname.
2060*6236dae4SAndroid Build Coastguard Worker  */
subj_alt_hostcheck(struct Curl_easy * data,const char * match_pattern,size_t matchlen,const char * hostname,size_t hostlen,const char * dispname)2061*6236dae4SAndroid Build Coastguard Worker static bool subj_alt_hostcheck(struct Curl_easy *data,
2062*6236dae4SAndroid Build Coastguard Worker                                const char *match_pattern,
2063*6236dae4SAndroid Build Coastguard Worker                                size_t matchlen,
2064*6236dae4SAndroid Build Coastguard Worker                                const char *hostname,
2065*6236dae4SAndroid Build Coastguard Worker                                size_t hostlen,
2066*6236dae4SAndroid Build Coastguard Worker                                const char *dispname)
2067*6236dae4SAndroid Build Coastguard Worker {
2068*6236dae4SAndroid Build Coastguard Worker #ifdef CURL_DISABLE_VERBOSE_STRINGS
2069*6236dae4SAndroid Build Coastguard Worker   (void)dispname;
2070*6236dae4SAndroid Build Coastguard Worker   (void)data;
2071*6236dae4SAndroid Build Coastguard Worker #endif
2072*6236dae4SAndroid Build Coastguard Worker   if(Curl_cert_hostcheck(match_pattern, matchlen, hostname, hostlen)) {
2073*6236dae4SAndroid Build Coastguard Worker     infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"",
2074*6236dae4SAndroid Build Coastguard Worker           dispname, match_pattern);
2075*6236dae4SAndroid Build Coastguard Worker     return TRUE;
2076*6236dae4SAndroid Build Coastguard Worker   }
2077*6236dae4SAndroid Build Coastguard Worker   return FALSE;
2078*6236dae4SAndroid Build Coastguard Worker }
2079*6236dae4SAndroid Build Coastguard Worker 
2080*6236dae4SAndroid Build Coastguard Worker /* Quote from RFC2818 section 3.1 "Server Identity"
2081*6236dae4SAndroid Build Coastguard Worker 
2082*6236dae4SAndroid Build Coastguard Worker    If a subjectAltName extension of type dNSName is present, that MUST
2083*6236dae4SAndroid Build Coastguard Worker    be used as the identity. Otherwise, the (most specific) Common Name
2084*6236dae4SAndroid Build Coastguard Worker    field in the Subject field of the certificate MUST be used. Although
2085*6236dae4SAndroid Build Coastguard Worker    the use of the Common Name is existing practice, it is deprecated and
2086*6236dae4SAndroid Build Coastguard Worker    Certification Authorities are encouraged to use the dNSName instead.
2087*6236dae4SAndroid Build Coastguard Worker 
2088*6236dae4SAndroid Build Coastguard Worker    Matching is performed using the matching rules specified by
2089*6236dae4SAndroid Build Coastguard Worker    [RFC2459]. If more than one identity of a given type is present in
2090*6236dae4SAndroid Build Coastguard Worker    the certificate (e.g., more than one dNSName name, a match in any one
2091*6236dae4SAndroid Build Coastguard Worker    of the set is considered acceptable.) Names may contain the wildcard
2092*6236dae4SAndroid Build Coastguard Worker    character * which is considered to match any single domain name
2093*6236dae4SAndroid Build Coastguard Worker    component or component fragment. E.g., *.a.com matches foo.a.com but
2094*6236dae4SAndroid Build Coastguard Worker    not bar.foo.a.com. f*.com matches foo.com but not bar.com.
2095*6236dae4SAndroid Build Coastguard Worker 
2096*6236dae4SAndroid Build Coastguard Worker    In some cases, the URI is specified as an IP address rather than a
2097*6236dae4SAndroid Build Coastguard Worker    hostname. In this case, the iPAddress subjectAltName must be present
2098*6236dae4SAndroid Build Coastguard Worker    in the certificate and must exactly match the IP in the URI.
2099*6236dae4SAndroid Build Coastguard Worker 
2100*6236dae4SAndroid Build Coastguard Worker    This function is now used from ngtcp2 (QUIC) as well.
2101*6236dae4SAndroid Build Coastguard Worker */
ossl_verifyhost(struct Curl_easy * data,struct connectdata * conn,struct ssl_peer * peer,X509 * server_cert)2102*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_verifyhost(struct Curl_easy *data,
2103*6236dae4SAndroid Build Coastguard Worker                                 struct connectdata *conn,
2104*6236dae4SAndroid Build Coastguard Worker                                 struct ssl_peer *peer, X509 *server_cert)
2105*6236dae4SAndroid Build Coastguard Worker {
2106*6236dae4SAndroid Build Coastguard Worker   bool matched = FALSE;
2107*6236dae4SAndroid Build Coastguard Worker   int target; /* target type, GEN_DNS or GEN_IPADD */
2108*6236dae4SAndroid Build Coastguard Worker   size_t addrlen = 0;
2109*6236dae4SAndroid Build Coastguard Worker   STACK_OF(GENERAL_NAME) *altnames;
2110*6236dae4SAndroid Build Coastguard Worker #ifdef USE_IPV6
2111*6236dae4SAndroid Build Coastguard Worker   struct in6_addr addr;
2112*6236dae4SAndroid Build Coastguard Worker #else
2113*6236dae4SAndroid Build Coastguard Worker   struct in_addr addr;
2114*6236dae4SAndroid Build Coastguard Worker #endif
2115*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
2116*6236dae4SAndroid Build Coastguard Worker   bool dNSName = FALSE; /* if a dNSName field exists in the cert */
2117*6236dae4SAndroid Build Coastguard Worker   bool iPAddress = FALSE; /* if an iPAddress field exists in the cert */
2118*6236dae4SAndroid Build Coastguard Worker   size_t hostlen;
2119*6236dae4SAndroid Build Coastguard Worker 
2120*6236dae4SAndroid Build Coastguard Worker   (void)conn;
2121*6236dae4SAndroid Build Coastguard Worker   hostlen = strlen(peer->hostname);
2122*6236dae4SAndroid Build Coastguard Worker   switch(peer->type) {
2123*6236dae4SAndroid Build Coastguard Worker   case CURL_SSL_PEER_IPV4:
2124*6236dae4SAndroid Build Coastguard Worker     if(!Curl_inet_pton(AF_INET, peer->hostname, &addr))
2125*6236dae4SAndroid Build Coastguard Worker       return CURLE_PEER_FAILED_VERIFICATION;
2126*6236dae4SAndroid Build Coastguard Worker     target = GEN_IPADD;
2127*6236dae4SAndroid Build Coastguard Worker     addrlen = sizeof(struct in_addr);
2128*6236dae4SAndroid Build Coastguard Worker     break;
2129*6236dae4SAndroid Build Coastguard Worker #ifdef USE_IPV6
2130*6236dae4SAndroid Build Coastguard Worker   case CURL_SSL_PEER_IPV6:
2131*6236dae4SAndroid Build Coastguard Worker     if(!Curl_inet_pton(AF_INET6, peer->hostname, &addr))
2132*6236dae4SAndroid Build Coastguard Worker       return CURLE_PEER_FAILED_VERIFICATION;
2133*6236dae4SAndroid Build Coastguard Worker     target = GEN_IPADD;
2134*6236dae4SAndroid Build Coastguard Worker     addrlen = sizeof(struct in6_addr);
2135*6236dae4SAndroid Build Coastguard Worker     break;
2136*6236dae4SAndroid Build Coastguard Worker #endif
2137*6236dae4SAndroid Build Coastguard Worker   case CURL_SSL_PEER_DNS:
2138*6236dae4SAndroid Build Coastguard Worker     target = GEN_DNS;
2139*6236dae4SAndroid Build Coastguard Worker     break;
2140*6236dae4SAndroid Build Coastguard Worker   default:
2141*6236dae4SAndroid Build Coastguard Worker     DEBUGASSERT(0);
2142*6236dae4SAndroid Build Coastguard Worker     failf(data, "unexpected ssl peer type: %d", peer->type);
2143*6236dae4SAndroid Build Coastguard Worker     return CURLE_PEER_FAILED_VERIFICATION;
2144*6236dae4SAndroid Build Coastguard Worker   }
2145*6236dae4SAndroid Build Coastguard Worker 
2146*6236dae4SAndroid Build Coastguard Worker   /* get a "list" of alternative names */
2147*6236dae4SAndroid Build Coastguard Worker   altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
2148*6236dae4SAndroid Build Coastguard Worker 
2149*6236dae4SAndroid Build Coastguard Worker   if(altnames) {
2150*6236dae4SAndroid Build Coastguard Worker #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
2151*6236dae4SAndroid Build Coastguard Worker     size_t numalts;
2152*6236dae4SAndroid Build Coastguard Worker     size_t i;
2153*6236dae4SAndroid Build Coastguard Worker #else
2154*6236dae4SAndroid Build Coastguard Worker     int numalts;
2155*6236dae4SAndroid Build Coastguard Worker     int i;
2156*6236dae4SAndroid Build Coastguard Worker #endif
2157*6236dae4SAndroid Build Coastguard Worker     bool dnsmatched = FALSE;
2158*6236dae4SAndroid Build Coastguard Worker     bool ipmatched = FALSE;
2159*6236dae4SAndroid Build Coastguard Worker 
2160*6236dae4SAndroid Build Coastguard Worker     /* get amount of alternatives, RFC2459 claims there MUST be at least
2161*6236dae4SAndroid Build Coastguard Worker        one, but we do not depend on it... */
2162*6236dae4SAndroid Build Coastguard Worker     numalts = sk_GENERAL_NAME_num(altnames);
2163*6236dae4SAndroid Build Coastguard Worker 
2164*6236dae4SAndroid Build Coastguard Worker     /* loop through all alternatives - until a dnsmatch */
2165*6236dae4SAndroid Build Coastguard Worker     for(i = 0; (i < numalts) && !dnsmatched; i++) {
2166*6236dae4SAndroid Build Coastguard Worker       /* get a handle to alternative name number i */
2167*6236dae4SAndroid Build Coastguard Worker       const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
2168*6236dae4SAndroid Build Coastguard Worker 
2169*6236dae4SAndroid Build Coastguard Worker       if(check->type == GEN_DNS)
2170*6236dae4SAndroid Build Coastguard Worker         dNSName = TRUE;
2171*6236dae4SAndroid Build Coastguard Worker       else if(check->type == GEN_IPADD)
2172*6236dae4SAndroid Build Coastguard Worker         iPAddress = TRUE;
2173*6236dae4SAndroid Build Coastguard Worker 
2174*6236dae4SAndroid Build Coastguard Worker       /* only check alternatives of the same type the target is */
2175*6236dae4SAndroid Build Coastguard Worker       if(check->type == target) {
2176*6236dae4SAndroid Build Coastguard Worker         /* get data and length */
2177*6236dae4SAndroid Build Coastguard Worker         const char *altptr = (char *)ASN1_STRING_get0_data(check->d.ia5);
2178*6236dae4SAndroid Build Coastguard Worker         size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
2179*6236dae4SAndroid Build Coastguard Worker 
2180*6236dae4SAndroid Build Coastguard Worker         switch(target) {
2181*6236dae4SAndroid Build Coastguard Worker         case GEN_DNS: /* name/pattern comparison */
2182*6236dae4SAndroid Build Coastguard Worker           /* The OpenSSL manpage explicitly says: "In general it cannot be
2183*6236dae4SAndroid Build Coastguard Worker              assumed that the data returned by ASN1_STRING_data() is null
2184*6236dae4SAndroid Build Coastguard Worker              terminated or does not contain embedded nulls." But also that
2185*6236dae4SAndroid Build Coastguard Worker              "The actual format of the data will depend on the actual string
2186*6236dae4SAndroid Build Coastguard Worker              type itself: for example for an IA5String the data will be ASCII"
2187*6236dae4SAndroid Build Coastguard Worker 
2188*6236dae4SAndroid Build Coastguard Worker              It has been however verified that in 0.9.6 and 0.9.7, IA5String
2189*6236dae4SAndroid Build Coastguard Worker              is always null-terminated.
2190*6236dae4SAndroid Build Coastguard Worker           */
2191*6236dae4SAndroid Build Coastguard Worker           if((altlen == strlen(altptr)) &&
2192*6236dae4SAndroid Build Coastguard Worker              /* if this is not true, there was an embedded zero in the name
2193*6236dae4SAndroid Build Coastguard Worker                 string and we cannot match it. */
2194*6236dae4SAndroid Build Coastguard Worker              subj_alt_hostcheck(data, altptr, altlen,
2195*6236dae4SAndroid Build Coastguard Worker                                 peer->hostname, hostlen,
2196*6236dae4SAndroid Build Coastguard Worker                                 peer->dispname)) {
2197*6236dae4SAndroid Build Coastguard Worker             dnsmatched = TRUE;
2198*6236dae4SAndroid Build Coastguard Worker           }
2199*6236dae4SAndroid Build Coastguard Worker           break;
2200*6236dae4SAndroid Build Coastguard Worker 
2201*6236dae4SAndroid Build Coastguard Worker         case GEN_IPADD: /* IP address comparison */
2202*6236dae4SAndroid Build Coastguard Worker           /* compare alternative IP address if the data chunk is the same size
2203*6236dae4SAndroid Build Coastguard Worker              our server IP address is */
2204*6236dae4SAndroid Build Coastguard Worker           if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) {
2205*6236dae4SAndroid Build Coastguard Worker             ipmatched = TRUE;
2206*6236dae4SAndroid Build Coastguard Worker             infof(data,
2207*6236dae4SAndroid Build Coastguard Worker                   " subjectAltName: host \"%s\" matched cert's IP address!",
2208*6236dae4SAndroid Build Coastguard Worker                   peer->dispname);
2209*6236dae4SAndroid Build Coastguard Worker           }
2210*6236dae4SAndroid Build Coastguard Worker           break;
2211*6236dae4SAndroid Build Coastguard Worker         }
2212*6236dae4SAndroid Build Coastguard Worker       }
2213*6236dae4SAndroid Build Coastguard Worker     }
2214*6236dae4SAndroid Build Coastguard Worker     GENERAL_NAMES_free(altnames);
2215*6236dae4SAndroid Build Coastguard Worker 
2216*6236dae4SAndroid Build Coastguard Worker     if(dnsmatched || ipmatched)
2217*6236dae4SAndroid Build Coastguard Worker       matched = TRUE;
2218*6236dae4SAndroid Build Coastguard Worker   }
2219*6236dae4SAndroid Build Coastguard Worker 
2220*6236dae4SAndroid Build Coastguard Worker   if(matched)
2221*6236dae4SAndroid Build Coastguard Worker     /* an alternative name matched */
2222*6236dae4SAndroid Build Coastguard Worker     ;
2223*6236dae4SAndroid Build Coastguard Worker   else if(dNSName || iPAddress) {
2224*6236dae4SAndroid Build Coastguard Worker     const char *tname = (peer->type == CURL_SSL_PEER_DNS) ? "hostname" :
2225*6236dae4SAndroid Build Coastguard Worker                         (peer->type == CURL_SSL_PEER_IPV4) ?
2226*6236dae4SAndroid Build Coastguard Worker                         "ipv4 address" : "ipv6 address";
2227*6236dae4SAndroid Build Coastguard Worker     infof(data, " subjectAltName does not match %s %s", tname, peer->dispname);
2228*6236dae4SAndroid Build Coastguard Worker     failf(data, "SSL: no alternative certificate subject name matches "
2229*6236dae4SAndroid Build Coastguard Worker           "target %s '%s'", tname, peer->dispname);
2230*6236dae4SAndroid Build Coastguard Worker     result = CURLE_PEER_FAILED_VERIFICATION;
2231*6236dae4SAndroid Build Coastguard Worker   }
2232*6236dae4SAndroid Build Coastguard Worker   else {
2233*6236dae4SAndroid Build Coastguard Worker     /* we have to look to the last occurrence of a commonName in the
2234*6236dae4SAndroid Build Coastguard Worker        distinguished one to get the most significant one. */
2235*6236dae4SAndroid Build Coastguard Worker     int i = -1;
2236*6236dae4SAndroid Build Coastguard Worker     unsigned char *cn = NULL;
2237*6236dae4SAndroid Build Coastguard Worker     int cnlen = 0;
2238*6236dae4SAndroid Build Coastguard Worker     bool free_cn = FALSE;
2239*6236dae4SAndroid Build Coastguard Worker 
2240*6236dae4SAndroid Build Coastguard Worker     /* The following is done because of a bug in 0.9.6b */
2241*6236dae4SAndroid Build Coastguard Worker     X509_NAME *name = X509_get_subject_name(server_cert);
2242*6236dae4SAndroid Build Coastguard Worker     if(name) {
2243*6236dae4SAndroid Build Coastguard Worker       int j;
2244*6236dae4SAndroid Build Coastguard Worker       while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)
2245*6236dae4SAndroid Build Coastguard Worker         i = j;
2246*6236dae4SAndroid Build Coastguard Worker     }
2247*6236dae4SAndroid Build Coastguard Worker 
2248*6236dae4SAndroid Build Coastguard Worker     /* we have the name entry and we will now convert this to a string
2249*6236dae4SAndroid Build Coastguard Worker        that we can use for comparison. Doing this we support BMPstring,
2250*6236dae4SAndroid Build Coastguard Worker        UTF8, etc. */
2251*6236dae4SAndroid Build Coastguard Worker 
2252*6236dae4SAndroid Build Coastguard Worker     if(i >= 0) {
2253*6236dae4SAndroid Build Coastguard Worker       ASN1_STRING *tmp =
2254*6236dae4SAndroid Build Coastguard Worker         X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
2255*6236dae4SAndroid Build Coastguard Worker 
2256*6236dae4SAndroid Build Coastguard Worker       /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
2257*6236dae4SAndroid Build Coastguard Worker          is already UTF-8 encoded. We check for this case and copy the raw
2258*6236dae4SAndroid Build Coastguard Worker          string manually to avoid the problem. This code can be made
2259*6236dae4SAndroid Build Coastguard Worker          conditional in the future when OpenSSL has been fixed. */
2260*6236dae4SAndroid Build Coastguard Worker       if(tmp) {
2261*6236dae4SAndroid Build Coastguard Worker         if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
2262*6236dae4SAndroid Build Coastguard Worker           cnlen = ASN1_STRING_length(tmp);
2263*6236dae4SAndroid Build Coastguard Worker           cn = (unsigned char *) ASN1_STRING_get0_data(tmp);
2264*6236dae4SAndroid Build Coastguard Worker         }
2265*6236dae4SAndroid Build Coastguard Worker         else { /* not a UTF8 name */
2266*6236dae4SAndroid Build Coastguard Worker           cnlen = ASN1_STRING_to_UTF8(&cn, tmp);
2267*6236dae4SAndroid Build Coastguard Worker           free_cn = TRUE;
2268*6236dae4SAndroid Build Coastguard Worker         }
2269*6236dae4SAndroid Build Coastguard Worker 
2270*6236dae4SAndroid Build Coastguard Worker         if((cnlen <= 0) || !cn)
2271*6236dae4SAndroid Build Coastguard Worker           result = CURLE_OUT_OF_MEMORY;
2272*6236dae4SAndroid Build Coastguard Worker         else if((size_t)cnlen != strlen((char *)cn)) {
2273*6236dae4SAndroid Build Coastguard Worker           /* there was a terminating zero before the end of string, this
2274*6236dae4SAndroid Build Coastguard Worker              cannot match and we return failure! */
2275*6236dae4SAndroid Build Coastguard Worker           failf(data, "SSL: illegal cert name field");
2276*6236dae4SAndroid Build Coastguard Worker           result = CURLE_PEER_FAILED_VERIFICATION;
2277*6236dae4SAndroid Build Coastguard Worker         }
2278*6236dae4SAndroid Build Coastguard Worker       }
2279*6236dae4SAndroid Build Coastguard Worker     }
2280*6236dae4SAndroid Build Coastguard Worker 
2281*6236dae4SAndroid Build Coastguard Worker     if(result)
2282*6236dae4SAndroid Build Coastguard Worker       /* error already detected, pass through */
2283*6236dae4SAndroid Build Coastguard Worker       ;
2284*6236dae4SAndroid Build Coastguard Worker     else if(!cn) {
2285*6236dae4SAndroid Build Coastguard Worker       failf(data,
2286*6236dae4SAndroid Build Coastguard Worker             "SSL: unable to obtain common name from peer certificate");
2287*6236dae4SAndroid Build Coastguard Worker       result = CURLE_PEER_FAILED_VERIFICATION;
2288*6236dae4SAndroid Build Coastguard Worker     }
2289*6236dae4SAndroid Build Coastguard Worker     else if(!Curl_cert_hostcheck((const char *)cn, cnlen,
2290*6236dae4SAndroid Build Coastguard Worker                                  peer->hostname, hostlen)) {
2291*6236dae4SAndroid Build Coastguard Worker       failf(data, "SSL: certificate subject name '%s' does not match "
2292*6236dae4SAndroid Build Coastguard Worker             "target hostname '%s'", cn, peer->dispname);
2293*6236dae4SAndroid Build Coastguard Worker       result = CURLE_PEER_FAILED_VERIFICATION;
2294*6236dae4SAndroid Build Coastguard Worker     }
2295*6236dae4SAndroid Build Coastguard Worker     else {
2296*6236dae4SAndroid Build Coastguard Worker       infof(data, " common name: %s (matched)", cn);
2297*6236dae4SAndroid Build Coastguard Worker     }
2298*6236dae4SAndroid Build Coastguard Worker     if(free_cn)
2299*6236dae4SAndroid Build Coastguard Worker       OPENSSL_free(cn);
2300*6236dae4SAndroid Build Coastguard Worker   }
2301*6236dae4SAndroid Build Coastguard Worker 
2302*6236dae4SAndroid Build Coastguard Worker   return result;
2303*6236dae4SAndroid Build Coastguard Worker }
2304*6236dae4SAndroid Build Coastguard Worker 
2305*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
2306*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_OCSP)
verifystatus(struct Curl_cfilter * cf,struct Curl_easy * data,struct ossl_ctx * octx)2307*6236dae4SAndroid Build Coastguard Worker static CURLcode verifystatus(struct Curl_cfilter *cf,
2308*6236dae4SAndroid Build Coastguard Worker                              struct Curl_easy *data,
2309*6236dae4SAndroid Build Coastguard Worker                              struct ossl_ctx *octx)
2310*6236dae4SAndroid Build Coastguard Worker {
2311*6236dae4SAndroid Build Coastguard Worker   int i, ocsp_status;
2312*6236dae4SAndroid Build Coastguard Worker #if defined(OPENSSL_IS_AWSLC)
2313*6236dae4SAndroid Build Coastguard Worker   const uint8_t *status;
2314*6236dae4SAndroid Build Coastguard Worker #else
2315*6236dae4SAndroid Build Coastguard Worker   unsigned char *status;
2316*6236dae4SAndroid Build Coastguard Worker #endif
2317*6236dae4SAndroid Build Coastguard Worker   const unsigned char *p;
2318*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
2319*6236dae4SAndroid Build Coastguard Worker   OCSP_RESPONSE *rsp = NULL;
2320*6236dae4SAndroid Build Coastguard Worker   OCSP_BASICRESP *br = NULL;
2321*6236dae4SAndroid Build Coastguard Worker   X509_STORE     *st = NULL;
2322*6236dae4SAndroid Build Coastguard Worker   STACK_OF(X509) *ch = NULL;
2323*6236dae4SAndroid Build Coastguard Worker   X509 *cert;
2324*6236dae4SAndroid Build Coastguard Worker   OCSP_CERTID *id = NULL;
2325*6236dae4SAndroid Build Coastguard Worker   int cert_status, crl_reason;
2326*6236dae4SAndroid Build Coastguard Worker   ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2327*6236dae4SAndroid Build Coastguard Worker   int ret;
2328*6236dae4SAndroid Build Coastguard Worker   long len;
2329*6236dae4SAndroid Build Coastguard Worker 
2330*6236dae4SAndroid Build Coastguard Worker   (void)cf;
2331*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
2332*6236dae4SAndroid Build Coastguard Worker 
2333*6236dae4SAndroid Build Coastguard Worker   len = (long)SSL_get_tlsext_status_ocsp_resp(octx->ssl, &status);
2334*6236dae4SAndroid Build Coastguard Worker 
2335*6236dae4SAndroid Build Coastguard Worker   if(!status) {
2336*6236dae4SAndroid Build Coastguard Worker     failf(data, "No OCSP response received");
2337*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2338*6236dae4SAndroid Build Coastguard Worker     goto end;
2339*6236dae4SAndroid Build Coastguard Worker   }
2340*6236dae4SAndroid Build Coastguard Worker   p = status;
2341*6236dae4SAndroid Build Coastguard Worker   rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
2342*6236dae4SAndroid Build Coastguard Worker   if(!rsp) {
2343*6236dae4SAndroid Build Coastguard Worker     failf(data, "Invalid OCSP response");
2344*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2345*6236dae4SAndroid Build Coastguard Worker     goto end;
2346*6236dae4SAndroid Build Coastguard Worker   }
2347*6236dae4SAndroid Build Coastguard Worker 
2348*6236dae4SAndroid Build Coastguard Worker   ocsp_status = OCSP_response_status(rsp);
2349*6236dae4SAndroid Build Coastguard Worker   if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2350*6236dae4SAndroid Build Coastguard Worker     failf(data, "Invalid OCSP response status: %s (%d)",
2351*6236dae4SAndroid Build Coastguard Worker           OCSP_response_status_str(ocsp_status), ocsp_status);
2352*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2353*6236dae4SAndroid Build Coastguard Worker     goto end;
2354*6236dae4SAndroid Build Coastguard Worker   }
2355*6236dae4SAndroid Build Coastguard Worker 
2356*6236dae4SAndroid Build Coastguard Worker   br = OCSP_response_get1_basic(rsp);
2357*6236dae4SAndroid Build Coastguard Worker   if(!br) {
2358*6236dae4SAndroid Build Coastguard Worker     failf(data, "Invalid OCSP response");
2359*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2360*6236dae4SAndroid Build Coastguard Worker     goto end;
2361*6236dae4SAndroid Build Coastguard Worker   }
2362*6236dae4SAndroid Build Coastguard Worker 
2363*6236dae4SAndroid Build Coastguard Worker   ch = SSL_get_peer_cert_chain(octx->ssl);
2364*6236dae4SAndroid Build Coastguard Worker   if(!ch) {
2365*6236dae4SAndroid Build Coastguard Worker     failf(data, "Could not get peer certificate chain");
2366*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2367*6236dae4SAndroid Build Coastguard Worker     goto end;
2368*6236dae4SAndroid Build Coastguard Worker   }
2369*6236dae4SAndroid Build Coastguard Worker   st = SSL_CTX_get_cert_store(octx->ssl_ctx);
2370*6236dae4SAndroid Build Coastguard Worker 
2371*6236dae4SAndroid Build Coastguard Worker #if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
2372*6236dae4SAndroid Build Coastguard Worker      (defined(LIBRESSL_VERSION_NUMBER) &&                               \
2373*6236dae4SAndroid Build Coastguard Worker       LIBRESSL_VERSION_NUMBER <= 0x2040200fL))
2374*6236dae4SAndroid Build Coastguard Worker   /* The authorized responder cert in the OCSP response MUST be signed by the
2375*6236dae4SAndroid Build Coastguard Worker      peer cert's issuer (see RFC6960 section 4.2.2.2). If that is a root cert,
2376*6236dae4SAndroid Build Coastguard Worker      no problem, but if it is an intermediate cert OpenSSL has a bug where it
2377*6236dae4SAndroid Build Coastguard Worker      expects this issuer to be present in the chain embedded in the OCSP
2378*6236dae4SAndroid Build Coastguard Worker      response. So we add it if necessary. */
2379*6236dae4SAndroid Build Coastguard Worker 
2380*6236dae4SAndroid Build Coastguard Worker   /* First make sure the peer cert chain includes both a peer and an issuer,
2381*6236dae4SAndroid Build Coastguard Worker      and the OCSP response contains a responder cert. */
2382*6236dae4SAndroid Build Coastguard Worker   if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) {
2383*6236dae4SAndroid Build Coastguard Worker     X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1);
2384*6236dae4SAndroid Build Coastguard Worker 
2385*6236dae4SAndroid Build Coastguard Worker     /* Find issuer of responder cert and add it to the OCSP response chain */
2386*6236dae4SAndroid Build Coastguard Worker     for(i = 0; i < sk_X509_num(ch); i++) {
2387*6236dae4SAndroid Build Coastguard Worker       X509 *issuer = sk_X509_value(ch, i);
2388*6236dae4SAndroid Build Coastguard Worker       if(X509_check_issued(issuer, responder) == X509_V_OK) {
2389*6236dae4SAndroid Build Coastguard Worker         if(!OCSP_basic_add1_cert(br, issuer)) {
2390*6236dae4SAndroid Build Coastguard Worker           failf(data, "Could not add issuer cert to OCSP response");
2391*6236dae4SAndroid Build Coastguard Worker           result = CURLE_SSL_INVALIDCERTSTATUS;
2392*6236dae4SAndroid Build Coastguard Worker           goto end;
2393*6236dae4SAndroid Build Coastguard Worker         }
2394*6236dae4SAndroid Build Coastguard Worker       }
2395*6236dae4SAndroid Build Coastguard Worker     }
2396*6236dae4SAndroid Build Coastguard Worker   }
2397*6236dae4SAndroid Build Coastguard Worker #endif
2398*6236dae4SAndroid Build Coastguard Worker 
2399*6236dae4SAndroid Build Coastguard Worker   if(OCSP_basic_verify(br, ch, st, 0) <= 0) {
2400*6236dae4SAndroid Build Coastguard Worker     failf(data, "OCSP response verification failed");
2401*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2402*6236dae4SAndroid Build Coastguard Worker     goto end;
2403*6236dae4SAndroid Build Coastguard Worker   }
2404*6236dae4SAndroid Build Coastguard Worker 
2405*6236dae4SAndroid Build Coastguard Worker   /* Compute the certificate's ID */
2406*6236dae4SAndroid Build Coastguard Worker   cert = SSL_get1_peer_certificate(octx->ssl);
2407*6236dae4SAndroid Build Coastguard Worker   if(!cert) {
2408*6236dae4SAndroid Build Coastguard Worker     failf(data, "Error getting peer certificate");
2409*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2410*6236dae4SAndroid Build Coastguard Worker     goto end;
2411*6236dae4SAndroid Build Coastguard Worker   }
2412*6236dae4SAndroid Build Coastguard Worker 
2413*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < (int)sk_X509_num(ch); i++) {
2414*6236dae4SAndroid Build Coastguard Worker     X509 *issuer = sk_X509_value(ch, (ossl_valsize_t)i);
2415*6236dae4SAndroid Build Coastguard Worker     if(X509_check_issued(issuer, cert) == X509_V_OK) {
2416*6236dae4SAndroid Build Coastguard Worker       id = OCSP_cert_to_id(EVP_sha1(), cert, issuer);
2417*6236dae4SAndroid Build Coastguard Worker       break;
2418*6236dae4SAndroid Build Coastguard Worker     }
2419*6236dae4SAndroid Build Coastguard Worker   }
2420*6236dae4SAndroid Build Coastguard Worker   X509_free(cert);
2421*6236dae4SAndroid Build Coastguard Worker 
2422*6236dae4SAndroid Build Coastguard Worker   if(!id) {
2423*6236dae4SAndroid Build Coastguard Worker     failf(data, "Error computing OCSP ID");
2424*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2425*6236dae4SAndroid Build Coastguard Worker     goto end;
2426*6236dae4SAndroid Build Coastguard Worker   }
2427*6236dae4SAndroid Build Coastguard Worker 
2428*6236dae4SAndroid Build Coastguard Worker   /* Find the single OCSP response corresponding to the certificate ID */
2429*6236dae4SAndroid Build Coastguard Worker   ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev,
2430*6236dae4SAndroid Build Coastguard Worker                               &thisupd, &nextupd);
2431*6236dae4SAndroid Build Coastguard Worker   OCSP_CERTID_free(id);
2432*6236dae4SAndroid Build Coastguard Worker   if(ret != 1) {
2433*6236dae4SAndroid Build Coastguard Worker     failf(data, "Could not find certificate ID in OCSP response");
2434*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2435*6236dae4SAndroid Build Coastguard Worker     goto end;
2436*6236dae4SAndroid Build Coastguard Worker   }
2437*6236dae4SAndroid Build Coastguard Worker 
2438*6236dae4SAndroid Build Coastguard Worker   /* Validate the corresponding single OCSP response */
2439*6236dae4SAndroid Build Coastguard Worker   if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
2440*6236dae4SAndroid Build Coastguard Worker     failf(data, "OCSP response has expired");
2441*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2442*6236dae4SAndroid Build Coastguard Worker     goto end;
2443*6236dae4SAndroid Build Coastguard Worker   }
2444*6236dae4SAndroid Build Coastguard Worker 
2445*6236dae4SAndroid Build Coastguard Worker   infof(data, "SSL certificate status: %s (%d)",
2446*6236dae4SAndroid Build Coastguard Worker         OCSP_cert_status_str(cert_status), cert_status);
2447*6236dae4SAndroid Build Coastguard Worker 
2448*6236dae4SAndroid Build Coastguard Worker   switch(cert_status) {
2449*6236dae4SAndroid Build Coastguard Worker   case V_OCSP_CERTSTATUS_GOOD:
2450*6236dae4SAndroid Build Coastguard Worker     break;
2451*6236dae4SAndroid Build Coastguard Worker 
2452*6236dae4SAndroid Build Coastguard Worker   case V_OCSP_CERTSTATUS_REVOKED:
2453*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2454*6236dae4SAndroid Build Coastguard Worker     failf(data, "SSL certificate revocation reason: %s (%d)",
2455*6236dae4SAndroid Build Coastguard Worker           OCSP_crl_reason_str(crl_reason), crl_reason);
2456*6236dae4SAndroid Build Coastguard Worker     goto end;
2457*6236dae4SAndroid Build Coastguard Worker 
2458*6236dae4SAndroid Build Coastguard Worker   case V_OCSP_CERTSTATUS_UNKNOWN:
2459*6236dae4SAndroid Build Coastguard Worker   default:
2460*6236dae4SAndroid Build Coastguard Worker     result = CURLE_SSL_INVALIDCERTSTATUS;
2461*6236dae4SAndroid Build Coastguard Worker     goto end;
2462*6236dae4SAndroid Build Coastguard Worker   }
2463*6236dae4SAndroid Build Coastguard Worker 
2464*6236dae4SAndroid Build Coastguard Worker end:
2465*6236dae4SAndroid Build Coastguard Worker   if(br)
2466*6236dae4SAndroid Build Coastguard Worker     OCSP_BASICRESP_free(br);
2467*6236dae4SAndroid Build Coastguard Worker   OCSP_RESPONSE_free(rsp);
2468*6236dae4SAndroid Build Coastguard Worker 
2469*6236dae4SAndroid Build Coastguard Worker   return result;
2470*6236dae4SAndroid Build Coastguard Worker }
2471*6236dae4SAndroid Build Coastguard Worker #endif
2472*6236dae4SAndroid Build Coastguard Worker 
2473*6236dae4SAndroid Build Coastguard Worker #endif /* USE_OPENSSL */
2474*6236dae4SAndroid Build Coastguard Worker 
2475*6236dae4SAndroid Build Coastguard Worker /* The SSL_CTRL_SET_MSG_CALLBACK does not exist in ancient OpenSSL versions
2476*6236dae4SAndroid Build Coastguard Worker    and thus this cannot be done there. */
2477*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_CTRL_SET_MSG_CALLBACK
2478*6236dae4SAndroid Build Coastguard Worker 
ssl_msg_type(int ssl_ver,int msg)2479*6236dae4SAndroid Build Coastguard Worker static const char *ssl_msg_type(int ssl_ver, int msg)
2480*6236dae4SAndroid Build Coastguard Worker {
2481*6236dae4SAndroid Build Coastguard Worker #ifdef SSL2_VERSION_MAJOR
2482*6236dae4SAndroid Build Coastguard Worker   if(ssl_ver == SSL2_VERSION_MAJOR) {
2483*6236dae4SAndroid Build Coastguard Worker     switch(msg) {
2484*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_ERROR:
2485*6236dae4SAndroid Build Coastguard Worker       return "Error";
2486*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_CLIENT_HELLO:
2487*6236dae4SAndroid Build Coastguard Worker       return "Client hello";
2488*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_CLIENT_MASTER_KEY:
2489*6236dae4SAndroid Build Coastguard Worker       return "Client key";
2490*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_CLIENT_FINISHED:
2491*6236dae4SAndroid Build Coastguard Worker       return "Client finished";
2492*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_SERVER_HELLO:
2493*6236dae4SAndroid Build Coastguard Worker       return "Server hello";
2494*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_SERVER_VERIFY:
2495*6236dae4SAndroid Build Coastguard Worker       return "Server verify";
2496*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_SERVER_FINISHED:
2497*6236dae4SAndroid Build Coastguard Worker       return "Server finished";
2498*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_REQUEST_CERTIFICATE:
2499*6236dae4SAndroid Build Coastguard Worker       return "Request CERT";
2500*6236dae4SAndroid Build Coastguard Worker     case SSL2_MT_CLIENT_CERTIFICATE:
2501*6236dae4SAndroid Build Coastguard Worker       return "Client CERT";
2502*6236dae4SAndroid Build Coastguard Worker     }
2503*6236dae4SAndroid Build Coastguard Worker   }
2504*6236dae4SAndroid Build Coastguard Worker   else
2505*6236dae4SAndroid Build Coastguard Worker #endif
2506*6236dae4SAndroid Build Coastguard Worker   if(ssl_ver == SSL3_VERSION_MAJOR) {
2507*6236dae4SAndroid Build Coastguard Worker     switch(msg) {
2508*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_HELLO_REQUEST:
2509*6236dae4SAndroid Build Coastguard Worker       return "Hello request";
2510*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_CLIENT_HELLO:
2511*6236dae4SAndroid Build Coastguard Worker       return "Client hello";
2512*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_SERVER_HELLO:
2513*6236dae4SAndroid Build Coastguard Worker       return "Server hello";
2514*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_NEWSESSION_TICKET
2515*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_NEWSESSION_TICKET:
2516*6236dae4SAndroid Build Coastguard Worker       return "Newsession Ticket";
2517*6236dae4SAndroid Build Coastguard Worker #endif
2518*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_CERTIFICATE:
2519*6236dae4SAndroid Build Coastguard Worker       return "Certificate";
2520*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_SERVER_KEY_EXCHANGE:
2521*6236dae4SAndroid Build Coastguard Worker       return "Server key exchange";
2522*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_CLIENT_KEY_EXCHANGE:
2523*6236dae4SAndroid Build Coastguard Worker       return "Client key exchange";
2524*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_CERTIFICATE_REQUEST:
2525*6236dae4SAndroid Build Coastguard Worker       return "Request CERT";
2526*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_SERVER_DONE:
2527*6236dae4SAndroid Build Coastguard Worker       return "Server finished";
2528*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_CERTIFICATE_VERIFY:
2529*6236dae4SAndroid Build Coastguard Worker       return "CERT verify";
2530*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_FINISHED:
2531*6236dae4SAndroid Build Coastguard Worker       return "Finished";
2532*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_CERTIFICATE_STATUS
2533*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_CERTIFICATE_STATUS:
2534*6236dae4SAndroid Build Coastguard Worker       return "Certificate Status";
2535*6236dae4SAndroid Build Coastguard Worker #endif
2536*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
2537*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_ENCRYPTED_EXTENSIONS:
2538*6236dae4SAndroid Build Coastguard Worker       return "Encrypted Extensions";
2539*6236dae4SAndroid Build Coastguard Worker #endif
2540*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_SUPPLEMENTAL_DATA
2541*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_SUPPLEMENTAL_DATA:
2542*6236dae4SAndroid Build Coastguard Worker       return "Supplemental data";
2543*6236dae4SAndroid Build Coastguard Worker #endif
2544*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_END_OF_EARLY_DATA
2545*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_END_OF_EARLY_DATA:
2546*6236dae4SAndroid Build Coastguard Worker       return "End of early data";
2547*6236dae4SAndroid Build Coastguard Worker #endif
2548*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_KEY_UPDATE
2549*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_KEY_UPDATE:
2550*6236dae4SAndroid Build Coastguard Worker       return "Key update";
2551*6236dae4SAndroid Build Coastguard Worker #endif
2552*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_NEXT_PROTO
2553*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_NEXT_PROTO:
2554*6236dae4SAndroid Build Coastguard Worker       return "Next protocol";
2555*6236dae4SAndroid Build Coastguard Worker #endif
2556*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_MT_MESSAGE_HASH
2557*6236dae4SAndroid Build Coastguard Worker     case SSL3_MT_MESSAGE_HASH:
2558*6236dae4SAndroid Build Coastguard Worker       return "Message hash";
2559*6236dae4SAndroid Build Coastguard Worker #endif
2560*6236dae4SAndroid Build Coastguard Worker     }
2561*6236dae4SAndroid Build Coastguard Worker   }
2562*6236dae4SAndroid Build Coastguard Worker   return "Unknown";
2563*6236dae4SAndroid Build Coastguard Worker }
2564*6236dae4SAndroid Build Coastguard Worker 
tls_rt_type(int type)2565*6236dae4SAndroid Build Coastguard Worker static const char *tls_rt_type(int type)
2566*6236dae4SAndroid Build Coastguard Worker {
2567*6236dae4SAndroid Build Coastguard Worker   switch(type) {
2568*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_RT_HEADER
2569*6236dae4SAndroid Build Coastguard Worker   case SSL3_RT_HEADER:
2570*6236dae4SAndroid Build Coastguard Worker     return "TLS header";
2571*6236dae4SAndroid Build Coastguard Worker #endif
2572*6236dae4SAndroid Build Coastguard Worker   case SSL3_RT_CHANGE_CIPHER_SPEC:
2573*6236dae4SAndroid Build Coastguard Worker     return "TLS change cipher";
2574*6236dae4SAndroid Build Coastguard Worker   case SSL3_RT_ALERT:
2575*6236dae4SAndroid Build Coastguard Worker     return "TLS alert";
2576*6236dae4SAndroid Build Coastguard Worker   case SSL3_RT_HANDSHAKE:
2577*6236dae4SAndroid Build Coastguard Worker     return "TLS handshake";
2578*6236dae4SAndroid Build Coastguard Worker   case SSL3_RT_APPLICATION_DATA:
2579*6236dae4SAndroid Build Coastguard Worker     return "TLS app data";
2580*6236dae4SAndroid Build Coastguard Worker   default:
2581*6236dae4SAndroid Build Coastguard Worker     return "TLS Unknown";
2582*6236dae4SAndroid Build Coastguard Worker   }
2583*6236dae4SAndroid Build Coastguard Worker }
2584*6236dae4SAndroid Build Coastguard Worker 
2585*6236dae4SAndroid Build Coastguard Worker /*
2586*6236dae4SAndroid Build Coastguard Worker  * Our callback from the SSL/TLS layers.
2587*6236dae4SAndroid Build Coastguard Worker  */
ossl_trace(int direction,int ssl_ver,int content_type,const void * buf,size_t len,SSL * ssl,void * userp)2588*6236dae4SAndroid Build Coastguard Worker static void ossl_trace(int direction, int ssl_ver, int content_type,
2589*6236dae4SAndroid Build Coastguard Worker                        const void *buf, size_t len, SSL *ssl,
2590*6236dae4SAndroid Build Coastguard Worker                        void *userp)
2591*6236dae4SAndroid Build Coastguard Worker {
2592*6236dae4SAndroid Build Coastguard Worker   const char *verstr = "???";
2593*6236dae4SAndroid Build Coastguard Worker   struct Curl_cfilter *cf = userp;
2594*6236dae4SAndroid Build Coastguard Worker   struct Curl_easy *data = NULL;
2595*6236dae4SAndroid Build Coastguard Worker   char unknown[32];
2596*6236dae4SAndroid Build Coastguard Worker 
2597*6236dae4SAndroid Build Coastguard Worker   if(!cf)
2598*6236dae4SAndroid Build Coastguard Worker     return;
2599*6236dae4SAndroid Build Coastguard Worker   data = CF_DATA_CURRENT(cf);
2600*6236dae4SAndroid Build Coastguard Worker   if(!data || !data->set.fdebug || (direction && direction != 1))
2601*6236dae4SAndroid Build Coastguard Worker     return;
2602*6236dae4SAndroid Build Coastguard Worker 
2603*6236dae4SAndroid Build Coastguard Worker   switch(ssl_ver) {
2604*6236dae4SAndroid Build Coastguard Worker #ifdef SSL2_VERSION /* removed in recent versions */
2605*6236dae4SAndroid Build Coastguard Worker   case SSL2_VERSION:
2606*6236dae4SAndroid Build Coastguard Worker     verstr = "SSLv2";
2607*6236dae4SAndroid Build Coastguard Worker     break;
2608*6236dae4SAndroid Build Coastguard Worker #endif
2609*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_VERSION
2610*6236dae4SAndroid Build Coastguard Worker   case SSL3_VERSION:
2611*6236dae4SAndroid Build Coastguard Worker     verstr = "SSLv3";
2612*6236dae4SAndroid Build Coastguard Worker     break;
2613*6236dae4SAndroid Build Coastguard Worker #endif
2614*6236dae4SAndroid Build Coastguard Worker   case TLS1_VERSION:
2615*6236dae4SAndroid Build Coastguard Worker     verstr = "TLSv1.0";
2616*6236dae4SAndroid Build Coastguard Worker     break;
2617*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_1_VERSION
2618*6236dae4SAndroid Build Coastguard Worker   case TLS1_1_VERSION:
2619*6236dae4SAndroid Build Coastguard Worker     verstr = "TLSv1.1";
2620*6236dae4SAndroid Build Coastguard Worker     break;
2621*6236dae4SAndroid Build Coastguard Worker #endif
2622*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_2_VERSION
2623*6236dae4SAndroid Build Coastguard Worker   case TLS1_2_VERSION:
2624*6236dae4SAndroid Build Coastguard Worker     verstr = "TLSv1.2";
2625*6236dae4SAndroid Build Coastguard Worker     break;
2626*6236dae4SAndroid Build Coastguard Worker #endif
2627*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_3_VERSION
2628*6236dae4SAndroid Build Coastguard Worker   case TLS1_3_VERSION:
2629*6236dae4SAndroid Build Coastguard Worker     verstr = "TLSv1.3";
2630*6236dae4SAndroid Build Coastguard Worker     break;
2631*6236dae4SAndroid Build Coastguard Worker #endif
2632*6236dae4SAndroid Build Coastguard Worker   case 0:
2633*6236dae4SAndroid Build Coastguard Worker     break;
2634*6236dae4SAndroid Build Coastguard Worker   default:
2635*6236dae4SAndroid Build Coastguard Worker     msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
2636*6236dae4SAndroid Build Coastguard Worker     verstr = unknown;
2637*6236dae4SAndroid Build Coastguard Worker     break;
2638*6236dae4SAndroid Build Coastguard Worker   }
2639*6236dae4SAndroid Build Coastguard Worker 
2640*6236dae4SAndroid Build Coastguard Worker   /* Log progress for interesting records only (like Handshake or Alert), skip
2641*6236dae4SAndroid Build Coastguard Worker    * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0).
2642*6236dae4SAndroid Build Coastguard Worker    * For TLS 1.3, skip notification of the decrypted inner Content-Type.
2643*6236dae4SAndroid Build Coastguard Worker    */
2644*6236dae4SAndroid Build Coastguard Worker   if(ssl_ver
2645*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_RT_HEADER
2646*6236dae4SAndroid Build Coastguard Worker      && content_type != SSL3_RT_HEADER
2647*6236dae4SAndroid Build Coastguard Worker #endif
2648*6236dae4SAndroid Build Coastguard Worker #ifdef SSL3_RT_INNER_CONTENT_TYPE
2649*6236dae4SAndroid Build Coastguard Worker      && content_type != SSL3_RT_INNER_CONTENT_TYPE
2650*6236dae4SAndroid Build Coastguard Worker #endif
2651*6236dae4SAndroid Build Coastguard Worker     ) {
2652*6236dae4SAndroid Build Coastguard Worker     const char *msg_name, *tls_rt_name;
2653*6236dae4SAndroid Build Coastguard Worker     char ssl_buf[1024];
2654*6236dae4SAndroid Build Coastguard Worker     int msg_type, txt_len;
2655*6236dae4SAndroid Build Coastguard Worker 
2656*6236dae4SAndroid Build Coastguard Worker     /* the info given when the version is zero is not that useful for us */
2657*6236dae4SAndroid Build Coastguard Worker 
2658*6236dae4SAndroid Build Coastguard Worker     ssl_ver >>= 8; /* check the upper 8 bits only below */
2659*6236dae4SAndroid Build Coastguard Worker 
2660*6236dae4SAndroid Build Coastguard Worker     /* SSLv2 does not seem to have TLS record-type headers, so OpenSSL
2661*6236dae4SAndroid Build Coastguard Worker      * always pass-up content-type as 0. But the interesting message-type
2662*6236dae4SAndroid Build Coastguard Worker      * is at 'buf[0]'.
2663*6236dae4SAndroid Build Coastguard Worker      */
2664*6236dae4SAndroid Build Coastguard Worker     if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
2665*6236dae4SAndroid Build Coastguard Worker       tls_rt_name = tls_rt_type(content_type);
2666*6236dae4SAndroid Build Coastguard Worker     else
2667*6236dae4SAndroid Build Coastguard Worker       tls_rt_name = "";
2668*6236dae4SAndroid Build Coastguard Worker 
2669*6236dae4SAndroid Build Coastguard Worker     if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
2670*6236dae4SAndroid Build Coastguard Worker       msg_type = *(char *)buf;
2671*6236dae4SAndroid Build Coastguard Worker       msg_name = "Change cipher spec";
2672*6236dae4SAndroid Build Coastguard Worker     }
2673*6236dae4SAndroid Build Coastguard Worker     else if(content_type == SSL3_RT_ALERT) {
2674*6236dae4SAndroid Build Coastguard Worker       msg_type = (((char *)buf)[0] << 8) + ((char *)buf)[1];
2675*6236dae4SAndroid Build Coastguard Worker       msg_name = SSL_alert_desc_string_long(msg_type);
2676*6236dae4SAndroid Build Coastguard Worker     }
2677*6236dae4SAndroid Build Coastguard Worker     else {
2678*6236dae4SAndroid Build Coastguard Worker       msg_type = *(char *)buf;
2679*6236dae4SAndroid Build Coastguard Worker       msg_name = ssl_msg_type(ssl_ver, msg_type);
2680*6236dae4SAndroid Build Coastguard Worker     }
2681*6236dae4SAndroid Build Coastguard Worker 
2682*6236dae4SAndroid Build Coastguard Worker     txt_len = msnprintf(ssl_buf, sizeof(ssl_buf),
2683*6236dae4SAndroid Build Coastguard Worker                         "%s (%s), %s, %s (%d):\n",
2684*6236dae4SAndroid Build Coastguard Worker                         verstr, direction ? "OUT" : "IN",
2685*6236dae4SAndroid Build Coastguard Worker                         tls_rt_name, msg_name, msg_type);
2686*6236dae4SAndroid Build Coastguard Worker     Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len);
2687*6236dae4SAndroid Build Coastguard Worker   }
2688*6236dae4SAndroid Build Coastguard Worker 
2689*6236dae4SAndroid Build Coastguard Worker   Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
2690*6236dae4SAndroid Build Coastguard Worker              CURLINFO_SSL_DATA_IN, (char *)buf, len);
2691*6236dae4SAndroid Build Coastguard Worker   (void) ssl;
2692*6236dae4SAndroid Build Coastguard Worker }
2693*6236dae4SAndroid Build Coastguard Worker #endif
2694*6236dae4SAndroid Build Coastguard Worker 
2695*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL
2696*6236dae4SAndroid Build Coastguard Worker /* ====================================================== */
2697*6236dae4SAndroid Build Coastguard Worker 
2698*6236dae4SAndroid Build Coastguard Worker /* Check for OpenSSL 1.0.2 which has ALPN support. */
2699*6236dae4SAndroid Build Coastguard Worker #undef HAS_ALPN
2700*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x10002000L       \
2701*6236dae4SAndroid Build Coastguard Worker   && !defined(OPENSSL_NO_TLSEXT)
2702*6236dae4SAndroid Build Coastguard Worker #  define HAS_ALPN 1
2703*6236dae4SAndroid Build Coastguard Worker #endif
2704*6236dae4SAndroid Build Coastguard Worker 
2705*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
2706*6236dae4SAndroid Build Coastguard Worker static CURLcode
ossl_set_ssl_version_min_max(struct Curl_cfilter * cf,SSL_CTX * ctx)2707*6236dae4SAndroid Build Coastguard Worker ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
2708*6236dae4SAndroid Build Coastguard Worker {
2709*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
2710*6236dae4SAndroid Build Coastguard Worker   /* first, TLS min version... */
2711*6236dae4SAndroid Build Coastguard Worker   long curl_ssl_version_min = conn_config->version;
2712*6236dae4SAndroid Build Coastguard Worker   long curl_ssl_version_max;
2713*6236dae4SAndroid Build Coastguard Worker 
2714*6236dae4SAndroid Build Coastguard Worker   /* convert curl min SSL version option to OpenSSL constant */
2715*6236dae4SAndroid Build Coastguard Worker #if (defined(OPENSSL_IS_BORINGSSL)  || \
2716*6236dae4SAndroid Build Coastguard Worker      defined(OPENSSL_IS_AWSLC)      || \
2717*6236dae4SAndroid Build Coastguard Worker      defined(LIBRESSL_VERSION_NUMBER))
2718*6236dae4SAndroid Build Coastguard Worker   uint16_t ossl_ssl_version_min = 0;
2719*6236dae4SAndroid Build Coastguard Worker   uint16_t ossl_ssl_version_max = 0;
2720*6236dae4SAndroid Build Coastguard Worker #else
2721*6236dae4SAndroid Build Coastguard Worker   long ossl_ssl_version_min = 0;
2722*6236dae4SAndroid Build Coastguard Worker   long ossl_ssl_version_max = 0;
2723*6236dae4SAndroid Build Coastguard Worker #endif
2724*6236dae4SAndroid Build Coastguard Worker   switch(curl_ssl_version_min) {
2725*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1: /* TLS 1.x */
2726*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_0:
2727*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_min = TLS1_VERSION;
2728*6236dae4SAndroid Build Coastguard Worker     break;
2729*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_1:
2730*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_min = TLS1_1_VERSION;
2731*6236dae4SAndroid Build Coastguard Worker     break;
2732*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_2:
2733*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_min = TLS1_2_VERSION;
2734*6236dae4SAndroid Build Coastguard Worker     break;
2735*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_3:
2736*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_3_VERSION
2737*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_min = TLS1_3_VERSION;
2738*6236dae4SAndroid Build Coastguard Worker     break;
2739*6236dae4SAndroid Build Coastguard Worker #else
2740*6236dae4SAndroid Build Coastguard Worker     return CURLE_NOT_BUILT_IN;
2741*6236dae4SAndroid Build Coastguard Worker #endif
2742*6236dae4SAndroid Build Coastguard Worker   }
2743*6236dae4SAndroid Build Coastguard Worker 
2744*6236dae4SAndroid Build Coastguard Worker   /* CURL_SSLVERSION_DEFAULT means that no option was selected.
2745*6236dae4SAndroid Build Coastguard Worker      We do not want to pass 0 to SSL_CTX_set_min_proto_version as
2746*6236dae4SAndroid Build Coastguard Worker      it would enable all versions down to the lowest supported by
2747*6236dae4SAndroid Build Coastguard Worker      the library.
2748*6236dae4SAndroid Build Coastguard Worker      So we skip this, and stay with the library default
2749*6236dae4SAndroid Build Coastguard Worker   */
2750*6236dae4SAndroid Build Coastguard Worker   if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) {
2751*6236dae4SAndroid Build Coastguard Worker     if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) {
2752*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
2753*6236dae4SAndroid Build Coastguard Worker     }
2754*6236dae4SAndroid Build Coastguard Worker   }
2755*6236dae4SAndroid Build Coastguard Worker 
2756*6236dae4SAndroid Build Coastguard Worker   /* ... then, TLS max version */
2757*6236dae4SAndroid Build Coastguard Worker   curl_ssl_version_max = (long)conn_config->version_max;
2758*6236dae4SAndroid Build Coastguard Worker 
2759*6236dae4SAndroid Build Coastguard Worker   /* convert curl max SSL version option to OpenSSL constant */
2760*6236dae4SAndroid Build Coastguard Worker   switch(curl_ssl_version_max) {
2761*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_0:
2762*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_max = TLS1_VERSION;
2763*6236dae4SAndroid Build Coastguard Worker     break;
2764*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_1:
2765*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_max = TLS1_1_VERSION;
2766*6236dae4SAndroid Build Coastguard Worker     break;
2767*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_2:
2768*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_max = TLS1_2_VERSION;
2769*6236dae4SAndroid Build Coastguard Worker     break;
2770*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_3_VERSION
2771*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_3:
2772*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_max = TLS1_3_VERSION;
2773*6236dae4SAndroid Build Coastguard Worker     break;
2774*6236dae4SAndroid Build Coastguard Worker #endif
2775*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_NONE:  /* none selected */
2776*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_DEFAULT:  /* max selected */
2777*6236dae4SAndroid Build Coastguard Worker   default:
2778*6236dae4SAndroid Build Coastguard Worker     /* SSL_CTX_set_max_proto_version states that:
2779*6236dae4SAndroid Build Coastguard Worker        setting the maximum to 0 will enable
2780*6236dae4SAndroid Build Coastguard Worker        protocol versions up to the highest version
2781*6236dae4SAndroid Build Coastguard Worker        supported by the library */
2782*6236dae4SAndroid Build Coastguard Worker     ossl_ssl_version_max = 0;
2783*6236dae4SAndroid Build Coastguard Worker     break;
2784*6236dae4SAndroid Build Coastguard Worker   }
2785*6236dae4SAndroid Build Coastguard Worker 
2786*6236dae4SAndroid Build Coastguard Worker   if(!SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) {
2787*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_CONNECT_ERROR;
2788*6236dae4SAndroid Build Coastguard Worker   }
2789*6236dae4SAndroid Build Coastguard Worker 
2790*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
2791*6236dae4SAndroid Build Coastguard Worker }
2792*6236dae4SAndroid Build Coastguard Worker #endif
2793*6236dae4SAndroid Build Coastguard Worker 
2794*6236dae4SAndroid Build Coastguard Worker #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
2795*6236dae4SAndroid Build Coastguard Worker typedef uint32_t ctx_option_t;
2796*6236dae4SAndroid Build Coastguard Worker #elif OPENSSL_VERSION_NUMBER >= 0x30000000L
2797*6236dae4SAndroid Build Coastguard Worker typedef uint64_t ctx_option_t;
2798*6236dae4SAndroid Build Coastguard Worker #elif OPENSSL_VERSION_NUMBER >= 0x10100000L && \
2799*6236dae4SAndroid Build Coastguard Worker   !defined(LIBRESSL_VERSION_NUMBER)
2800*6236dae4SAndroid Build Coastguard Worker typedef unsigned long ctx_option_t;
2801*6236dae4SAndroid Build Coastguard Worker #else
2802*6236dae4SAndroid Build Coastguard Worker typedef long ctx_option_t;
2803*6236dae4SAndroid Build Coastguard Worker #endif
2804*6236dae4SAndroid Build Coastguard Worker 
2805*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
2806*6236dae4SAndroid Build Coastguard Worker static CURLcode
ossl_set_ssl_version_min_max_legacy(ctx_option_t * ctx_options,struct Curl_cfilter * cf,struct Curl_easy * data)2807*6236dae4SAndroid Build Coastguard Worker ossl_set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
2808*6236dae4SAndroid Build Coastguard Worker                                     struct Curl_cfilter *cf,
2809*6236dae4SAndroid Build Coastguard Worker                                     struct Curl_easy *data)
2810*6236dae4SAndroid Build Coastguard Worker {
2811*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
2812*6236dae4SAndroid Build Coastguard Worker   long ssl_version = conn_config->version;
2813*6236dae4SAndroid Build Coastguard Worker   long ssl_version_max = conn_config->version_max;
2814*6236dae4SAndroid Build Coastguard Worker 
2815*6236dae4SAndroid Build Coastguard Worker   (void) data; /* In case it is unused. */
2816*6236dae4SAndroid Build Coastguard Worker 
2817*6236dae4SAndroid Build Coastguard Worker   switch(ssl_version) {
2818*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_3:
2819*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_3_VERSION
2820*6236dae4SAndroid Build Coastguard Worker   {
2821*6236dae4SAndroid Build Coastguard Worker     struct ssl_connect_data *connssl = cf->ctx;
2822*6236dae4SAndroid Build Coastguard Worker     struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
2823*6236dae4SAndroid Build Coastguard Worker     DEBUGASSERT(octx);
2824*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_set_max_proto_version(octx->ssl_ctx, TLS1_3_VERSION);
2825*6236dae4SAndroid Build Coastguard Worker     *ctx_options |= SSL_OP_NO_TLSv1_2;
2826*6236dae4SAndroid Build Coastguard Worker   }
2827*6236dae4SAndroid Build Coastguard Worker #else
2828*6236dae4SAndroid Build Coastguard Worker   (void)ctx_options;
2829*6236dae4SAndroid Build Coastguard Worker   failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
2830*6236dae4SAndroid Build Coastguard Worker   return CURLE_NOT_BUILT_IN;
2831*6236dae4SAndroid Build Coastguard Worker #endif
2832*6236dae4SAndroid Build Coastguard Worker   FALLTHROUGH();
2833*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_2:
2834*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
2835*6236dae4SAndroid Build Coastguard Worker     *ctx_options |= SSL_OP_NO_TLSv1_1;
2836*6236dae4SAndroid Build Coastguard Worker #else
2837*6236dae4SAndroid Build Coastguard Worker     failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
2838*6236dae4SAndroid Build Coastguard Worker     return CURLE_NOT_BUILT_IN;
2839*6236dae4SAndroid Build Coastguard Worker #endif
2840*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
2841*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_1:
2842*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
2843*6236dae4SAndroid Build Coastguard Worker     *ctx_options |= SSL_OP_NO_TLSv1;
2844*6236dae4SAndroid Build Coastguard Worker #else
2845*6236dae4SAndroid Build Coastguard Worker     failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
2846*6236dae4SAndroid Build Coastguard Worker     return CURLE_NOT_BUILT_IN;
2847*6236dae4SAndroid Build Coastguard Worker #endif
2848*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
2849*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_0:
2850*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1:
2851*6236dae4SAndroid Build Coastguard Worker     break;
2852*6236dae4SAndroid Build Coastguard Worker   }
2853*6236dae4SAndroid Build Coastguard Worker 
2854*6236dae4SAndroid Build Coastguard Worker   switch(ssl_version_max) {
2855*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_0:
2856*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
2857*6236dae4SAndroid Build Coastguard Worker     *ctx_options |= SSL_OP_NO_TLSv1_1;
2858*6236dae4SAndroid Build Coastguard Worker #endif
2859*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
2860*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_1:
2861*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER >= 0x1000100FL
2862*6236dae4SAndroid Build Coastguard Worker     *ctx_options |= SSL_OP_NO_TLSv1_2;
2863*6236dae4SAndroid Build Coastguard Worker #endif
2864*6236dae4SAndroid Build Coastguard Worker     FALLTHROUGH();
2865*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_2:
2866*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_3_VERSION
2867*6236dae4SAndroid Build Coastguard Worker     *ctx_options |= SSL_OP_NO_TLSv1_3;
2868*6236dae4SAndroid Build Coastguard Worker #endif
2869*6236dae4SAndroid Build Coastguard Worker     break;
2870*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_MAX_TLSv1_3:
2871*6236dae4SAndroid Build Coastguard Worker #ifdef TLS1_3_VERSION
2872*6236dae4SAndroid Build Coastguard Worker     break;
2873*6236dae4SAndroid Build Coastguard Worker #else
2874*6236dae4SAndroid Build Coastguard Worker     failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
2875*6236dae4SAndroid Build Coastguard Worker     return CURLE_NOT_BUILT_IN;
2876*6236dae4SAndroid Build Coastguard Worker #endif
2877*6236dae4SAndroid Build Coastguard Worker   }
2878*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
2879*6236dae4SAndroid Build Coastguard Worker }
2880*6236dae4SAndroid Build Coastguard Worker #endif
2881*6236dae4SAndroid Build Coastguard Worker 
Curl_ossl_add_session(struct Curl_cfilter * cf,struct Curl_easy * data,const struct ssl_peer * peer,SSL_SESSION * session)2882*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
2883*6236dae4SAndroid Build Coastguard Worker                                struct Curl_easy *data,
2884*6236dae4SAndroid Build Coastguard Worker                                const struct ssl_peer *peer,
2885*6236dae4SAndroid Build Coastguard Worker                                SSL_SESSION *session)
2886*6236dae4SAndroid Build Coastguard Worker {
2887*6236dae4SAndroid Build Coastguard Worker   const struct ssl_config_data *config;
2888*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
2889*6236dae4SAndroid Build Coastguard Worker   size_t der_session_size;
2890*6236dae4SAndroid Build Coastguard Worker   unsigned char *der_session_buf;
2891*6236dae4SAndroid Build Coastguard Worker   unsigned char *der_session_ptr;
2892*6236dae4SAndroid Build Coastguard Worker 
2893*6236dae4SAndroid Build Coastguard Worker   if(!cf || !data)
2894*6236dae4SAndroid Build Coastguard Worker     goto out;
2895*6236dae4SAndroid Build Coastguard Worker 
2896*6236dae4SAndroid Build Coastguard Worker   config = Curl_ssl_cf_get_config(cf, data);
2897*6236dae4SAndroid Build Coastguard Worker   if(config->primary.cache_session) {
2898*6236dae4SAndroid Build Coastguard Worker 
2899*6236dae4SAndroid Build Coastguard Worker     der_session_size = i2d_SSL_SESSION(session, NULL);
2900*6236dae4SAndroid Build Coastguard Worker     if(der_session_size == 0) {
2901*6236dae4SAndroid Build Coastguard Worker       result = CURLE_OUT_OF_MEMORY;
2902*6236dae4SAndroid Build Coastguard Worker       goto out;
2903*6236dae4SAndroid Build Coastguard Worker     }
2904*6236dae4SAndroid Build Coastguard Worker 
2905*6236dae4SAndroid Build Coastguard Worker     der_session_buf = der_session_ptr = malloc(der_session_size);
2906*6236dae4SAndroid Build Coastguard Worker     if(!der_session_buf) {
2907*6236dae4SAndroid Build Coastguard Worker       result = CURLE_OUT_OF_MEMORY;
2908*6236dae4SAndroid Build Coastguard Worker       goto out;
2909*6236dae4SAndroid Build Coastguard Worker     }
2910*6236dae4SAndroid Build Coastguard Worker 
2911*6236dae4SAndroid Build Coastguard Worker     der_session_size = i2d_SSL_SESSION(session, &der_session_ptr);
2912*6236dae4SAndroid Build Coastguard Worker     if(der_session_size == 0) {
2913*6236dae4SAndroid Build Coastguard Worker       result = CURLE_OUT_OF_MEMORY;
2914*6236dae4SAndroid Build Coastguard Worker       free(der_session_buf);
2915*6236dae4SAndroid Build Coastguard Worker       goto out;
2916*6236dae4SAndroid Build Coastguard Worker     }
2917*6236dae4SAndroid Build Coastguard Worker 
2918*6236dae4SAndroid Build Coastguard Worker     Curl_ssl_sessionid_lock(data);
2919*6236dae4SAndroid Build Coastguard Worker     result = Curl_ssl_set_sessionid(cf, data, peer, NULL, der_session_buf,
2920*6236dae4SAndroid Build Coastguard Worker                                     der_session_size, ossl_session_free);
2921*6236dae4SAndroid Build Coastguard Worker     Curl_ssl_sessionid_unlock(data);
2922*6236dae4SAndroid Build Coastguard Worker   }
2923*6236dae4SAndroid Build Coastguard Worker 
2924*6236dae4SAndroid Build Coastguard Worker out:
2925*6236dae4SAndroid Build Coastguard Worker   return result;
2926*6236dae4SAndroid Build Coastguard Worker }
2927*6236dae4SAndroid Build Coastguard Worker 
2928*6236dae4SAndroid Build Coastguard Worker /* The "new session" callback must return zero if the session can be removed
2929*6236dae4SAndroid Build Coastguard Worker  * or non-zero if the session has been put into the session cache.
2930*6236dae4SAndroid Build Coastguard Worker  */
ossl_new_session_cb(SSL * ssl,SSL_SESSION * ssl_sessionid)2931*6236dae4SAndroid Build Coastguard Worker static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
2932*6236dae4SAndroid Build Coastguard Worker {
2933*6236dae4SAndroid Build Coastguard Worker   struct Curl_cfilter *cf;
2934*6236dae4SAndroid Build Coastguard Worker   struct Curl_easy *data;
2935*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl;
2936*6236dae4SAndroid Build Coastguard Worker 
2937*6236dae4SAndroid Build Coastguard Worker   cf = (struct Curl_cfilter*) SSL_get_app_data(ssl);
2938*6236dae4SAndroid Build Coastguard Worker   connssl = cf ? cf->ctx : NULL;
2939*6236dae4SAndroid Build Coastguard Worker   data = connssl ? CF_DATA_CURRENT(cf) : NULL;
2940*6236dae4SAndroid Build Coastguard Worker   Curl_ossl_add_session(cf, data, &connssl->peer, ssl_sessionid);
2941*6236dae4SAndroid Build Coastguard Worker   return 0;
2942*6236dae4SAndroid Build Coastguard Worker }
2943*6236dae4SAndroid Build Coastguard Worker 
load_cacert_from_memory(X509_STORE * store,const struct curl_blob * ca_info_blob)2944*6236dae4SAndroid Build Coastguard Worker static CURLcode load_cacert_from_memory(X509_STORE *store,
2945*6236dae4SAndroid Build Coastguard Worker                                         const struct curl_blob *ca_info_blob)
2946*6236dae4SAndroid Build Coastguard Worker {
2947*6236dae4SAndroid Build Coastguard Worker   /* these need to be freed at the end */
2948*6236dae4SAndroid Build Coastguard Worker   BIO *cbio = NULL;
2949*6236dae4SAndroid Build Coastguard Worker   STACK_OF(X509_INFO) *inf = NULL;
2950*6236dae4SAndroid Build Coastguard Worker 
2951*6236dae4SAndroid Build Coastguard Worker   /* everything else is just a reference */
2952*6236dae4SAndroid Build Coastguard Worker   int i, count = 0;
2953*6236dae4SAndroid Build Coastguard Worker   X509_INFO *itmp = NULL;
2954*6236dae4SAndroid Build Coastguard Worker 
2955*6236dae4SAndroid Build Coastguard Worker   if(ca_info_blob->len > (size_t)INT_MAX)
2956*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_CACERT_BADFILE;
2957*6236dae4SAndroid Build Coastguard Worker 
2958*6236dae4SAndroid Build Coastguard Worker   cbio = BIO_new_mem_buf(ca_info_blob->data, (int)ca_info_blob->len);
2959*6236dae4SAndroid Build Coastguard Worker   if(!cbio)
2960*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
2961*6236dae4SAndroid Build Coastguard Worker 
2962*6236dae4SAndroid Build Coastguard Worker   inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
2963*6236dae4SAndroid Build Coastguard Worker   if(!inf) {
2964*6236dae4SAndroid Build Coastguard Worker     BIO_free(cbio);
2965*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_CACERT_BADFILE;
2966*6236dae4SAndroid Build Coastguard Worker   }
2967*6236dae4SAndroid Build Coastguard Worker 
2968*6236dae4SAndroid Build Coastguard Worker   /* add each entry from PEM file to x509_store */
2969*6236dae4SAndroid Build Coastguard Worker   for(i = 0; i < (int)sk_X509_INFO_num(inf); ++i) {
2970*6236dae4SAndroid Build Coastguard Worker     itmp = sk_X509_INFO_value(inf, (ossl_valsize_t)i);
2971*6236dae4SAndroid Build Coastguard Worker     if(itmp->x509) {
2972*6236dae4SAndroid Build Coastguard Worker       if(X509_STORE_add_cert(store, itmp->x509)) {
2973*6236dae4SAndroid Build Coastguard Worker         ++count;
2974*6236dae4SAndroid Build Coastguard Worker       }
2975*6236dae4SAndroid Build Coastguard Worker       else {
2976*6236dae4SAndroid Build Coastguard Worker         /* set count to 0 to return an error */
2977*6236dae4SAndroid Build Coastguard Worker         count = 0;
2978*6236dae4SAndroid Build Coastguard Worker         break;
2979*6236dae4SAndroid Build Coastguard Worker       }
2980*6236dae4SAndroid Build Coastguard Worker     }
2981*6236dae4SAndroid Build Coastguard Worker     if(itmp->crl) {
2982*6236dae4SAndroid Build Coastguard Worker       if(X509_STORE_add_crl(store, itmp->crl)) {
2983*6236dae4SAndroid Build Coastguard Worker         ++count;
2984*6236dae4SAndroid Build Coastguard Worker       }
2985*6236dae4SAndroid Build Coastguard Worker       else {
2986*6236dae4SAndroid Build Coastguard Worker         /* set count to 0 to return an error */
2987*6236dae4SAndroid Build Coastguard Worker         count = 0;
2988*6236dae4SAndroid Build Coastguard Worker         break;
2989*6236dae4SAndroid Build Coastguard Worker       }
2990*6236dae4SAndroid Build Coastguard Worker     }
2991*6236dae4SAndroid Build Coastguard Worker   }
2992*6236dae4SAndroid Build Coastguard Worker 
2993*6236dae4SAndroid Build Coastguard Worker   sk_X509_INFO_pop_free(inf, X509_INFO_free);
2994*6236dae4SAndroid Build Coastguard Worker   BIO_free(cbio);
2995*6236dae4SAndroid Build Coastguard Worker 
2996*6236dae4SAndroid Build Coastguard Worker   /* if we did not end up importing anything, treat that as an error */
2997*6236dae4SAndroid Build Coastguard Worker   return (count > 0) ? CURLE_OK : CURLE_SSL_CACERT_BADFILE;
2998*6236dae4SAndroid Build Coastguard Worker }
2999*6236dae4SAndroid Build Coastguard Worker 
3000*6236dae4SAndroid Build Coastguard Worker #if defined(USE_WIN32_CRYPTO)
import_windows_cert_store(struct Curl_easy * data,const char * name,X509_STORE * store,bool * imported)3001*6236dae4SAndroid Build Coastguard Worker static CURLcode import_windows_cert_store(struct Curl_easy *data,
3002*6236dae4SAndroid Build Coastguard Worker                                           const char *name,
3003*6236dae4SAndroid Build Coastguard Worker                                           X509_STORE *store,
3004*6236dae4SAndroid Build Coastguard Worker                                           bool *imported)
3005*6236dae4SAndroid Build Coastguard Worker {
3006*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
3007*6236dae4SAndroid Build Coastguard Worker   HCERTSTORE hStore;
3008*6236dae4SAndroid Build Coastguard Worker 
3009*6236dae4SAndroid Build Coastguard Worker   *imported = FALSE;
3010*6236dae4SAndroid Build Coastguard Worker 
3011*6236dae4SAndroid Build Coastguard Worker   hStore = CertOpenSystemStoreA(0, name);
3012*6236dae4SAndroid Build Coastguard Worker   if(hStore) {
3013*6236dae4SAndroid Build Coastguard Worker     PCCERT_CONTEXT pContext = NULL;
3014*6236dae4SAndroid Build Coastguard Worker     /* The array of enhanced key usage OIDs will vary per certificate and
3015*6236dae4SAndroid Build Coastguard Worker        is declared outside of the loop so that rather than malloc/free each
3016*6236dae4SAndroid Build Coastguard Worker        iteration we can grow it with realloc, when necessary. */
3017*6236dae4SAndroid Build Coastguard Worker     CERT_ENHKEY_USAGE *enhkey_usage = NULL;
3018*6236dae4SAndroid Build Coastguard Worker     DWORD enhkey_usage_size = 0;
3019*6236dae4SAndroid Build Coastguard Worker 
3020*6236dae4SAndroid Build Coastguard Worker     /* This loop makes a best effort to import all valid certificates from
3021*6236dae4SAndroid Build Coastguard Worker        the MS root store. If a certificate cannot be imported it is
3022*6236dae4SAndroid Build Coastguard Worker        skipped. 'result' is used to store only hard-fail conditions (such
3023*6236dae4SAndroid Build Coastguard Worker        as out of memory) that cause an early break. */
3024*6236dae4SAndroid Build Coastguard Worker     result = CURLE_OK;
3025*6236dae4SAndroid Build Coastguard Worker     for(;;) {
3026*6236dae4SAndroid Build Coastguard Worker       X509 *x509;
3027*6236dae4SAndroid Build Coastguard Worker       FILETIME now;
3028*6236dae4SAndroid Build Coastguard Worker       BYTE key_usage[2];
3029*6236dae4SAndroid Build Coastguard Worker       DWORD req_size;
3030*6236dae4SAndroid Build Coastguard Worker       const unsigned char *encoded_cert;
3031*6236dae4SAndroid Build Coastguard Worker       pContext = CertEnumCertificatesInStore(hStore, pContext);
3032*6236dae4SAndroid Build Coastguard Worker       if(!pContext)
3033*6236dae4SAndroid Build Coastguard Worker         break;
3034*6236dae4SAndroid Build Coastguard Worker 
3035*6236dae4SAndroid Build Coastguard Worker #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
3036*6236dae4SAndroid Build Coastguard Worker       else {
3037*6236dae4SAndroid Build Coastguard Worker         char cert_name[256];
3038*6236dae4SAndroid Build Coastguard Worker         if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
3039*6236dae4SAndroid Build Coastguard Worker                                NULL, cert_name, sizeof(cert_name)))
3040*6236dae4SAndroid Build Coastguard Worker           infof(data, "SSL: unknown cert name");
3041*6236dae4SAndroid Build Coastguard Worker         else
3042*6236dae4SAndroid Build Coastguard Worker           infof(data, "SSL: Checking cert \"%s\"", cert_name);
3043*6236dae4SAndroid Build Coastguard Worker       }
3044*6236dae4SAndroid Build Coastguard Worker #endif
3045*6236dae4SAndroid Build Coastguard Worker       encoded_cert = (const unsigned char *)pContext->pbCertEncoded;
3046*6236dae4SAndroid Build Coastguard Worker       if(!encoded_cert)
3047*6236dae4SAndroid Build Coastguard Worker         continue;
3048*6236dae4SAndroid Build Coastguard Worker 
3049*6236dae4SAndroid Build Coastguard Worker       GetSystemTimeAsFileTime(&now);
3050*6236dae4SAndroid Build Coastguard Worker       if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 ||
3051*6236dae4SAndroid Build Coastguard Worker          CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0)
3052*6236dae4SAndroid Build Coastguard Worker         continue;
3053*6236dae4SAndroid Build Coastguard Worker 
3054*6236dae4SAndroid Build Coastguard Worker       /* If key usage exists check for signing attribute */
3055*6236dae4SAndroid Build Coastguard Worker       if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType,
3056*6236dae4SAndroid Build Coastguard Worker                                  pContext->pCertInfo,
3057*6236dae4SAndroid Build Coastguard Worker                                  key_usage, sizeof(key_usage))) {
3058*6236dae4SAndroid Build Coastguard Worker         if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE))
3059*6236dae4SAndroid Build Coastguard Worker           continue;
3060*6236dae4SAndroid Build Coastguard Worker       }
3061*6236dae4SAndroid Build Coastguard Worker       else if(GetLastError())
3062*6236dae4SAndroid Build Coastguard Worker         continue;
3063*6236dae4SAndroid Build Coastguard Worker 
3064*6236dae4SAndroid Build Coastguard Worker       /* If enhanced key usage exists check for server auth attribute.
3065*6236dae4SAndroid Build Coastguard Worker        *
3066*6236dae4SAndroid Build Coastguard Worker        * Note "In a Microsoft environment, a certificate might also have
3067*6236dae4SAndroid Build Coastguard Worker        * EKU extended properties that specify valid uses for the
3068*6236dae4SAndroid Build Coastguard Worker        * certificate."  The call below checks both, and behavior varies
3069*6236dae4SAndroid Build Coastguard Worker        * depending on what is found. For more details see
3070*6236dae4SAndroid Build Coastguard Worker        * CertGetEnhancedKeyUsage doc.
3071*6236dae4SAndroid Build Coastguard Worker        */
3072*6236dae4SAndroid Build Coastguard Worker       if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) {
3073*6236dae4SAndroid Build Coastguard Worker         if(req_size && req_size > enhkey_usage_size) {
3074*6236dae4SAndroid Build Coastguard Worker           void *tmp = realloc(enhkey_usage, req_size);
3075*6236dae4SAndroid Build Coastguard Worker 
3076*6236dae4SAndroid Build Coastguard Worker           if(!tmp) {
3077*6236dae4SAndroid Build Coastguard Worker             failf(data, "SSL: Out of memory allocating for OID list");
3078*6236dae4SAndroid Build Coastguard Worker             result = CURLE_OUT_OF_MEMORY;
3079*6236dae4SAndroid Build Coastguard Worker             break;
3080*6236dae4SAndroid Build Coastguard Worker           }
3081*6236dae4SAndroid Build Coastguard Worker 
3082*6236dae4SAndroid Build Coastguard Worker           enhkey_usage = (CERT_ENHKEY_USAGE *)tmp;
3083*6236dae4SAndroid Build Coastguard Worker           enhkey_usage_size = req_size;
3084*6236dae4SAndroid Build Coastguard Worker         }
3085*6236dae4SAndroid Build Coastguard Worker 
3086*6236dae4SAndroid Build Coastguard Worker         if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) {
3087*6236dae4SAndroid Build Coastguard Worker           if(!enhkey_usage->cUsageIdentifier) {
3088*6236dae4SAndroid Build Coastguard Worker             /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate
3089*6236dae4SAndroid Build Coastguard Worker                is good for all uses. If it returns zero, the certificate
3090*6236dae4SAndroid Build Coastguard Worker                has no valid uses." */
3091*6236dae4SAndroid Build Coastguard Worker             if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND)
3092*6236dae4SAndroid Build Coastguard Worker               continue;
3093*6236dae4SAndroid Build Coastguard Worker           }
3094*6236dae4SAndroid Build Coastguard Worker           else {
3095*6236dae4SAndroid Build Coastguard Worker             DWORD i;
3096*6236dae4SAndroid Build Coastguard Worker             bool found = FALSE;
3097*6236dae4SAndroid Build Coastguard Worker 
3098*6236dae4SAndroid Build Coastguard Worker             for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) {
3099*6236dae4SAndroid Build Coastguard Worker               if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */,
3100*6236dae4SAndroid Build Coastguard Worker                          enhkey_usage->rgpszUsageIdentifier[i])) {
3101*6236dae4SAndroid Build Coastguard Worker                 found = TRUE;
3102*6236dae4SAndroid Build Coastguard Worker                 break;
3103*6236dae4SAndroid Build Coastguard Worker               }
3104*6236dae4SAndroid Build Coastguard Worker             }
3105*6236dae4SAndroid Build Coastguard Worker 
3106*6236dae4SAndroid Build Coastguard Worker             if(!found)
3107*6236dae4SAndroid Build Coastguard Worker               continue;
3108*6236dae4SAndroid Build Coastguard Worker           }
3109*6236dae4SAndroid Build Coastguard Worker         }
3110*6236dae4SAndroid Build Coastguard Worker         else
3111*6236dae4SAndroid Build Coastguard Worker           continue;
3112*6236dae4SAndroid Build Coastguard Worker       }
3113*6236dae4SAndroid Build Coastguard Worker       else
3114*6236dae4SAndroid Build Coastguard Worker         continue;
3115*6236dae4SAndroid Build Coastguard Worker 
3116*6236dae4SAndroid Build Coastguard Worker       x509 = d2i_X509(NULL, &encoded_cert, (long)pContext->cbCertEncoded);
3117*6236dae4SAndroid Build Coastguard Worker       if(!x509)
3118*6236dae4SAndroid Build Coastguard Worker         continue;
3119*6236dae4SAndroid Build Coastguard Worker 
3120*6236dae4SAndroid Build Coastguard Worker       /* Try to import the certificate. This may fail for legitimate
3121*6236dae4SAndroid Build Coastguard Worker          reasons such as duplicate certificate, which is allowed by MS but
3122*6236dae4SAndroid Build Coastguard Worker          not OpenSSL. */
3123*6236dae4SAndroid Build Coastguard Worker       if(X509_STORE_add_cert(store, x509) == 1) {
3124*6236dae4SAndroid Build Coastguard Worker #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
3125*6236dae4SAndroid Build Coastguard Worker         infof(data, "SSL: Imported cert");
3126*6236dae4SAndroid Build Coastguard Worker #endif
3127*6236dae4SAndroid Build Coastguard Worker         *imported = TRUE;
3128*6236dae4SAndroid Build Coastguard Worker       }
3129*6236dae4SAndroid Build Coastguard Worker       X509_free(x509);
3130*6236dae4SAndroid Build Coastguard Worker     }
3131*6236dae4SAndroid Build Coastguard Worker 
3132*6236dae4SAndroid Build Coastguard Worker     free(enhkey_usage);
3133*6236dae4SAndroid Build Coastguard Worker     CertFreeCertificateContext(pContext);
3134*6236dae4SAndroid Build Coastguard Worker     CertCloseStore(hStore, 0);
3135*6236dae4SAndroid Build Coastguard Worker 
3136*6236dae4SAndroid Build Coastguard Worker     if(result)
3137*6236dae4SAndroid Build Coastguard Worker       return result;
3138*6236dae4SAndroid Build Coastguard Worker   }
3139*6236dae4SAndroid Build Coastguard Worker 
3140*6236dae4SAndroid Build Coastguard Worker   return result;
3141*6236dae4SAndroid Build Coastguard Worker }
3142*6236dae4SAndroid Build Coastguard Worker #endif
3143*6236dae4SAndroid Build Coastguard Worker 
populate_x509_store(struct Curl_cfilter * cf,struct Curl_easy * data,X509_STORE * store)3144*6236dae4SAndroid Build Coastguard Worker static CURLcode populate_x509_store(struct Curl_cfilter *cf,
3145*6236dae4SAndroid Build Coastguard Worker                                     struct Curl_easy *data,
3146*6236dae4SAndroid Build Coastguard Worker                                     X509_STORE *store)
3147*6236dae4SAndroid Build Coastguard Worker {
3148*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
3149*6236dae4SAndroid Build Coastguard Worker   struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
3150*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
3151*6236dae4SAndroid Build Coastguard Worker   X509_LOOKUP *lookup = NULL;
3152*6236dae4SAndroid Build Coastguard Worker   const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
3153*6236dae4SAndroid Build Coastguard Worker   const char * const ssl_cafile =
3154*6236dae4SAndroid Build Coastguard Worker     /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
3155*6236dae4SAndroid Build Coastguard Worker     (ca_info_blob ? NULL : conn_config->CAfile);
3156*6236dae4SAndroid Build Coastguard Worker   const char * const ssl_capath = conn_config->CApath;
3157*6236dae4SAndroid Build Coastguard Worker   const char * const ssl_crlfile = ssl_config->primary.CRLfile;
3158*6236dae4SAndroid Build Coastguard Worker   const bool verifypeer = conn_config->verifypeer;
3159*6236dae4SAndroid Build Coastguard Worker   bool imported_native_ca = FALSE;
3160*6236dae4SAndroid Build Coastguard Worker   bool imported_ca_info_blob = FALSE;
3161*6236dae4SAndroid Build Coastguard Worker 
3162*6236dae4SAndroid Build Coastguard Worker   CURL_TRC_CF(data, cf, "populate_x509_store, path=%s, blob=%d",
3163*6236dae4SAndroid Build Coastguard Worker               ssl_cafile ? ssl_cafile : "none", !!ca_info_blob);
3164*6236dae4SAndroid Build Coastguard Worker   if(!store)
3165*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
3166*6236dae4SAndroid Build Coastguard Worker 
3167*6236dae4SAndroid Build Coastguard Worker   if(verifypeer) {
3168*6236dae4SAndroid Build Coastguard Worker #if defined(USE_WIN32_CRYPTO)
3169*6236dae4SAndroid Build Coastguard Worker     /* Import certificates from the Windows root certificate store if
3170*6236dae4SAndroid Build Coastguard Worker        requested.
3171*6236dae4SAndroid Build Coastguard Worker        https://stackoverflow.com/questions/9507184/
3172*6236dae4SAndroid Build Coastguard Worker        https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037
3173*6236dae4SAndroid Build Coastguard Worker        https://datatracker.ietf.org/doc/html/rfc5280 */
3174*6236dae4SAndroid Build Coastguard Worker     if(ssl_config->native_ca_store) {
3175*6236dae4SAndroid Build Coastguard Worker       const char *storeNames[] = {
3176*6236dae4SAndroid Build Coastguard Worker         "ROOT",   /* Trusted Root Certification Authorities */
3177*6236dae4SAndroid Build Coastguard Worker         "CA"      /* Intermediate Certification Authorities */
3178*6236dae4SAndroid Build Coastguard Worker       };
3179*6236dae4SAndroid Build Coastguard Worker       size_t i;
3180*6236dae4SAndroid Build Coastguard Worker       for(i = 0; i < ARRAYSIZE(storeNames); ++i) {
3181*6236dae4SAndroid Build Coastguard Worker         bool imported = FALSE;
3182*6236dae4SAndroid Build Coastguard Worker         result = import_windows_cert_store(data, storeNames[i], store,
3183*6236dae4SAndroid Build Coastguard Worker                                            &imported);
3184*6236dae4SAndroid Build Coastguard Worker         if(result)
3185*6236dae4SAndroid Build Coastguard Worker           return result;
3186*6236dae4SAndroid Build Coastguard Worker         if(imported) {
3187*6236dae4SAndroid Build Coastguard Worker           infof(data, "successfully imported Windows %s store", storeNames[i]);
3188*6236dae4SAndroid Build Coastguard Worker           imported_native_ca = TRUE;
3189*6236dae4SAndroid Build Coastguard Worker         }
3190*6236dae4SAndroid Build Coastguard Worker         else
3191*6236dae4SAndroid Build Coastguard Worker           infof(data, "error importing Windows %s store, continuing anyway",
3192*6236dae4SAndroid Build Coastguard Worker                 storeNames[i]);
3193*6236dae4SAndroid Build Coastguard Worker       }
3194*6236dae4SAndroid Build Coastguard Worker     }
3195*6236dae4SAndroid Build Coastguard Worker #endif
3196*6236dae4SAndroid Build Coastguard Worker     if(ca_info_blob) {
3197*6236dae4SAndroid Build Coastguard Worker       result = load_cacert_from_memory(store, ca_info_blob);
3198*6236dae4SAndroid Build Coastguard Worker       if(result) {
3199*6236dae4SAndroid Build Coastguard Worker         failf(data, "error importing CA certificate blob");
3200*6236dae4SAndroid Build Coastguard Worker         return result;
3201*6236dae4SAndroid Build Coastguard Worker       }
3202*6236dae4SAndroid Build Coastguard Worker       else {
3203*6236dae4SAndroid Build Coastguard Worker         imported_ca_info_blob = TRUE;
3204*6236dae4SAndroid Build Coastguard Worker         infof(data, "successfully imported CA certificate blob");
3205*6236dae4SAndroid Build Coastguard Worker       }
3206*6236dae4SAndroid Build Coastguard Worker     }
3207*6236dae4SAndroid Build Coastguard Worker 
3208*6236dae4SAndroid Build Coastguard Worker     if(ssl_cafile || ssl_capath) {
3209*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
3210*6236dae4SAndroid Build Coastguard Worker       /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */
3211*6236dae4SAndroid Build Coastguard Worker       if(ssl_cafile && !X509_STORE_load_file(store, ssl_cafile)) {
3212*6236dae4SAndroid Build Coastguard Worker         if(!imported_native_ca && !imported_ca_info_blob) {
3213*6236dae4SAndroid Build Coastguard Worker           /* Fail if we insist on successfully verifying the server. */
3214*6236dae4SAndroid Build Coastguard Worker           failf(data, "error setting certificate file: %s", ssl_cafile);
3215*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CACERT_BADFILE;
3216*6236dae4SAndroid Build Coastguard Worker         }
3217*6236dae4SAndroid Build Coastguard Worker         else
3218*6236dae4SAndroid Build Coastguard Worker           infof(data, "error setting certificate file, continuing anyway");
3219*6236dae4SAndroid Build Coastguard Worker       }
3220*6236dae4SAndroid Build Coastguard Worker       if(ssl_capath && !X509_STORE_load_path(store, ssl_capath)) {
3221*6236dae4SAndroid Build Coastguard Worker         if(!imported_native_ca && !imported_ca_info_blob) {
3222*6236dae4SAndroid Build Coastguard Worker           /* Fail if we insist on successfully verifying the server. */
3223*6236dae4SAndroid Build Coastguard Worker           failf(data, "error setting certificate path: %s", ssl_capath);
3224*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CACERT_BADFILE;
3225*6236dae4SAndroid Build Coastguard Worker         }
3226*6236dae4SAndroid Build Coastguard Worker         else
3227*6236dae4SAndroid Build Coastguard Worker           infof(data, "error setting certificate path, continuing anyway");
3228*6236dae4SAndroid Build Coastguard Worker       }
3229*6236dae4SAndroid Build Coastguard Worker #else
3230*6236dae4SAndroid Build Coastguard Worker       /* tell OpenSSL where to find CA certificates that are used to verify the
3231*6236dae4SAndroid Build Coastguard Worker          server's certificate. */
3232*6236dae4SAndroid Build Coastguard Worker       if(!X509_STORE_load_locations(store, ssl_cafile, ssl_capath)) {
3233*6236dae4SAndroid Build Coastguard Worker         if(!imported_native_ca && !imported_ca_info_blob) {
3234*6236dae4SAndroid Build Coastguard Worker           /* Fail if we insist on successfully verifying the server. */
3235*6236dae4SAndroid Build Coastguard Worker           failf(data, "error setting certificate verify locations:"
3236*6236dae4SAndroid Build Coastguard Worker                 "  CAfile: %s CApath: %s",
3237*6236dae4SAndroid Build Coastguard Worker                 ssl_cafile ? ssl_cafile : "none",
3238*6236dae4SAndroid Build Coastguard Worker                 ssl_capath ? ssl_capath : "none");
3239*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CACERT_BADFILE;
3240*6236dae4SAndroid Build Coastguard Worker         }
3241*6236dae4SAndroid Build Coastguard Worker         else {
3242*6236dae4SAndroid Build Coastguard Worker           infof(data, "error setting certificate verify locations,"
3243*6236dae4SAndroid Build Coastguard Worker                 " continuing anyway");
3244*6236dae4SAndroid Build Coastguard Worker         }
3245*6236dae4SAndroid Build Coastguard Worker       }
3246*6236dae4SAndroid Build Coastguard Worker #endif
3247*6236dae4SAndroid Build Coastguard Worker       infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
3248*6236dae4SAndroid Build Coastguard Worker       infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
3249*6236dae4SAndroid Build Coastguard Worker     }
3250*6236dae4SAndroid Build Coastguard Worker 
3251*6236dae4SAndroid Build Coastguard Worker #ifdef CURL_CA_FALLBACK
3252*6236dae4SAndroid Build Coastguard Worker     if(!ssl_cafile && !ssl_capath &&
3253*6236dae4SAndroid Build Coastguard Worker        !imported_native_ca && !imported_ca_info_blob) {
3254*6236dae4SAndroid Build Coastguard Worker       /* verifying the peer without any CA certificates will not
3255*6236dae4SAndroid Build Coastguard Worker          work so use OpenSSL's built-in default as fallback */
3256*6236dae4SAndroid Build Coastguard Worker       X509_STORE_set_default_paths(store);
3257*6236dae4SAndroid Build Coastguard Worker     }
3258*6236dae4SAndroid Build Coastguard Worker #endif
3259*6236dae4SAndroid Build Coastguard Worker   }
3260*6236dae4SAndroid Build Coastguard Worker 
3261*6236dae4SAndroid Build Coastguard Worker   if(ssl_crlfile) {
3262*6236dae4SAndroid Build Coastguard Worker     /* tell OpenSSL where to find CRL file that is used to check certificate
3263*6236dae4SAndroid Build Coastguard Worker      * revocation */
3264*6236dae4SAndroid Build Coastguard Worker     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
3265*6236dae4SAndroid Build Coastguard Worker     if(!lookup ||
3266*6236dae4SAndroid Build Coastguard Worker        (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
3267*6236dae4SAndroid Build Coastguard Worker       failf(data, "error loading CRL file: %s", ssl_crlfile);
3268*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CRL_BADFILE;
3269*6236dae4SAndroid Build Coastguard Worker     }
3270*6236dae4SAndroid Build Coastguard Worker     /* Everything is fine. */
3271*6236dae4SAndroid Build Coastguard Worker     infof(data, "successfully loaded CRL file:");
3272*6236dae4SAndroid Build Coastguard Worker     X509_STORE_set_flags(store,
3273*6236dae4SAndroid Build Coastguard Worker                          X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3274*6236dae4SAndroid Build Coastguard Worker 
3275*6236dae4SAndroid Build Coastguard Worker     infof(data, "  CRLfile: %s", ssl_crlfile);
3276*6236dae4SAndroid Build Coastguard Worker   }
3277*6236dae4SAndroid Build Coastguard Worker 
3278*6236dae4SAndroid Build Coastguard Worker   if(verifypeer) {
3279*6236dae4SAndroid Build Coastguard Worker     /* Try building a chain using issuers in the trusted store first to avoid
3280*6236dae4SAndroid Build Coastguard Worker        problems with server-sent legacy intermediates. Newer versions of
3281*6236dae4SAndroid Build Coastguard Worker        OpenSSL do alternate chain checking by default but we do not know how to
3282*6236dae4SAndroid Build Coastguard Worker        determine that in a reliable manner.
3283*6236dae4SAndroid Build Coastguard Worker        https://web.archive.org/web/20190422050538/
3284*6236dae4SAndroid Build Coastguard Worker        rt.openssl.org/Ticket/Display.html?id=3621
3285*6236dae4SAndroid Build Coastguard Worker     */
3286*6236dae4SAndroid Build Coastguard Worker #if defined(X509_V_FLAG_TRUSTED_FIRST)
3287*6236dae4SAndroid Build Coastguard Worker     X509_STORE_set_flags(store, X509_V_FLAG_TRUSTED_FIRST);
3288*6236dae4SAndroid Build Coastguard Worker #endif
3289*6236dae4SAndroid Build Coastguard Worker #ifdef X509_V_FLAG_PARTIAL_CHAIN
3290*6236dae4SAndroid Build Coastguard Worker     if(!ssl_config->no_partialchain && !ssl_crlfile) {
3291*6236dae4SAndroid Build Coastguard Worker       /* Have intermediate certificates in the trust store be treated as
3292*6236dae4SAndroid Build Coastguard Worker          trust-anchors, in the same way as self-signed root CA certificates
3293*6236dae4SAndroid Build Coastguard Worker          are. This allows users to verify servers using the intermediate cert
3294*6236dae4SAndroid Build Coastguard Worker          only, instead of needing the whole chain.
3295*6236dae4SAndroid Build Coastguard Worker 
3296*6236dae4SAndroid Build Coastguard Worker          Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we
3297*6236dae4SAndroid Build Coastguard Worker          cannot do partial chains with a CRL check.
3298*6236dae4SAndroid Build Coastguard Worker       */
3299*6236dae4SAndroid Build Coastguard Worker       X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN);
3300*6236dae4SAndroid Build Coastguard Worker     }
3301*6236dae4SAndroid Build Coastguard Worker #endif
3302*6236dae4SAndroid Build Coastguard Worker   }
3303*6236dae4SAndroid Build Coastguard Worker 
3304*6236dae4SAndroid Build Coastguard Worker   return result;
3305*6236dae4SAndroid Build Coastguard Worker }
3306*6236dae4SAndroid Build Coastguard Worker 
3307*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_SSL_X509_STORE_SHARE)
3308*6236dae4SAndroid Build Coastguard Worker 
3309*6236dae4SAndroid Build Coastguard Worker /* key to use at `multi->proto_hash` */
3310*6236dae4SAndroid Build Coastguard Worker #define MPROTO_OSSL_X509_KEY   "tls:ossl:x509:share"
3311*6236dae4SAndroid Build Coastguard Worker 
3312*6236dae4SAndroid Build Coastguard Worker struct ossl_x509_share {
3313*6236dae4SAndroid Build Coastguard Worker   char *CAfile;         /* CAfile path used to generate X509 store */
3314*6236dae4SAndroid Build Coastguard Worker   X509_STORE *store;    /* cached X509 store or NULL if none */
3315*6236dae4SAndroid Build Coastguard Worker   struct curltime time; /* when the cached store was created */
3316*6236dae4SAndroid Build Coastguard Worker };
3317*6236dae4SAndroid Build Coastguard Worker 
oss_x509_share_free(void * key,size_t key_len,void * p)3318*6236dae4SAndroid Build Coastguard Worker static void oss_x509_share_free(void *key, size_t key_len, void *p)
3319*6236dae4SAndroid Build Coastguard Worker {
3320*6236dae4SAndroid Build Coastguard Worker   struct ossl_x509_share *share = p;
3321*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(key_len == (sizeof(MPROTO_OSSL_X509_KEY)-1));
3322*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(!memcmp(MPROTO_OSSL_X509_KEY, key, key_len));
3323*6236dae4SAndroid Build Coastguard Worker   (void)key;
3324*6236dae4SAndroid Build Coastguard Worker   (void)key_len;
3325*6236dae4SAndroid Build Coastguard Worker   if(share->store) {
3326*6236dae4SAndroid Build Coastguard Worker     X509_STORE_free(share->store);
3327*6236dae4SAndroid Build Coastguard Worker   }
3328*6236dae4SAndroid Build Coastguard Worker   free(share->CAfile);
3329*6236dae4SAndroid Build Coastguard Worker   free(share);
3330*6236dae4SAndroid Build Coastguard Worker }
3331*6236dae4SAndroid Build Coastguard Worker 
3332*6236dae4SAndroid Build Coastguard Worker static bool
cached_x509_store_expired(const struct Curl_easy * data,const struct ossl_x509_share * mb)3333*6236dae4SAndroid Build Coastguard Worker cached_x509_store_expired(const struct Curl_easy *data,
3334*6236dae4SAndroid Build Coastguard Worker                           const struct ossl_x509_share *mb)
3335*6236dae4SAndroid Build Coastguard Worker {
3336*6236dae4SAndroid Build Coastguard Worker   const struct ssl_general_config *cfg = &data->set.general_ssl;
3337*6236dae4SAndroid Build Coastguard Worker   if(cfg->ca_cache_timeout < 0)
3338*6236dae4SAndroid Build Coastguard Worker     return FALSE;
3339*6236dae4SAndroid Build Coastguard Worker   else {
3340*6236dae4SAndroid Build Coastguard Worker     struct curltime now = Curl_now();
3341*6236dae4SAndroid Build Coastguard Worker     timediff_t elapsed_ms = Curl_timediff(now, mb->time);
3342*6236dae4SAndroid Build Coastguard Worker     timediff_t timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000;
3343*6236dae4SAndroid Build Coastguard Worker 
3344*6236dae4SAndroid Build Coastguard Worker     return elapsed_ms >= timeout_ms;
3345*6236dae4SAndroid Build Coastguard Worker   }
3346*6236dae4SAndroid Build Coastguard Worker }
3347*6236dae4SAndroid Build Coastguard Worker 
3348*6236dae4SAndroid Build Coastguard Worker static bool
cached_x509_store_different(struct Curl_cfilter * cf,const struct ossl_x509_share * mb)3349*6236dae4SAndroid Build Coastguard Worker cached_x509_store_different(struct Curl_cfilter *cf,
3350*6236dae4SAndroid Build Coastguard Worker                             const struct ossl_x509_share *mb)
3351*6236dae4SAndroid Build Coastguard Worker {
3352*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
3353*6236dae4SAndroid Build Coastguard Worker   if(!mb->CAfile || !conn_config->CAfile)
3354*6236dae4SAndroid Build Coastguard Worker     return mb->CAfile != conn_config->CAfile;
3355*6236dae4SAndroid Build Coastguard Worker 
3356*6236dae4SAndroid Build Coastguard Worker   return strcmp(mb->CAfile, conn_config->CAfile);
3357*6236dae4SAndroid Build Coastguard Worker }
3358*6236dae4SAndroid Build Coastguard Worker 
get_cached_x509_store(struct Curl_cfilter * cf,const struct Curl_easy * data)3359*6236dae4SAndroid Build Coastguard Worker static X509_STORE *get_cached_x509_store(struct Curl_cfilter *cf,
3360*6236dae4SAndroid Build Coastguard Worker                                          const struct Curl_easy *data)
3361*6236dae4SAndroid Build Coastguard Worker {
3362*6236dae4SAndroid Build Coastguard Worker   struct Curl_multi *multi = data->multi;
3363*6236dae4SAndroid Build Coastguard Worker   struct ossl_x509_share *share;
3364*6236dae4SAndroid Build Coastguard Worker   X509_STORE *store = NULL;
3365*6236dae4SAndroid Build Coastguard Worker 
3366*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(multi);
3367*6236dae4SAndroid Build Coastguard Worker   share = multi ? Curl_hash_pick(&multi->proto_hash,
3368*6236dae4SAndroid Build Coastguard Worker                                  (void *)MPROTO_OSSL_X509_KEY,
3369*6236dae4SAndroid Build Coastguard Worker                                  sizeof(MPROTO_OSSL_X509_KEY)-1) : NULL;
3370*6236dae4SAndroid Build Coastguard Worker   if(share && share->store &&
3371*6236dae4SAndroid Build Coastguard Worker      !cached_x509_store_expired(data, share) &&
3372*6236dae4SAndroid Build Coastguard Worker      !cached_x509_store_different(cf, share)) {
3373*6236dae4SAndroid Build Coastguard Worker     store = share->store;
3374*6236dae4SAndroid Build Coastguard Worker   }
3375*6236dae4SAndroid Build Coastguard Worker 
3376*6236dae4SAndroid Build Coastguard Worker   return store;
3377*6236dae4SAndroid Build Coastguard Worker }
3378*6236dae4SAndroid Build Coastguard Worker 
set_cached_x509_store(struct Curl_cfilter * cf,const struct Curl_easy * data,X509_STORE * store)3379*6236dae4SAndroid Build Coastguard Worker static void set_cached_x509_store(struct Curl_cfilter *cf,
3380*6236dae4SAndroid Build Coastguard Worker                                   const struct Curl_easy *data,
3381*6236dae4SAndroid Build Coastguard Worker                                   X509_STORE *store)
3382*6236dae4SAndroid Build Coastguard Worker {
3383*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
3384*6236dae4SAndroid Build Coastguard Worker   struct Curl_multi *multi = data->multi;
3385*6236dae4SAndroid Build Coastguard Worker   struct ossl_x509_share *share;
3386*6236dae4SAndroid Build Coastguard Worker 
3387*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(multi);
3388*6236dae4SAndroid Build Coastguard Worker   if(!multi)
3389*6236dae4SAndroid Build Coastguard Worker     return;
3390*6236dae4SAndroid Build Coastguard Worker   share = Curl_hash_pick(&multi->proto_hash,
3391*6236dae4SAndroid Build Coastguard Worker                          (void *)MPROTO_OSSL_X509_KEY,
3392*6236dae4SAndroid Build Coastguard Worker                          sizeof(MPROTO_OSSL_X509_KEY)-1);
3393*6236dae4SAndroid Build Coastguard Worker 
3394*6236dae4SAndroid Build Coastguard Worker   if(!share) {
3395*6236dae4SAndroid Build Coastguard Worker     share = calloc(1, sizeof(*share));
3396*6236dae4SAndroid Build Coastguard Worker     if(!share)
3397*6236dae4SAndroid Build Coastguard Worker       return;
3398*6236dae4SAndroid Build Coastguard Worker     if(!Curl_hash_add2(&multi->proto_hash,
3399*6236dae4SAndroid Build Coastguard Worker                        (void *)MPROTO_OSSL_X509_KEY,
3400*6236dae4SAndroid Build Coastguard Worker                        sizeof(MPROTO_OSSL_X509_KEY)-1,
3401*6236dae4SAndroid Build Coastguard Worker                        share, oss_x509_share_free)) {
3402*6236dae4SAndroid Build Coastguard Worker       free(share);
3403*6236dae4SAndroid Build Coastguard Worker       return;
3404*6236dae4SAndroid Build Coastguard Worker     }
3405*6236dae4SAndroid Build Coastguard Worker   }
3406*6236dae4SAndroid Build Coastguard Worker 
3407*6236dae4SAndroid Build Coastguard Worker   if(X509_STORE_up_ref(store)) {
3408*6236dae4SAndroid Build Coastguard Worker     char *CAfile = NULL;
3409*6236dae4SAndroid Build Coastguard Worker 
3410*6236dae4SAndroid Build Coastguard Worker     if(conn_config->CAfile) {
3411*6236dae4SAndroid Build Coastguard Worker       CAfile = strdup(conn_config->CAfile);
3412*6236dae4SAndroid Build Coastguard Worker       if(!CAfile) {
3413*6236dae4SAndroid Build Coastguard Worker         X509_STORE_free(store);
3414*6236dae4SAndroid Build Coastguard Worker         return;
3415*6236dae4SAndroid Build Coastguard Worker       }
3416*6236dae4SAndroid Build Coastguard Worker     }
3417*6236dae4SAndroid Build Coastguard Worker 
3418*6236dae4SAndroid Build Coastguard Worker     if(share->store) {
3419*6236dae4SAndroid Build Coastguard Worker       X509_STORE_free(share->store);
3420*6236dae4SAndroid Build Coastguard Worker       free(share->CAfile);
3421*6236dae4SAndroid Build Coastguard Worker     }
3422*6236dae4SAndroid Build Coastguard Worker 
3423*6236dae4SAndroid Build Coastguard Worker     share->time = Curl_now();
3424*6236dae4SAndroid Build Coastguard Worker     share->store = store;
3425*6236dae4SAndroid Build Coastguard Worker     share->CAfile = CAfile;
3426*6236dae4SAndroid Build Coastguard Worker   }
3427*6236dae4SAndroid Build Coastguard Worker }
3428*6236dae4SAndroid Build Coastguard Worker 
Curl_ssl_setup_x509_store(struct Curl_cfilter * cf,struct Curl_easy * data,SSL_CTX * ssl_ctx)3429*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
3430*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_easy *data,
3431*6236dae4SAndroid Build Coastguard Worker                                    SSL_CTX *ssl_ctx)
3432*6236dae4SAndroid Build Coastguard Worker {
3433*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
3434*6236dae4SAndroid Build Coastguard Worker   struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
3435*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
3436*6236dae4SAndroid Build Coastguard Worker   X509_STORE *cached_store;
3437*6236dae4SAndroid Build Coastguard Worker   bool cache_criteria_met;
3438*6236dae4SAndroid Build Coastguard Worker 
3439*6236dae4SAndroid Build Coastguard Worker   /* Consider the X509 store cacheable if it comes exclusively from a CAfile,
3440*6236dae4SAndroid Build Coastguard Worker      or no source is provided and we are falling back to OpenSSL's built-in
3441*6236dae4SAndroid Build Coastguard Worker      default. */
3442*6236dae4SAndroid Build Coastguard Worker   cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) &&
3443*6236dae4SAndroid Build Coastguard Worker     conn_config->verifypeer &&
3444*6236dae4SAndroid Build Coastguard Worker     !conn_config->CApath &&
3445*6236dae4SAndroid Build Coastguard Worker     !conn_config->ca_info_blob &&
3446*6236dae4SAndroid Build Coastguard Worker     !ssl_config->primary.CRLfile &&
3447*6236dae4SAndroid Build Coastguard Worker     !ssl_config->native_ca_store;
3448*6236dae4SAndroid Build Coastguard Worker 
3449*6236dae4SAndroid Build Coastguard Worker   cached_store = get_cached_x509_store(cf, data);
3450*6236dae4SAndroid Build Coastguard Worker   if(cached_store && cache_criteria_met && X509_STORE_up_ref(cached_store)) {
3451*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_set_cert_store(ssl_ctx, cached_store);
3452*6236dae4SAndroid Build Coastguard Worker   }
3453*6236dae4SAndroid Build Coastguard Worker   else {
3454*6236dae4SAndroid Build Coastguard Worker     X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
3455*6236dae4SAndroid Build Coastguard Worker 
3456*6236dae4SAndroid Build Coastguard Worker     result = populate_x509_store(cf, data, store);
3457*6236dae4SAndroid Build Coastguard Worker     if(result == CURLE_OK && cache_criteria_met) {
3458*6236dae4SAndroid Build Coastguard Worker       set_cached_x509_store(cf, data, store);
3459*6236dae4SAndroid Build Coastguard Worker     }
3460*6236dae4SAndroid Build Coastguard Worker   }
3461*6236dae4SAndroid Build Coastguard Worker 
3462*6236dae4SAndroid Build Coastguard Worker   return result;
3463*6236dae4SAndroid Build Coastguard Worker }
3464*6236dae4SAndroid Build Coastguard Worker #else /* HAVE_SSL_X509_STORE_SHARE */
Curl_ssl_setup_x509_store(struct Curl_cfilter * cf,struct Curl_easy * data,SSL_CTX * ssl_ctx)3465*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf,
3466*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_easy *data,
3467*6236dae4SAndroid Build Coastguard Worker                                    SSL_CTX *ssl_ctx)
3468*6236dae4SAndroid Build Coastguard Worker {
3469*6236dae4SAndroid Build Coastguard Worker   X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
3470*6236dae4SAndroid Build Coastguard Worker 
3471*6236dae4SAndroid Build Coastguard Worker   return populate_x509_store(cf, data, store);
3472*6236dae4SAndroid Build Coastguard Worker }
3473*6236dae4SAndroid Build Coastguard Worker #endif /* HAVE_SSL_X509_STORE_SHARE */
3474*6236dae4SAndroid Build Coastguard Worker 
Curl_ossl_ctx_init(struct ossl_ctx * octx,struct Curl_cfilter * cf,struct Curl_easy * data,struct ssl_peer * peer,int transport,const unsigned char * alpn,size_t alpn_len,Curl_ossl_ctx_setup_cb * cb_setup,void * cb_user_data,Curl_ossl_new_session_cb * cb_new_session,void * ssl_user_data)3475*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
3476*6236dae4SAndroid Build Coastguard Worker                             struct Curl_cfilter *cf,
3477*6236dae4SAndroid Build Coastguard Worker                             struct Curl_easy *data,
3478*6236dae4SAndroid Build Coastguard Worker                             struct ssl_peer *peer,
3479*6236dae4SAndroid Build Coastguard Worker                             int transport, /* TCP or QUIC */
3480*6236dae4SAndroid Build Coastguard Worker                             const unsigned char *alpn, size_t alpn_len,
3481*6236dae4SAndroid Build Coastguard Worker                             Curl_ossl_ctx_setup_cb *cb_setup,
3482*6236dae4SAndroid Build Coastguard Worker                             void *cb_user_data,
3483*6236dae4SAndroid Build Coastguard Worker                             Curl_ossl_new_session_cb *cb_new_session,
3484*6236dae4SAndroid Build Coastguard Worker                             void *ssl_user_data)
3485*6236dae4SAndroid Build Coastguard Worker {
3486*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
3487*6236dae4SAndroid Build Coastguard Worker   const char *ciphers;
3488*6236dae4SAndroid Build Coastguard Worker   SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
3489*6236dae4SAndroid Build Coastguard Worker   ctx_option_t ctx_options = 0;
3490*6236dae4SAndroid Build Coastguard Worker   SSL_SESSION *ssl_session = NULL;
3491*6236dae4SAndroid Build Coastguard Worker   const unsigned char *der_sessionid = NULL;
3492*6236dae4SAndroid Build Coastguard Worker   size_t der_sessionid_size = 0;
3493*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
3494*6236dae4SAndroid Build Coastguard Worker   struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
3495*6236dae4SAndroid Build Coastguard Worker   const long int ssl_version_min = conn_config->version;
3496*6236dae4SAndroid Build Coastguard Worker   char * const ssl_cert = ssl_config->primary.clientcert;
3497*6236dae4SAndroid Build Coastguard Worker   const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
3498*6236dae4SAndroid Build Coastguard Worker   const char * const ssl_cert_type = ssl_config->cert_type;
3499*6236dae4SAndroid Build Coastguard Worker   const bool verifypeer = conn_config->verifypeer;
3500*6236dae4SAndroid Build Coastguard Worker   char error_buffer[256];
3501*6236dae4SAndroid Build Coastguard Worker 
3502*6236dae4SAndroid Build Coastguard Worker   /* Make funny stuff to get random input */
3503*6236dae4SAndroid Build Coastguard Worker   result = ossl_seed(data);
3504*6236dae4SAndroid Build Coastguard Worker   if(result)
3505*6236dae4SAndroid Build Coastguard Worker     return result;
3506*6236dae4SAndroid Build Coastguard Worker 
3507*6236dae4SAndroid Build Coastguard Worker   ssl_config->certverifyresult = !X509_V_OK;
3508*6236dae4SAndroid Build Coastguard Worker 
3509*6236dae4SAndroid Build Coastguard Worker   switch(transport) {
3510*6236dae4SAndroid Build Coastguard Worker   case TRNSPRT_TCP:
3511*6236dae4SAndroid Build Coastguard Worker     /* check to see if we have been told to use an explicit SSL/TLS version */
3512*6236dae4SAndroid Build Coastguard Worker     switch(ssl_version_min) {
3513*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_DEFAULT:
3514*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_TLSv1:
3515*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_TLSv1_0:
3516*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_TLSv1_1:
3517*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_TLSv1_2:
3518*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_TLSv1_3:
3519*6236dae4SAndroid Build Coastguard Worker       /* it will be handled later with the context options */
3520*6236dae4SAndroid Build Coastguard Worker   #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
3521*6236dae4SAndroid Build Coastguard Worker       req_method = TLS_client_method();
3522*6236dae4SAndroid Build Coastguard Worker   #else
3523*6236dae4SAndroid Build Coastguard Worker       req_method = SSLv23_client_method();
3524*6236dae4SAndroid Build Coastguard Worker   #endif
3525*6236dae4SAndroid Build Coastguard Worker       break;
3526*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_SSLv2:
3527*6236dae4SAndroid Build Coastguard Worker       failf(data, "No SSLv2 support");
3528*6236dae4SAndroid Build Coastguard Worker       return CURLE_NOT_BUILT_IN;
3529*6236dae4SAndroid Build Coastguard Worker     case CURL_SSLVERSION_SSLv3:
3530*6236dae4SAndroid Build Coastguard Worker       failf(data, "No SSLv3 support");
3531*6236dae4SAndroid Build Coastguard Worker       return CURLE_NOT_BUILT_IN;
3532*6236dae4SAndroid Build Coastguard Worker     default:
3533*6236dae4SAndroid Build Coastguard Worker       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
3534*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
3535*6236dae4SAndroid Build Coastguard Worker     }
3536*6236dae4SAndroid Build Coastguard Worker     break;
3537*6236dae4SAndroid Build Coastguard Worker   case TRNSPRT_QUIC:
3538*6236dae4SAndroid Build Coastguard Worker     if(conn_config->version_max &&
3539*6236dae4SAndroid Build Coastguard Worker        (conn_config->version_max != CURL_SSLVERSION_MAX_TLSv1_3)) {
3540*6236dae4SAndroid Build Coastguard Worker       failf(data, "QUIC needs at least TLS version 1.3");
3541*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
3542*6236dae4SAndroid Build Coastguard Worker     }
3543*6236dae4SAndroid Build Coastguard Worker 
3544*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_QUIC
3545*6236dae4SAndroid Build Coastguard Worker     req_method = OSSL_QUIC_client_method();
3546*6236dae4SAndroid Build Coastguard Worker #elif (OPENSSL_VERSION_NUMBER >= 0x10100000L)
3547*6236dae4SAndroid Build Coastguard Worker     req_method = TLS_method();
3548*6236dae4SAndroid Build Coastguard Worker #else
3549*6236dae4SAndroid Build Coastguard Worker     req_method = SSLv23_client_method();
3550*6236dae4SAndroid Build Coastguard Worker #endif
3551*6236dae4SAndroid Build Coastguard Worker     break;
3552*6236dae4SAndroid Build Coastguard Worker   default:
3553*6236dae4SAndroid Build Coastguard Worker     failf(data, "unsupported transport %d in SSL init", transport);
3554*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_CONNECT_ERROR;
3555*6236dae4SAndroid Build Coastguard Worker   }
3556*6236dae4SAndroid Build Coastguard Worker 
3557*6236dae4SAndroid Build Coastguard Worker 
3558*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(!octx->ssl_ctx);
3559*6236dae4SAndroid Build Coastguard Worker   octx->ssl_ctx = SSL_CTX_new(req_method);
3560*6236dae4SAndroid Build Coastguard Worker 
3561*6236dae4SAndroid Build Coastguard Worker   if(!octx->ssl_ctx) {
3562*6236dae4SAndroid Build Coastguard Worker     failf(data, "SSL: could not create a context: %s",
3563*6236dae4SAndroid Build Coastguard Worker           ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
3564*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
3565*6236dae4SAndroid Build Coastguard Worker   }
3566*6236dae4SAndroid Build Coastguard Worker 
3567*6236dae4SAndroid Build Coastguard Worker   if(cb_setup) {
3568*6236dae4SAndroid Build Coastguard Worker     result = cb_setup(cf, data, cb_user_data);
3569*6236dae4SAndroid Build Coastguard Worker     if(result)
3570*6236dae4SAndroid Build Coastguard Worker       return result;
3571*6236dae4SAndroid Build Coastguard Worker   }
3572*6236dae4SAndroid Build Coastguard Worker 
3573*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_CTRL_SET_MSG_CALLBACK
3574*6236dae4SAndroid Build Coastguard Worker   if(data->set.fdebug && data->set.verbose) {
3575*6236dae4SAndroid Build Coastguard Worker     /* the SSL trace callback is only used for verbose logging */
3576*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_set_msg_callback(octx->ssl_ctx, ossl_trace);
3577*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_set_msg_callback_arg(octx->ssl_ctx, cf);
3578*6236dae4SAndroid Build Coastguard Worker   }
3579*6236dae4SAndroid Build Coastguard Worker #endif
3580*6236dae4SAndroid Build Coastguard Worker 
3581*6236dae4SAndroid Build Coastguard Worker   /* OpenSSL contains code to work around lots of bugs and flaws in various
3582*6236dae4SAndroid Build Coastguard Worker      SSL-implementations. SSL_CTX_set_options() is used to enabled those
3583*6236dae4SAndroid Build Coastguard Worker      work-arounds. The manpage for this option states that SSL_OP_ALL enables
3584*6236dae4SAndroid Build Coastguard Worker      all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
3585*6236dae4SAndroid Build Coastguard Worker      enable the bug workaround options if compatibility with somewhat broken
3586*6236dae4SAndroid Build Coastguard Worker      implementations is desired."
3587*6236dae4SAndroid Build Coastguard Worker 
3588*6236dae4SAndroid Build Coastguard Worker      The "-no_ticket" option was introduced in OpenSSL 0.9.8j. it is a flag to
3589*6236dae4SAndroid Build Coastguard Worker      disable "rfc4507bis session ticket support". rfc4507bis was later turned
3590*6236dae4SAndroid Build Coastguard Worker      into the proper RFC5077: https://datatracker.ietf.org/doc/html/rfc5077
3591*6236dae4SAndroid Build Coastguard Worker 
3592*6236dae4SAndroid Build Coastguard Worker      The enabled extension concerns the session management. I wonder how often
3593*6236dae4SAndroid Build Coastguard Worker      libcurl stops a connection and then resumes a TLS session. Also, sending
3594*6236dae4SAndroid Build Coastguard Worker      the session data is some overhead. I suggest that you just use your
3595*6236dae4SAndroid Build Coastguard Worker      proposed patch (which explicitly disables TICKET).
3596*6236dae4SAndroid Build Coastguard Worker 
3597*6236dae4SAndroid Build Coastguard Worker      If someone writes an application with libcurl and OpenSSL who wants to
3598*6236dae4SAndroid Build Coastguard Worker      enable the feature, one can do this in the SSL callback.
3599*6236dae4SAndroid Build Coastguard Worker 
3600*6236dae4SAndroid Build Coastguard Worker      SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
3601*6236dae4SAndroid Build Coastguard Worker      interoperability with web server Netscape Enterprise Server 2.0.1 which
3602*6236dae4SAndroid Build Coastguard Worker      was released back in 1996.
3603*6236dae4SAndroid Build Coastguard Worker 
3604*6236dae4SAndroid Build Coastguard Worker      Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
3605*6236dae4SAndroid Build Coastguard Worker      become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
3606*6236dae4SAndroid Build Coastguard Worker      CVE-2010-4180 when using previous OpenSSL versions we no longer enable
3607*6236dae4SAndroid Build Coastguard Worker      this option regardless of OpenSSL version and SSL_OP_ALL definition.
3608*6236dae4SAndroid Build Coastguard Worker 
3609*6236dae4SAndroid Build Coastguard Worker      OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability:
3610*6236dae4SAndroid Build Coastguard Worker      https://web.archive.org/web/20240114184648/openssl.org/~bodo/tls-cbc.txt.
3611*6236dae4SAndroid Build Coastguard Worker      In 0.9.6e they added a bit to SSL_OP_ALL that _disables_ that work-around
3612*6236dae4SAndroid Build Coastguard Worker      despite the fact that SSL_OP_ALL is documented to do "rather harmless"
3613*6236dae4SAndroid Build Coastguard Worker      workarounds. In order to keep the secure work-around, the
3614*6236dae4SAndroid Build Coastguard Worker      SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit must not be set.
3615*6236dae4SAndroid Build Coastguard Worker   */
3616*6236dae4SAndroid Build Coastguard Worker 
3617*6236dae4SAndroid Build Coastguard Worker   ctx_options = SSL_OP_ALL;
3618*6236dae4SAndroid Build Coastguard Worker 
3619*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_OP_NO_TICKET
3620*6236dae4SAndroid Build Coastguard Worker   ctx_options |= SSL_OP_NO_TICKET;
3621*6236dae4SAndroid Build Coastguard Worker #endif
3622*6236dae4SAndroid Build Coastguard Worker 
3623*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_OP_NO_COMPRESSION
3624*6236dae4SAndroid Build Coastguard Worker   ctx_options |= SSL_OP_NO_COMPRESSION;
3625*6236dae4SAndroid Build Coastguard Worker #endif
3626*6236dae4SAndroid Build Coastguard Worker 
3627*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
3628*6236dae4SAndroid Build Coastguard Worker   /* mitigate CVE-2010-4180 */
3629*6236dae4SAndroid Build Coastguard Worker   ctx_options &= ~(ctx_option_t)SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
3630*6236dae4SAndroid Build Coastguard Worker #endif
3631*6236dae4SAndroid Build Coastguard Worker 
3632*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
3633*6236dae4SAndroid Build Coastguard Worker   /* unless the user explicitly asks to allow the protocol vulnerability we
3634*6236dae4SAndroid Build Coastguard Worker      use the work-around */
3635*6236dae4SAndroid Build Coastguard Worker   if(!ssl_config->enable_beast)
3636*6236dae4SAndroid Build Coastguard Worker     ctx_options &= ~(ctx_option_t)SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
3637*6236dae4SAndroid Build Coastguard Worker #endif
3638*6236dae4SAndroid Build Coastguard Worker 
3639*6236dae4SAndroid Build Coastguard Worker   switch(ssl_version_min) {
3640*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_SSLv2:
3641*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_SSLv3:
3642*6236dae4SAndroid Build Coastguard Worker     return CURLE_NOT_BUILT_IN;
3643*6236dae4SAndroid Build Coastguard Worker 
3644*6236dae4SAndroid Build Coastguard Worker     /* "--tlsv<x.y>" options mean TLS >= version <x.y> */
3645*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_DEFAULT:
3646*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */
3647*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */
3648*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */
3649*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */
3650*6236dae4SAndroid Build Coastguard Worker   case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */
3651*6236dae4SAndroid Build Coastguard Worker     /* asking for any TLS version as the minimum, means no SSL versions
3652*6236dae4SAndroid Build Coastguard Worker        allowed */
3653*6236dae4SAndroid Build Coastguard Worker     ctx_options |= SSL_OP_NO_SSLv2;
3654*6236dae4SAndroid Build Coastguard Worker     ctx_options |= SSL_OP_NO_SSLv3;
3655*6236dae4SAndroid Build Coastguard Worker 
3656*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
3657*6236dae4SAndroid Build Coastguard Worker     result = ossl_set_ssl_version_min_max(cf, octx->ssl_ctx);
3658*6236dae4SAndroid Build Coastguard Worker #else
3659*6236dae4SAndroid Build Coastguard Worker     result = ossl_set_ssl_version_min_max_legacy(&ctx_options, cf, data);
3660*6236dae4SAndroid Build Coastguard Worker #endif
3661*6236dae4SAndroid Build Coastguard Worker     if(result != CURLE_OK)
3662*6236dae4SAndroid Build Coastguard Worker       return result;
3663*6236dae4SAndroid Build Coastguard Worker     break;
3664*6236dae4SAndroid Build Coastguard Worker 
3665*6236dae4SAndroid Build Coastguard Worker   default:
3666*6236dae4SAndroid Build Coastguard Worker     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
3667*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_CONNECT_ERROR;
3668*6236dae4SAndroid Build Coastguard Worker   }
3669*6236dae4SAndroid Build Coastguard Worker 
3670*6236dae4SAndroid Build Coastguard Worker   SSL_CTX_set_options(octx->ssl_ctx, ctx_options);
3671*6236dae4SAndroid Build Coastguard Worker 
3672*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
3673*6236dae4SAndroid Build Coastguard Worker   /* We do retry writes sometimes from another buffer address */
3674*6236dae4SAndroid Build Coastguard Worker   SSL_CTX_set_mode(octx->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3675*6236dae4SAndroid Build Coastguard Worker #endif
3676*6236dae4SAndroid Build Coastguard Worker 
3677*6236dae4SAndroid Build Coastguard Worker #ifdef HAS_ALPN
3678*6236dae4SAndroid Build Coastguard Worker   if(alpn && alpn_len) {
3679*6236dae4SAndroid Build Coastguard Worker     if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, alpn, (int)alpn_len)) {
3680*6236dae4SAndroid Build Coastguard Worker       failf(data, "Error setting ALPN");
3681*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
3682*6236dae4SAndroid Build Coastguard Worker     }
3683*6236dae4SAndroid Build Coastguard Worker   }
3684*6236dae4SAndroid Build Coastguard Worker #endif
3685*6236dae4SAndroid Build Coastguard Worker 
3686*6236dae4SAndroid Build Coastguard Worker   if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
3687*6236dae4SAndroid Build Coastguard Worker     if(!result &&
3688*6236dae4SAndroid Build Coastguard Worker        !cert_stuff(data, octx->ssl_ctx,
3689*6236dae4SAndroid Build Coastguard Worker                    ssl_cert, ssl_cert_blob, ssl_cert_type,
3690*6236dae4SAndroid Build Coastguard Worker                    ssl_config->key, ssl_config->key_blob,
3691*6236dae4SAndroid Build Coastguard Worker                    ssl_config->key_type, ssl_config->key_passwd))
3692*6236dae4SAndroid Build Coastguard Worker       result = CURLE_SSL_CERTPROBLEM;
3693*6236dae4SAndroid Build Coastguard Worker     if(result)
3694*6236dae4SAndroid Build Coastguard Worker       /* failf() is already done in cert_stuff() */
3695*6236dae4SAndroid Build Coastguard Worker       return result;
3696*6236dae4SAndroid Build Coastguard Worker   }
3697*6236dae4SAndroid Build Coastguard Worker 
3698*6236dae4SAndroid Build Coastguard Worker   ciphers = conn_config->cipher_list;
3699*6236dae4SAndroid Build Coastguard Worker   if(!ciphers && (peer->transport != TRNSPRT_QUIC))
3700*6236dae4SAndroid Build Coastguard Worker     ciphers = DEFAULT_CIPHER_SELECTION;
3701*6236dae4SAndroid Build Coastguard Worker   if(ciphers) {
3702*6236dae4SAndroid Build Coastguard Worker     if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, ciphers)) {
3703*6236dae4SAndroid Build Coastguard Worker       failf(data, "failed setting cipher list: %s", ciphers);
3704*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CIPHER;
3705*6236dae4SAndroid Build Coastguard Worker     }
3706*6236dae4SAndroid Build Coastguard Worker     infof(data, "Cipher selection: %s", ciphers);
3707*6236dae4SAndroid Build Coastguard Worker   }
3708*6236dae4SAndroid Build Coastguard Worker 
3709*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
3710*6236dae4SAndroid Build Coastguard Worker   {
3711*6236dae4SAndroid Build Coastguard Worker     const char *ciphers13 = conn_config->cipher_list13;
3712*6236dae4SAndroid Build Coastguard Worker     if(ciphers13) {
3713*6236dae4SAndroid Build Coastguard Worker       if(!SSL_CTX_set_ciphersuites(octx->ssl_ctx, ciphers13)) {
3714*6236dae4SAndroid Build Coastguard Worker         failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13);
3715*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CIPHER;
3716*6236dae4SAndroid Build Coastguard Worker       }
3717*6236dae4SAndroid Build Coastguard Worker       infof(data, "TLS 1.3 cipher selection: %s", ciphers13);
3718*6236dae4SAndroid Build Coastguard Worker     }
3719*6236dae4SAndroid Build Coastguard Worker   }
3720*6236dae4SAndroid Build Coastguard Worker #endif
3721*6236dae4SAndroid Build Coastguard Worker 
3722*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
3723*6236dae4SAndroid Build Coastguard Worker   /* OpenSSL 1.1.1 requires clients to opt-in for PHA */
3724*6236dae4SAndroid Build Coastguard Worker   SSL_CTX_set_post_handshake_auth(octx->ssl_ctx, 1);
3725*6236dae4SAndroid Build Coastguard Worker #endif
3726*6236dae4SAndroid Build Coastguard Worker 
3727*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SSL_CTX_SET_EC_CURVES
3728*6236dae4SAndroid Build Coastguard Worker   {
3729*6236dae4SAndroid Build Coastguard Worker     const char *curves = conn_config->curves;
3730*6236dae4SAndroid Build Coastguard Worker     if(curves) {
3731*6236dae4SAndroid Build Coastguard Worker       if(!SSL_CTX_set1_curves_list(octx->ssl_ctx, curves)) {
3732*6236dae4SAndroid Build Coastguard Worker         failf(data, "failed setting curves list: '%s'", curves);
3733*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CIPHER;
3734*6236dae4SAndroid Build Coastguard Worker       }
3735*6236dae4SAndroid Build Coastguard Worker     }
3736*6236dae4SAndroid Build Coastguard Worker   }
3737*6236dae4SAndroid Build Coastguard Worker #endif
3738*6236dae4SAndroid Build Coastguard Worker 
3739*6236dae4SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_SRP
3740*6236dae4SAndroid Build Coastguard Worker   if(ssl_config->primary.username && Curl_auth_allowed_to_host(data)) {
3741*6236dae4SAndroid Build Coastguard Worker     char * const ssl_username = ssl_config->primary.username;
3742*6236dae4SAndroid Build Coastguard Worker     char * const ssl_password = ssl_config->primary.password;
3743*6236dae4SAndroid Build Coastguard Worker     infof(data, "Using TLS-SRP username: %s", ssl_username);
3744*6236dae4SAndroid Build Coastguard Worker 
3745*6236dae4SAndroid Build Coastguard Worker     if(!SSL_CTX_set_srp_username(octx->ssl_ctx, ssl_username)) {
3746*6236dae4SAndroid Build Coastguard Worker       failf(data, "Unable to set SRP username");
3747*6236dae4SAndroid Build Coastguard Worker       return CURLE_BAD_FUNCTION_ARGUMENT;
3748*6236dae4SAndroid Build Coastguard Worker     }
3749*6236dae4SAndroid Build Coastguard Worker     if(!SSL_CTX_set_srp_password(octx->ssl_ctx, ssl_password)) {
3750*6236dae4SAndroid Build Coastguard Worker       failf(data, "failed setting SRP password");
3751*6236dae4SAndroid Build Coastguard Worker       return CURLE_BAD_FUNCTION_ARGUMENT;
3752*6236dae4SAndroid Build Coastguard Worker     }
3753*6236dae4SAndroid Build Coastguard Worker     if(!conn_config->cipher_list) {
3754*6236dae4SAndroid Build Coastguard Worker       infof(data, "Setting cipher list SRP");
3755*6236dae4SAndroid Build Coastguard Worker 
3756*6236dae4SAndroid Build Coastguard Worker       if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, "SRP")) {
3757*6236dae4SAndroid Build Coastguard Worker         failf(data, "failed setting SRP cipher list");
3758*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CIPHER;
3759*6236dae4SAndroid Build Coastguard Worker       }
3760*6236dae4SAndroid Build Coastguard Worker     }
3761*6236dae4SAndroid Build Coastguard Worker   }
3762*6236dae4SAndroid Build Coastguard Worker #endif
3763*6236dae4SAndroid Build Coastguard Worker 
3764*6236dae4SAndroid Build Coastguard Worker   /* OpenSSL always tries to verify the peer, this only says whether it should
3765*6236dae4SAndroid Build Coastguard Worker    * fail to connect if the verification fails, or if it should continue
3766*6236dae4SAndroid Build Coastguard Worker    * anyway. In the latter case the result of the verification is checked with
3767*6236dae4SAndroid Build Coastguard Worker    * SSL_get_verify_result() below. */
3768*6236dae4SAndroid Build Coastguard Worker   SSL_CTX_set_verify(octx->ssl_ctx,
3769*6236dae4SAndroid Build Coastguard Worker                      verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
3770*6236dae4SAndroid Build Coastguard Worker 
3771*6236dae4SAndroid Build Coastguard Worker   /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */
3772*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_KEYLOG_CALLBACK
3773*6236dae4SAndroid Build Coastguard Worker   if(Curl_tls_keylog_enabled()) {
3774*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_set_keylog_callback(octx->ssl_ctx, ossl_keylog_callback);
3775*6236dae4SAndroid Build Coastguard Worker   }
3776*6236dae4SAndroid Build Coastguard Worker #endif
3777*6236dae4SAndroid Build Coastguard Worker 
3778*6236dae4SAndroid Build Coastguard Worker   if(cb_new_session) {
3779*6236dae4SAndroid Build Coastguard Worker     /* Enable the session cache because it is a prerequisite for the
3780*6236dae4SAndroid Build Coastguard Worker      * "new session" callback. Use the "external storage" mode to prevent
3781*6236dae4SAndroid Build Coastguard Worker      * OpenSSL from creating an internal session cache.
3782*6236dae4SAndroid Build Coastguard Worker      */
3783*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_set_session_cache_mode(octx->ssl_ctx,
3784*6236dae4SAndroid Build Coastguard Worker                                    SSL_SESS_CACHE_CLIENT |
3785*6236dae4SAndroid Build Coastguard Worker                                    SSL_SESS_CACHE_NO_INTERNAL);
3786*6236dae4SAndroid Build Coastguard Worker     SSL_CTX_sess_set_new_cb(octx->ssl_ctx, cb_new_session);
3787*6236dae4SAndroid Build Coastguard Worker   }
3788*6236dae4SAndroid Build Coastguard Worker 
3789*6236dae4SAndroid Build Coastguard Worker   /* give application a chance to interfere with SSL set up. */
3790*6236dae4SAndroid Build Coastguard Worker   if(data->set.ssl.fsslctx) {
3791*6236dae4SAndroid Build Coastguard Worker     /* When a user callback is installed to modify the SSL_CTX,
3792*6236dae4SAndroid Build Coastguard Worker      * we need to do the full initialization before calling it.
3793*6236dae4SAndroid Build Coastguard Worker      * See: #11800 */
3794*6236dae4SAndroid Build Coastguard Worker     if(!octx->x509_store_setup) {
3795*6236dae4SAndroid Build Coastguard Worker       result = Curl_ssl_setup_x509_store(cf, data, octx->ssl_ctx);
3796*6236dae4SAndroid Build Coastguard Worker       if(result)
3797*6236dae4SAndroid Build Coastguard Worker         return result;
3798*6236dae4SAndroid Build Coastguard Worker       octx->x509_store_setup = TRUE;
3799*6236dae4SAndroid Build Coastguard Worker     }
3800*6236dae4SAndroid Build Coastguard Worker     Curl_set_in_callback(data, TRUE);
3801*6236dae4SAndroid Build Coastguard Worker     result = (*data->set.ssl.fsslctx)(data, octx->ssl_ctx,
3802*6236dae4SAndroid Build Coastguard Worker                                       data->set.ssl.fsslctxp);
3803*6236dae4SAndroid Build Coastguard Worker     Curl_set_in_callback(data, FALSE);
3804*6236dae4SAndroid Build Coastguard Worker     if(result) {
3805*6236dae4SAndroid Build Coastguard Worker       failf(data, "error signaled by ssl ctx callback");
3806*6236dae4SAndroid Build Coastguard Worker       return result;
3807*6236dae4SAndroid Build Coastguard Worker     }
3808*6236dae4SAndroid Build Coastguard Worker   }
3809*6236dae4SAndroid Build Coastguard Worker 
3810*6236dae4SAndroid Build Coastguard Worker   /* Let's make an SSL structure */
3811*6236dae4SAndroid Build Coastguard Worker   if(octx->ssl)
3812*6236dae4SAndroid Build Coastguard Worker     SSL_free(octx->ssl);
3813*6236dae4SAndroid Build Coastguard Worker   octx->ssl = SSL_new(octx->ssl_ctx);
3814*6236dae4SAndroid Build Coastguard Worker   if(!octx->ssl) {
3815*6236dae4SAndroid Build Coastguard Worker     failf(data, "SSL: could not create a context (handle)");
3816*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
3817*6236dae4SAndroid Build Coastguard Worker   }
3818*6236dae4SAndroid Build Coastguard Worker 
3819*6236dae4SAndroid Build Coastguard Worker   SSL_set_app_data(octx->ssl, ssl_user_data);
3820*6236dae4SAndroid Build Coastguard Worker 
3821*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
3822*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_OCSP)
3823*6236dae4SAndroid Build Coastguard Worker   if(conn_config->verifystatus)
3824*6236dae4SAndroid Build Coastguard Worker     SSL_set_tlsext_status_type(octx->ssl, TLSEXT_STATUSTYPE_ocsp);
3825*6236dae4SAndroid Build Coastguard Worker #endif
3826*6236dae4SAndroid Build Coastguard Worker 
3827*6236dae4SAndroid Build Coastguard Worker #if (defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)) && \
3828*6236dae4SAndroid Build Coastguard Worker     defined(ALLOW_RENEG)
3829*6236dae4SAndroid Build Coastguard Worker   SSL_set_renegotiate_mode(octx->ssl, ssl_renegotiate_freely);
3830*6236dae4SAndroid Build Coastguard Worker #endif
3831*6236dae4SAndroid Build Coastguard Worker 
3832*6236dae4SAndroid Build Coastguard Worker   SSL_set_connect_state(octx->ssl);
3833*6236dae4SAndroid Build Coastguard Worker 
3834*6236dae4SAndroid Build Coastguard Worker   octx->server_cert = 0x0;
3835*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3836*6236dae4SAndroid Build Coastguard Worker   if(peer->sni) {
3837*6236dae4SAndroid Build Coastguard Worker     if(!SSL_set_tlsext_host_name(octx->ssl, peer->sni)) {
3838*6236dae4SAndroid Build Coastguard Worker       failf(data, "Failed set SNI");
3839*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
3840*6236dae4SAndroid Build Coastguard Worker     }
3841*6236dae4SAndroid Build Coastguard Worker   }
3842*6236dae4SAndroid Build Coastguard Worker 
3843*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
3844*6236dae4SAndroid Build Coastguard Worker   if(ECH_ENABLED(data)) {
3845*6236dae4SAndroid Build Coastguard Worker     unsigned char *ech_config = NULL;
3846*6236dae4SAndroid Build Coastguard Worker     size_t ech_config_len = 0;
3847*6236dae4SAndroid Build Coastguard Worker     char *outername = data->set.str[STRING_ECH_PUBLIC];
3848*6236dae4SAndroid Build Coastguard Worker     int trying_ech_now = 0;
3849*6236dae4SAndroid Build Coastguard Worker 
3850*6236dae4SAndroid Build Coastguard Worker     if(data->set.tls_ech & CURLECH_GREASE) {
3851*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: will GREASE ClientHello");
3852*6236dae4SAndroid Build Coastguard Worker # ifdef OPENSSL_IS_BORINGSSL
3853*6236dae4SAndroid Build Coastguard Worker       SSL_set_enable_ech_grease(octx->ssl, 1);
3854*6236dae4SAndroid Build Coastguard Worker # else
3855*6236dae4SAndroid Build Coastguard Worker       SSL_set_options(octx->ssl, SSL_OP_ECH_GREASE);
3856*6236dae4SAndroid Build Coastguard Worker # endif
3857*6236dae4SAndroid Build Coastguard Worker     }
3858*6236dae4SAndroid Build Coastguard Worker     else if(data->set.tls_ech & CURLECH_CLA_CFG) {
3859*6236dae4SAndroid Build Coastguard Worker # ifdef OPENSSL_IS_BORINGSSL
3860*6236dae4SAndroid Build Coastguard Worker       /* have to do base64 decode here for boring */
3861*6236dae4SAndroid Build Coastguard Worker       const char *b64 = data->set.str[STRING_ECH_CONFIG];
3862*6236dae4SAndroid Build Coastguard Worker 
3863*6236dae4SAndroid Build Coastguard Worker       if(!b64) {
3864*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: ECHConfig from command line empty");
3865*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CONNECT_ERROR;
3866*6236dae4SAndroid Build Coastguard Worker       }
3867*6236dae4SAndroid Build Coastguard Worker       ech_config_len = 2 * strlen(b64);
3868*6236dae4SAndroid Build Coastguard Worker       result = Curl_base64_decode(b64, &ech_config, &ech_config_len);
3869*6236dae4SAndroid Build Coastguard Worker       if(result || !ech_config) {
3870*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: cannot base64 decode ECHConfig from command line");
3871*6236dae4SAndroid Build Coastguard Worker         if(data->set.tls_ech & CURLECH_HARD)
3872*6236dae4SAndroid Build Coastguard Worker           return result;
3873*6236dae4SAndroid Build Coastguard Worker       }
3874*6236dae4SAndroid Build Coastguard Worker       if(SSL_set1_ech_config_list(octx->ssl, ech_config,
3875*6236dae4SAndroid Build Coastguard Worker                                   ech_config_len) != 1) {
3876*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: SSL_ECH_set1_echconfig failed");
3877*6236dae4SAndroid Build Coastguard Worker         if(data->set.tls_ech & CURLECH_HARD) {
3878*6236dae4SAndroid Build Coastguard Worker           free(ech_config);
3879*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CONNECT_ERROR;
3880*6236dae4SAndroid Build Coastguard Worker         }
3881*6236dae4SAndroid Build Coastguard Worker       }
3882*6236dae4SAndroid Build Coastguard Worker       free(ech_config);
3883*6236dae4SAndroid Build Coastguard Worker       trying_ech_now = 1;
3884*6236dae4SAndroid Build Coastguard Worker # else
3885*6236dae4SAndroid Build Coastguard Worker       ech_config = (unsigned char *) data->set.str[STRING_ECH_CONFIG];
3886*6236dae4SAndroid Build Coastguard Worker       if(!ech_config) {
3887*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: ECHConfig from command line empty");
3888*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CONNECT_ERROR;
3889*6236dae4SAndroid Build Coastguard Worker       }
3890*6236dae4SAndroid Build Coastguard Worker       ech_config_len = strlen(data->set.str[STRING_ECH_CONFIG]);
3891*6236dae4SAndroid Build Coastguard Worker       if(SSL_ech_set1_echconfig(octx->ssl, ech_config, ech_config_len) != 1) {
3892*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: SSL_ECH_set1_echconfig failed");
3893*6236dae4SAndroid Build Coastguard Worker         if(data->set.tls_ech & CURLECH_HARD)
3894*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CONNECT_ERROR;
3895*6236dae4SAndroid Build Coastguard Worker       }
3896*6236dae4SAndroid Build Coastguard Worker       else
3897*6236dae4SAndroid Build Coastguard Worker         trying_ech_now = 1;
3898*6236dae4SAndroid Build Coastguard Worker # endif
3899*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: ECHConfig from command line");
3900*6236dae4SAndroid Build Coastguard Worker     }
3901*6236dae4SAndroid Build Coastguard Worker     else {
3902*6236dae4SAndroid Build Coastguard Worker       struct Curl_dns_entry *dns = NULL;
3903*6236dae4SAndroid Build Coastguard Worker 
3904*6236dae4SAndroid Build Coastguard Worker       if(peer->hostname)
3905*6236dae4SAndroid Build Coastguard Worker         dns = Curl_fetch_addr(data, peer->hostname, peer->port);
3906*6236dae4SAndroid Build Coastguard Worker       if(!dns) {
3907*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: requested but no DNS info available");
3908*6236dae4SAndroid Build Coastguard Worker         if(data->set.tls_ech & CURLECH_HARD)
3909*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CONNECT_ERROR;
3910*6236dae4SAndroid Build Coastguard Worker       }
3911*6236dae4SAndroid Build Coastguard Worker       else {
3912*6236dae4SAndroid Build Coastguard Worker         struct Curl_https_rrinfo *rinfo = NULL;
3913*6236dae4SAndroid Build Coastguard Worker 
3914*6236dae4SAndroid Build Coastguard Worker         rinfo = dns->hinfo;
3915*6236dae4SAndroid Build Coastguard Worker         if(rinfo && rinfo->echconfiglist) {
3916*6236dae4SAndroid Build Coastguard Worker           unsigned char *ecl = rinfo->echconfiglist;
3917*6236dae4SAndroid Build Coastguard Worker           size_t elen = rinfo->echconfiglist_len;
3918*6236dae4SAndroid Build Coastguard Worker 
3919*6236dae4SAndroid Build Coastguard Worker           infof(data, "ECH: ECHConfig from DoH HTTPS RR");
3920*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
3921*6236dae4SAndroid Build Coastguard Worker           if(SSL_ech_set1_echconfig(octx->ssl, ecl, elen) != 1) {
3922*6236dae4SAndroid Build Coastguard Worker             infof(data, "ECH: SSL_ECH_set1_echconfig failed");
3923*6236dae4SAndroid Build Coastguard Worker             if(data->set.tls_ech & CURLECH_HARD)
3924*6236dae4SAndroid Build Coastguard Worker               return CURLE_SSL_CONNECT_ERROR;
3925*6236dae4SAndroid Build Coastguard Worker           }
3926*6236dae4SAndroid Build Coastguard Worker # else
3927*6236dae4SAndroid Build Coastguard Worker           if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) {
3928*6236dae4SAndroid Build Coastguard Worker             infof(data, "ECH: SSL_set1_ech_config_list failed (boring)");
3929*6236dae4SAndroid Build Coastguard Worker             if(data->set.tls_ech & CURLECH_HARD)
3930*6236dae4SAndroid Build Coastguard Worker               return CURLE_SSL_CONNECT_ERROR;
3931*6236dae4SAndroid Build Coastguard Worker           }
3932*6236dae4SAndroid Build Coastguard Worker # endif
3933*6236dae4SAndroid Build Coastguard Worker           else {
3934*6236dae4SAndroid Build Coastguard Worker             trying_ech_now = 1;
3935*6236dae4SAndroid Build Coastguard Worker             infof(data, "ECH: imported ECHConfigList of length %zu", elen);
3936*6236dae4SAndroid Build Coastguard Worker           }
3937*6236dae4SAndroid Build Coastguard Worker         }
3938*6236dae4SAndroid Build Coastguard Worker         else {
3939*6236dae4SAndroid Build Coastguard Worker           infof(data, "ECH: requested but no ECHConfig available");
3940*6236dae4SAndroid Build Coastguard Worker           if(data->set.tls_ech & CURLECH_HARD)
3941*6236dae4SAndroid Build Coastguard Worker             return CURLE_SSL_CONNECT_ERROR;
3942*6236dae4SAndroid Build Coastguard Worker         }
3943*6236dae4SAndroid Build Coastguard Worker         Curl_resolv_unlink(data, &dns);
3944*6236dae4SAndroid Build Coastguard Worker       }
3945*6236dae4SAndroid Build Coastguard Worker     }
3946*6236dae4SAndroid Build Coastguard Worker # ifdef OPENSSL_IS_BORINGSSL
3947*6236dae4SAndroid Build Coastguard Worker     if(trying_ech_now && outername) {
3948*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: setting public_name not supported with BoringSSL");
3949*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
3950*6236dae4SAndroid Build Coastguard Worker     }
3951*6236dae4SAndroid Build Coastguard Worker # else
3952*6236dae4SAndroid Build Coastguard Worker     if(trying_ech_now && outername) {
3953*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: inner: '%s', outer: '%s'",
3954*6236dae4SAndroid Build Coastguard Worker             peer->hostname ? peer->hostname : "NULL", outername);
3955*6236dae4SAndroid Build Coastguard Worker       result = SSL_ech_set_server_names(octx->ssl,
3956*6236dae4SAndroid Build Coastguard Worker                                         peer->hostname, outername,
3957*6236dae4SAndroid Build Coastguard Worker                                         0 /* do send outer */);
3958*6236dae4SAndroid Build Coastguard Worker       if(result != 1) {
3959*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: rv failed to set server name(s) %d [ERROR]", result);
3960*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CONNECT_ERROR;
3961*6236dae4SAndroid Build Coastguard Worker       }
3962*6236dae4SAndroid Build Coastguard Worker     }
3963*6236dae4SAndroid Build Coastguard Worker # endif  /* not BORING */
3964*6236dae4SAndroid Build Coastguard Worker     if(trying_ech_now
3965*6236dae4SAndroid Build Coastguard Worker        && SSL_set_min_proto_version(octx->ssl, TLS1_3_VERSION) != 1) {
3966*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: cannot force TLSv1.3 [ERROR]");
3967*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
3968*6236dae4SAndroid Build Coastguard Worker     }
3969*6236dae4SAndroid Build Coastguard Worker   }
3970*6236dae4SAndroid Build Coastguard Worker #endif  /* USE_ECH */
3971*6236dae4SAndroid Build Coastguard Worker 
3972*6236dae4SAndroid Build Coastguard Worker #endif
3973*6236dae4SAndroid Build Coastguard Worker 
3974*6236dae4SAndroid Build Coastguard Worker   octx->reused_session = FALSE;
3975*6236dae4SAndroid Build Coastguard Worker   if(ssl_config->primary.cache_session) {
3976*6236dae4SAndroid Build Coastguard Worker     Curl_ssl_sessionid_lock(data);
3977*6236dae4SAndroid Build Coastguard Worker     if(!Curl_ssl_getsessionid(cf, data, peer, (void **)&der_sessionid,
3978*6236dae4SAndroid Build Coastguard Worker       &der_sessionid_size, NULL)) {
3979*6236dae4SAndroid Build Coastguard Worker       /* we got a session id, use it! */
3980*6236dae4SAndroid Build Coastguard Worker       ssl_session = d2i_SSL_SESSION(NULL, &der_sessionid,
3981*6236dae4SAndroid Build Coastguard Worker         (long)der_sessionid_size);
3982*6236dae4SAndroid Build Coastguard Worker       if(ssl_session) {
3983*6236dae4SAndroid Build Coastguard Worker         if(!SSL_set_session(octx->ssl, ssl_session)) {
3984*6236dae4SAndroid Build Coastguard Worker           Curl_ssl_sessionid_unlock(data);
3985*6236dae4SAndroid Build Coastguard Worker           SSL_SESSION_free(ssl_session);
3986*6236dae4SAndroid Build Coastguard Worker           failf(data, "SSL: SSL_set_session failed: %s",
3987*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
3988*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)));
3989*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_CONNECT_ERROR;
3990*6236dae4SAndroid Build Coastguard Worker         }
3991*6236dae4SAndroid Build Coastguard Worker         SSL_SESSION_free(ssl_session);
3992*6236dae4SAndroid Build Coastguard Worker         /* Informational message */
3993*6236dae4SAndroid Build Coastguard Worker         infof(data, "SSL reusing session ID");
3994*6236dae4SAndroid Build Coastguard Worker         octx->reused_session = TRUE;
3995*6236dae4SAndroid Build Coastguard Worker       }
3996*6236dae4SAndroid Build Coastguard Worker       else {
3997*6236dae4SAndroid Build Coastguard Worker         Curl_ssl_sessionid_unlock(data);
3998*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CONNECT_ERROR;
3999*6236dae4SAndroid Build Coastguard Worker       }
4000*6236dae4SAndroid Build Coastguard Worker     }
4001*6236dae4SAndroid Build Coastguard Worker     Curl_ssl_sessionid_unlock(data);
4002*6236dae4SAndroid Build Coastguard Worker   }
4003*6236dae4SAndroid Build Coastguard Worker 
4004*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
4005*6236dae4SAndroid Build Coastguard Worker }
4006*6236dae4SAndroid Build Coastguard Worker 
ossl_connect_step1(struct Curl_cfilter * cf,struct Curl_easy * data)4007*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
4008*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_easy *data)
4009*6236dae4SAndroid Build Coastguard Worker {
4010*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
4011*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
4012*6236dae4SAndroid Build Coastguard Worker   struct alpn_proto_buf proto;
4013*6236dae4SAndroid Build Coastguard Worker   BIO *bio;
4014*6236dae4SAndroid Build Coastguard Worker   CURLcode result;
4015*6236dae4SAndroid Build Coastguard Worker 
4016*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
4017*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
4018*6236dae4SAndroid Build Coastguard Worker   memset(&proto, 0, sizeof(proto));
4019*6236dae4SAndroid Build Coastguard Worker #ifdef HAS_ALPN
4020*6236dae4SAndroid Build Coastguard Worker   if(connssl->alpn) {
4021*6236dae4SAndroid Build Coastguard Worker     result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
4022*6236dae4SAndroid Build Coastguard Worker     if(result) {
4023*6236dae4SAndroid Build Coastguard Worker       failf(data, "Error determining ALPN");
4024*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_CONNECT_ERROR;
4025*6236dae4SAndroid Build Coastguard Worker     }
4026*6236dae4SAndroid Build Coastguard Worker   }
4027*6236dae4SAndroid Build Coastguard Worker #endif
4028*6236dae4SAndroid Build Coastguard Worker 
4029*6236dae4SAndroid Build Coastguard Worker   result = Curl_ossl_ctx_init(octx, cf, data, &connssl->peer, TRNSPRT_TCP,
4030*6236dae4SAndroid Build Coastguard Worker                               proto.data, proto.len, NULL, NULL,
4031*6236dae4SAndroid Build Coastguard Worker                               ossl_new_session_cb, cf);
4032*6236dae4SAndroid Build Coastguard Worker   if(result)
4033*6236dae4SAndroid Build Coastguard Worker     return result;
4034*6236dae4SAndroid Build Coastguard Worker 
4035*6236dae4SAndroid Build Coastguard Worker   octx->bio_method = ossl_bio_cf_method_create();
4036*6236dae4SAndroid Build Coastguard Worker   if(!octx->bio_method)
4037*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
4038*6236dae4SAndroid Build Coastguard Worker   bio = BIO_new(octx->bio_method);
4039*6236dae4SAndroid Build Coastguard Worker   if(!bio)
4040*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
4041*6236dae4SAndroid Build Coastguard Worker 
4042*6236dae4SAndroid Build Coastguard Worker   BIO_set_data(bio, cf);
4043*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SSL_SET0_WBIO
4044*6236dae4SAndroid Build Coastguard Worker   /* with OpenSSL v1.1.1 we get an alternative to SSL_set_bio() that works
4045*6236dae4SAndroid Build Coastguard Worker    * without backward compat quirks. Every call takes one reference, so we
4046*6236dae4SAndroid Build Coastguard Worker    * up it and pass. SSL* then owns it and will free.
4047*6236dae4SAndroid Build Coastguard Worker    * We check on the function in configure, since LibreSSL and friends
4048*6236dae4SAndroid Build Coastguard Worker    * each have their own versions to add support for this. */
4049*6236dae4SAndroid Build Coastguard Worker   BIO_up_ref(bio);
4050*6236dae4SAndroid Build Coastguard Worker   SSL_set0_rbio(octx->ssl, bio);
4051*6236dae4SAndroid Build Coastguard Worker   SSL_set0_wbio(octx->ssl, bio);
4052*6236dae4SAndroid Build Coastguard Worker #else
4053*6236dae4SAndroid Build Coastguard Worker   SSL_set_bio(octx->ssl, bio, bio);
4054*6236dae4SAndroid Build Coastguard Worker #endif
4055*6236dae4SAndroid Build Coastguard Worker 
4056*6236dae4SAndroid Build Coastguard Worker #ifdef HAS_ALPN
4057*6236dae4SAndroid Build Coastguard Worker   if(connssl->alpn) {
4058*6236dae4SAndroid Build Coastguard Worker     Curl_alpn_to_proto_str(&proto, connssl->alpn);
4059*6236dae4SAndroid Build Coastguard Worker     infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
4060*6236dae4SAndroid Build Coastguard Worker   }
4061*6236dae4SAndroid Build Coastguard Worker #endif
4062*6236dae4SAndroid Build Coastguard Worker   connssl->connecting_state = ssl_connect_2;
4063*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
4064*6236dae4SAndroid Build Coastguard Worker }
4065*6236dae4SAndroid Build Coastguard Worker 
4066*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
4067*6236dae4SAndroid Build Coastguard Worker /* If we have retry configs, then trace those out */
ossl_trace_ech_retry_configs(struct Curl_easy * data,SSL * ssl,int reason)4068*6236dae4SAndroid Build Coastguard Worker static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
4069*6236dae4SAndroid Build Coastguard Worker                                          int reason)
4070*6236dae4SAndroid Build Coastguard Worker {
4071*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
4072*6236dae4SAndroid Build Coastguard Worker   size_t rcl = 0;
4073*6236dae4SAndroid Build Coastguard Worker   int rv = 1;
4074*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
4075*6236dae4SAndroid Build Coastguard Worker   char *inner = NULL;
4076*6236dae4SAndroid Build Coastguard Worker   unsigned char *rcs = NULL;
4077*6236dae4SAndroid Build Coastguard Worker   char *outer = NULL;
4078*6236dae4SAndroid Build Coastguard Worker # else
4079*6236dae4SAndroid Build Coastguard Worker   const char *inner = NULL;
4080*6236dae4SAndroid Build Coastguard Worker   const uint8_t *rcs = NULL;
4081*6236dae4SAndroid Build Coastguard Worker   const char *outer = NULL;
4082*6236dae4SAndroid Build Coastguard Worker   size_t out_name_len = 0;
4083*6236dae4SAndroid Build Coastguard Worker   int servername_type = 0;
4084*6236dae4SAndroid Build Coastguard Worker # endif
4085*6236dae4SAndroid Build Coastguard Worker 
4086*6236dae4SAndroid Build Coastguard Worker   /* nothing to trace if not doing ECH */
4087*6236dae4SAndroid Build Coastguard Worker   if(!ECH_ENABLED(data))
4088*6236dae4SAndroid Build Coastguard Worker     return;
4089*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
4090*6236dae4SAndroid Build Coastguard Worker   rv = SSL_ech_get_retry_config(ssl, &rcs, &rcl);
4091*6236dae4SAndroid Build Coastguard Worker # else
4092*6236dae4SAndroid Build Coastguard Worker   SSL_get0_ech_retry_configs(ssl, &rcs, &rcl);
4093*6236dae4SAndroid Build Coastguard Worker   rv = (int)rcl;
4094*6236dae4SAndroid Build Coastguard Worker # endif
4095*6236dae4SAndroid Build Coastguard Worker 
4096*6236dae4SAndroid Build Coastguard Worker   if(rv && rcs) {
4097*6236dae4SAndroid Build Coastguard Worker # define HEXSTR_MAX 800
4098*6236dae4SAndroid Build Coastguard Worker     char *b64str = NULL;
4099*6236dae4SAndroid Build Coastguard Worker     size_t blen = 0;
4100*6236dae4SAndroid Build Coastguard Worker 
4101*6236dae4SAndroid Build Coastguard Worker     result = Curl_base64_encode((const char *)rcs, rcl,
4102*6236dae4SAndroid Build Coastguard Worker                                 &b64str, &blen);
4103*6236dae4SAndroid Build Coastguard Worker     if(!result && b64str)
4104*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: retry_configs %s", b64str);
4105*6236dae4SAndroid Build Coastguard Worker     free(b64str);
4106*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
4107*6236dae4SAndroid Build Coastguard Worker     rv = SSL_ech_get_status(ssl, &inner, &outer);
4108*6236dae4SAndroid Build Coastguard Worker     infof(data, "ECH: retry_configs for %s from %s, %d %d",
4109*6236dae4SAndroid Build Coastguard Worker           inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
4110*6236dae4SAndroid Build Coastguard Worker #else
4111*6236dae4SAndroid Build Coastguard Worker     rv = SSL_ech_accepted(ssl);
4112*6236dae4SAndroid Build Coastguard Worker     servername_type = SSL_get_servername_type(ssl);
4113*6236dae4SAndroid Build Coastguard Worker     inner = SSL_get_servername(ssl, servername_type);
4114*6236dae4SAndroid Build Coastguard Worker     SSL_get0_ech_name_override(ssl, &outer, &out_name_len);
4115*6236dae4SAndroid Build Coastguard Worker     /* TODO: get the inner from boring */
4116*6236dae4SAndroid Build Coastguard Worker     infof(data, "ECH: retry_configs for %s from %s, %d %d",
4117*6236dae4SAndroid Build Coastguard Worker           inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
4118*6236dae4SAndroid Build Coastguard Worker #endif
4119*6236dae4SAndroid Build Coastguard Worker   }
4120*6236dae4SAndroid Build Coastguard Worker   else
4121*6236dae4SAndroid Build Coastguard Worker     infof(data, "ECH: no retry_configs (rv = %d)", rv);
4122*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
4123*6236dae4SAndroid Build Coastguard Worker   OPENSSL_free((void *)rcs);
4124*6236dae4SAndroid Build Coastguard Worker # endif
4125*6236dae4SAndroid Build Coastguard Worker   return;
4126*6236dae4SAndroid Build Coastguard Worker }
4127*6236dae4SAndroid Build Coastguard Worker 
4128*6236dae4SAndroid Build Coastguard Worker #endif
4129*6236dae4SAndroid Build Coastguard Worker 
ossl_connect_step2(struct Curl_cfilter * cf,struct Curl_easy * data)4130*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
4131*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_easy *data)
4132*6236dae4SAndroid Build Coastguard Worker {
4133*6236dae4SAndroid Build Coastguard Worker   int err;
4134*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
4135*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
4136*6236dae4SAndroid Build Coastguard Worker   struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
4137*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state);
4138*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
4139*6236dae4SAndroid Build Coastguard Worker 
4140*6236dae4SAndroid Build Coastguard Worker   connssl->io_need = CURL_SSL_IO_NEED_NONE;
4141*6236dae4SAndroid Build Coastguard Worker   ERR_clear_error();
4142*6236dae4SAndroid Build Coastguard Worker 
4143*6236dae4SAndroid Build Coastguard Worker   err = SSL_connect(octx->ssl);
4144*6236dae4SAndroid Build Coastguard Worker 
4145*6236dae4SAndroid Build Coastguard Worker   if(!octx->x509_store_setup) {
4146*6236dae4SAndroid Build Coastguard Worker     /* After having send off the ClientHello, we prepare the x509
4147*6236dae4SAndroid Build Coastguard Worker      * store to verify the coming certificate from the server */
4148*6236dae4SAndroid Build Coastguard Worker     CURLcode result = Curl_ssl_setup_x509_store(cf, data, octx->ssl_ctx);
4149*6236dae4SAndroid Build Coastguard Worker     if(result)
4150*6236dae4SAndroid Build Coastguard Worker       return result;
4151*6236dae4SAndroid Build Coastguard Worker     octx->x509_store_setup = TRUE;
4152*6236dae4SAndroid Build Coastguard Worker   }
4153*6236dae4SAndroid Build Coastguard Worker 
4154*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_KEYLOG_CALLBACK
4155*6236dae4SAndroid Build Coastguard Worker   /* If key logging is enabled, wait for the handshake to complete and then
4156*6236dae4SAndroid Build Coastguard Worker    * proceed with logging secrets (for TLS 1.2 or older).
4157*6236dae4SAndroid Build Coastguard Worker    */
4158*6236dae4SAndroid Build Coastguard Worker   if(Curl_tls_keylog_enabled() && !octx->keylog_done)
4159*6236dae4SAndroid Build Coastguard Worker     ossl_log_tls12_secret(octx->ssl, &octx->keylog_done);
4160*6236dae4SAndroid Build Coastguard Worker #endif
4161*6236dae4SAndroid Build Coastguard Worker 
4162*6236dae4SAndroid Build Coastguard Worker   /* 1  is fine
4163*6236dae4SAndroid Build Coastguard Worker      0  is "not successful but was shut down controlled"
4164*6236dae4SAndroid Build Coastguard Worker      <0 is "handshake was not successful, because a fatal error occurred" */
4165*6236dae4SAndroid Build Coastguard Worker   if(1 != err) {
4166*6236dae4SAndroid Build Coastguard Worker     int detail = SSL_get_error(octx->ssl, err);
4167*6236dae4SAndroid Build Coastguard Worker     CURL_TRC_CF(data, cf, "SSL_connect() -> err=%d, detail=%d", err, detail);
4168*6236dae4SAndroid Build Coastguard Worker 
4169*6236dae4SAndroid Build Coastguard Worker     if(SSL_ERROR_WANT_READ == detail) {
4170*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL_connect() -> want recv");
4171*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_RECV;
4172*6236dae4SAndroid Build Coastguard Worker       return CURLE_OK;
4173*6236dae4SAndroid Build Coastguard Worker     }
4174*6236dae4SAndroid Build Coastguard Worker     if(SSL_ERROR_WANT_WRITE == detail) {
4175*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL_connect() -> want send");
4176*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_SEND;
4177*6236dae4SAndroid Build Coastguard Worker       return CURLE_OK;
4178*6236dae4SAndroid Build Coastguard Worker     }
4179*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_ERROR_WANT_ASYNC
4180*6236dae4SAndroid Build Coastguard Worker     if(SSL_ERROR_WANT_ASYNC == detail) {
4181*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL_connect() -> want async");
4182*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_RECV;
4183*6236dae4SAndroid Build Coastguard Worker       connssl->connecting_state = ssl_connect_2;
4184*6236dae4SAndroid Build Coastguard Worker       return CURLE_OK;
4185*6236dae4SAndroid Build Coastguard Worker     }
4186*6236dae4SAndroid Build Coastguard Worker #endif
4187*6236dae4SAndroid Build Coastguard Worker #ifdef SSL_ERROR_WANT_RETRY_VERIFY
4188*6236dae4SAndroid Build Coastguard Worker     if(SSL_ERROR_WANT_RETRY_VERIFY == detail) {
4189*6236dae4SAndroid Build Coastguard Worker       CURL_TRC_CF(data, cf, "SSL_connect() -> want retry_verify");
4190*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_RECV;
4191*6236dae4SAndroid Build Coastguard Worker       connssl->connecting_state = ssl_connect_2;
4192*6236dae4SAndroid Build Coastguard Worker       return CURLE_OK;
4193*6236dae4SAndroid Build Coastguard Worker     }
4194*6236dae4SAndroid Build Coastguard Worker #endif
4195*6236dae4SAndroid Build Coastguard Worker     else {
4196*6236dae4SAndroid Build Coastguard Worker       /* untreated error */
4197*6236dae4SAndroid Build Coastguard Worker       sslerr_t errdetail;
4198*6236dae4SAndroid Build Coastguard Worker       char error_buffer[256]="";
4199*6236dae4SAndroid Build Coastguard Worker       CURLcode result;
4200*6236dae4SAndroid Build Coastguard Worker       long lerr;
4201*6236dae4SAndroid Build Coastguard Worker       int lib;
4202*6236dae4SAndroid Build Coastguard Worker       int reason;
4203*6236dae4SAndroid Build Coastguard Worker 
4204*6236dae4SAndroid Build Coastguard Worker       /* the connection failed, we are not waiting for anything else. */
4205*6236dae4SAndroid Build Coastguard Worker       connssl->connecting_state = ssl_connect_2;
4206*6236dae4SAndroid Build Coastguard Worker 
4207*6236dae4SAndroid Build Coastguard Worker       /* Get the earliest error code from the thread's error queue and remove
4208*6236dae4SAndroid Build Coastguard Worker          the entry. */
4209*6236dae4SAndroid Build Coastguard Worker       errdetail = ERR_get_error();
4210*6236dae4SAndroid Build Coastguard Worker 
4211*6236dae4SAndroid Build Coastguard Worker       /* Extract which lib and reason */
4212*6236dae4SAndroid Build Coastguard Worker       lib = ERR_GET_LIB(errdetail);
4213*6236dae4SAndroid Build Coastguard Worker       reason = ERR_GET_REASON(errdetail);
4214*6236dae4SAndroid Build Coastguard Worker 
4215*6236dae4SAndroid Build Coastguard Worker       if((lib == ERR_LIB_SSL) &&
4216*6236dae4SAndroid Build Coastguard Worker          ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) ||
4217*6236dae4SAndroid Build Coastguard Worker           (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) {
4218*6236dae4SAndroid Build Coastguard Worker         result = CURLE_PEER_FAILED_VERIFICATION;
4219*6236dae4SAndroid Build Coastguard Worker 
4220*6236dae4SAndroid Build Coastguard Worker         lerr = SSL_get_verify_result(octx->ssl);
4221*6236dae4SAndroid Build Coastguard Worker         if(lerr != X509_V_OK) {
4222*6236dae4SAndroid Build Coastguard Worker           ssl_config->certverifyresult = lerr;
4223*6236dae4SAndroid Build Coastguard Worker           msnprintf(error_buffer, sizeof(error_buffer),
4224*6236dae4SAndroid Build Coastguard Worker                     "SSL certificate problem: %s",
4225*6236dae4SAndroid Build Coastguard Worker                     X509_verify_cert_error_string(lerr));
4226*6236dae4SAndroid Build Coastguard Worker         }
4227*6236dae4SAndroid Build Coastguard Worker         else {
4228*6236dae4SAndroid Build Coastguard Worker           failf(data, "%s", "SSL certificate verification failed");
4229*6236dae4SAndroid Build Coastguard Worker           return result;
4230*6236dae4SAndroid Build Coastguard Worker         }
4231*6236dae4SAndroid Build Coastguard Worker       }
4232*6236dae4SAndroid Build Coastguard Worker #if defined(SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)
4233*6236dae4SAndroid Build Coastguard Worker       /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on
4234*6236dae4SAndroid Build Coastguard Worker          OpenSSL version above v1.1.1, not LibreSSL, BoringSSL, or AWS-LC */
4235*6236dae4SAndroid Build Coastguard Worker       else if((lib == ERR_LIB_SSL) &&
4236*6236dae4SAndroid Build Coastguard Worker               (reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)) {
4237*6236dae4SAndroid Build Coastguard Worker         /* If client certificate is required, communicate the
4238*6236dae4SAndroid Build Coastguard Worker            error to client */
4239*6236dae4SAndroid Build Coastguard Worker         result = CURLE_SSL_CLIENTCERT;
4240*6236dae4SAndroid Build Coastguard Worker         failf(data, "TLS cert problem: %s",
4241*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)));
4242*6236dae4SAndroid Build Coastguard Worker       }
4243*6236dae4SAndroid Build Coastguard Worker #endif
4244*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
4245*6236dae4SAndroid Build Coastguard Worker       else if((lib == ERR_LIB_SSL) &&
4246*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
4247*6236dae4SAndroid Build Coastguard Worker               (reason == SSL_R_ECH_REQUIRED)) {
4248*6236dae4SAndroid Build Coastguard Worker # else
4249*6236dae4SAndroid Build Coastguard Worker               (reason == SSL_R_ECH_REJECTED)) {
4250*6236dae4SAndroid Build Coastguard Worker # endif
4251*6236dae4SAndroid Build Coastguard Worker 
4252*6236dae4SAndroid Build Coastguard Worker         /* trace retry_configs if we got some */
4253*6236dae4SAndroid Build Coastguard Worker         ossl_trace_ech_retry_configs(data, octx->ssl, reason);
4254*6236dae4SAndroid Build Coastguard Worker 
4255*6236dae4SAndroid Build Coastguard Worker         result = CURLE_ECH_REQUIRED;
4256*6236dae4SAndroid Build Coastguard Worker         failf(data, "ECH required: %s",
4257*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)));
4258*6236dae4SAndroid Build Coastguard Worker       }
4259*6236dae4SAndroid Build Coastguard Worker #endif
4260*6236dae4SAndroid Build Coastguard Worker       else {
4261*6236dae4SAndroid Build Coastguard Worker         result = CURLE_SSL_CONNECT_ERROR;
4262*6236dae4SAndroid Build Coastguard Worker         failf(data, "TLS connect error: %s",
4263*6236dae4SAndroid Build Coastguard Worker               ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)));
4264*6236dae4SAndroid Build Coastguard Worker       }
4265*6236dae4SAndroid Build Coastguard Worker 
4266*6236dae4SAndroid Build Coastguard Worker       /* detail is already set to the SSL error above */
4267*6236dae4SAndroid Build Coastguard Worker 
4268*6236dae4SAndroid Build Coastguard Worker       /* If we e.g. use SSLv2 request-method and the server does not like us
4269*6236dae4SAndroid Build Coastguard Worker        * (RST connection, etc.), OpenSSL gives no explanation whatsoever and
4270*6236dae4SAndroid Build Coastguard Worker        * the SO_ERROR is also lost.
4271*6236dae4SAndroid Build Coastguard Worker        */
4272*6236dae4SAndroid Build Coastguard Worker       if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
4273*6236dae4SAndroid Build Coastguard Worker         char extramsg[80]="";
4274*6236dae4SAndroid Build Coastguard Worker         int sockerr = SOCKERRNO;
4275*6236dae4SAndroid Build Coastguard Worker 
4276*6236dae4SAndroid Build Coastguard Worker         if(sockerr && detail == SSL_ERROR_SYSCALL)
4277*6236dae4SAndroid Build Coastguard Worker           Curl_strerror(sockerr, extramsg, sizeof(extramsg));
4278*6236dae4SAndroid Build Coastguard Worker         failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%d ",
4279*6236dae4SAndroid Build Coastguard Worker               extramsg[0] ? extramsg : SSL_ERROR_to_str(detail),
4280*6236dae4SAndroid Build Coastguard Worker               connssl->peer.hostname, connssl->peer.port);
4281*6236dae4SAndroid Build Coastguard Worker         return result;
4282*6236dae4SAndroid Build Coastguard Worker       }
4283*6236dae4SAndroid Build Coastguard Worker 
4284*6236dae4SAndroid Build Coastguard Worker       return result;
4285*6236dae4SAndroid Build Coastguard Worker     }
4286*6236dae4SAndroid Build Coastguard Worker   }
4287*6236dae4SAndroid Build Coastguard Worker   else {
4288*6236dae4SAndroid Build Coastguard Worker     int psigtype_nid = NID_undef;
4289*6236dae4SAndroid Build Coastguard Worker     const char *negotiated_group_name = NULL;
4290*6236dae4SAndroid Build Coastguard Worker 
4291*6236dae4SAndroid Build Coastguard Worker     /* we connected fine, we are not waiting for anything else. */
4292*6236dae4SAndroid Build Coastguard Worker     connssl->connecting_state = ssl_connect_3;
4293*6236dae4SAndroid Build Coastguard Worker 
4294*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
4295*6236dae4SAndroid Build Coastguard Worker     SSL_get_peer_signature_type_nid(octx->ssl, &psigtype_nid);
4296*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x30200000L)
4297*6236dae4SAndroid Build Coastguard Worker     negotiated_group_name = SSL_get0_group_name(octx->ssl);
4298*6236dae4SAndroid Build Coastguard Worker #else
4299*6236dae4SAndroid Build Coastguard Worker     negotiated_group_name =
4300*6236dae4SAndroid Build Coastguard Worker       OBJ_nid2sn(SSL_get_negotiated_group(octx->ssl) & 0x0000FFFF);
4301*6236dae4SAndroid Build Coastguard Worker #endif
4302*6236dae4SAndroid Build Coastguard Worker #endif
4303*6236dae4SAndroid Build Coastguard Worker 
4304*6236dae4SAndroid Build Coastguard Worker     /* Informational message */
4305*6236dae4SAndroid Build Coastguard Worker     infof(data, "SSL connection using %s / %s / %s / %s",
4306*6236dae4SAndroid Build Coastguard Worker           SSL_get_version(octx->ssl),
4307*6236dae4SAndroid Build Coastguard Worker           SSL_get_cipher(octx->ssl),
4308*6236dae4SAndroid Build Coastguard Worker           negotiated_group_name ? negotiated_group_name : "[blank]",
4309*6236dae4SAndroid Build Coastguard Worker           OBJ_nid2sn(psigtype_nid));
4310*6236dae4SAndroid Build Coastguard Worker 
4311*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
4312*6236dae4SAndroid Build Coastguard Worker # ifndef OPENSSL_IS_BORINGSSL
4313*6236dae4SAndroid Build Coastguard Worker     if(ECH_ENABLED(data)) {
4314*6236dae4SAndroid Build Coastguard Worker       char *inner = NULL, *outer = NULL;
4315*6236dae4SAndroid Build Coastguard Worker       const char *status = NULL;
4316*6236dae4SAndroid Build Coastguard Worker       int rv;
4317*6236dae4SAndroid Build Coastguard Worker 
4318*6236dae4SAndroid Build Coastguard Worker       rv = SSL_ech_get_status(octx->ssl, &inner, &outer);
4319*6236dae4SAndroid Build Coastguard Worker       switch(rv) {
4320*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_SUCCESS:
4321*6236dae4SAndroid Build Coastguard Worker         status = "succeeded";
4322*6236dae4SAndroid Build Coastguard Worker         break;
4323*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_GREASE_ECH:
4324*6236dae4SAndroid Build Coastguard Worker         status = "sent GREASE, got retry-configs";
4325*6236dae4SAndroid Build Coastguard Worker         break;
4326*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_GREASE:
4327*6236dae4SAndroid Build Coastguard Worker         status = "sent GREASE";
4328*6236dae4SAndroid Build Coastguard Worker         break;
4329*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_NOT_TRIED:
4330*6236dae4SAndroid Build Coastguard Worker         status = "not attempted";
4331*6236dae4SAndroid Build Coastguard Worker         break;
4332*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_NOT_CONFIGURED:
4333*6236dae4SAndroid Build Coastguard Worker         status = "not configured";
4334*6236dae4SAndroid Build Coastguard Worker         break;
4335*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_BACKEND:
4336*6236dae4SAndroid Build Coastguard Worker         status = "backend (unexpected)";
4337*6236dae4SAndroid Build Coastguard Worker         break;
4338*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_FAILED:
4339*6236dae4SAndroid Build Coastguard Worker         status = "failed";
4340*6236dae4SAndroid Build Coastguard Worker         break;
4341*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_BAD_CALL:
4342*6236dae4SAndroid Build Coastguard Worker         status = "bad call (unexpected)";
4343*6236dae4SAndroid Build Coastguard Worker         break;
4344*6236dae4SAndroid Build Coastguard Worker       case SSL_ECH_STATUS_BAD_NAME:
4345*6236dae4SAndroid Build Coastguard Worker         status = "bad name (unexpected)";
4346*6236dae4SAndroid Build Coastguard Worker         break;
4347*6236dae4SAndroid Build Coastguard Worker       default:
4348*6236dae4SAndroid Build Coastguard Worker         status = "unexpected status";
4349*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: unexpected status %d",rv);
4350*6236dae4SAndroid Build Coastguard Worker       }
4351*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: result: status is %s, inner is %s, outer is %s",
4352*6236dae4SAndroid Build Coastguard Worker             (status ? status : "NULL"),
4353*6236dae4SAndroid Build Coastguard Worker             (inner ? inner : "NULL"),
4354*6236dae4SAndroid Build Coastguard Worker             (outer ? outer : "NULL"));
4355*6236dae4SAndroid Build Coastguard Worker       OPENSSL_free(inner);
4356*6236dae4SAndroid Build Coastguard Worker       OPENSSL_free(outer);
4357*6236dae4SAndroid Build Coastguard Worker       if(rv == SSL_ECH_STATUS_GREASE_ECH) {
4358*6236dae4SAndroid Build Coastguard Worker         /* trace retry_configs if we got some */
4359*6236dae4SAndroid Build Coastguard Worker         ossl_trace_ech_retry_configs(data, octx->ssl, 0);
4360*6236dae4SAndroid Build Coastguard Worker       }
4361*6236dae4SAndroid Build Coastguard Worker       if(rv != SSL_ECH_STATUS_SUCCESS
4362*6236dae4SAndroid Build Coastguard Worker          && data->set.tls_ech & CURLECH_HARD) {
4363*6236dae4SAndroid Build Coastguard Worker         infof(data, "ECH: ech-hard failed");
4364*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_CONNECT_ERROR;
4365*6236dae4SAndroid Build Coastguard Worker       }
4366*6236dae4SAndroid Build Coastguard Worker    }
4367*6236dae4SAndroid Build Coastguard Worker    else {
4368*6236dae4SAndroid Build Coastguard Worker       infof(data, "ECH: result: status is not attempted");
4369*6236dae4SAndroid Build Coastguard Worker    }
4370*6236dae4SAndroid Build Coastguard Worker # endif  /* BORING */
4371*6236dae4SAndroid Build Coastguard Worker #endif  /* USE_ECH */
4372*6236dae4SAndroid Build Coastguard Worker 
4373*6236dae4SAndroid Build Coastguard Worker #ifdef HAS_ALPN
4374*6236dae4SAndroid Build Coastguard Worker     /* Sets data and len to negotiated protocol, len is 0 if no protocol was
4375*6236dae4SAndroid Build Coastguard Worker      * negotiated
4376*6236dae4SAndroid Build Coastguard Worker      */
4377*6236dae4SAndroid Build Coastguard Worker     if(connssl->alpn) {
4378*6236dae4SAndroid Build Coastguard Worker       const unsigned char *neg_protocol;
4379*6236dae4SAndroid Build Coastguard Worker       unsigned int len;
4380*6236dae4SAndroid Build Coastguard Worker       SSL_get0_alpn_selected(octx->ssl, &neg_protocol, &len);
4381*6236dae4SAndroid Build Coastguard Worker 
4382*6236dae4SAndroid Build Coastguard Worker       return Curl_alpn_set_negotiated(cf, data, connssl, neg_protocol, len);
4383*6236dae4SAndroid Build Coastguard Worker     }
4384*6236dae4SAndroid Build Coastguard Worker #endif
4385*6236dae4SAndroid Build Coastguard Worker 
4386*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
4387*6236dae4SAndroid Build Coastguard Worker   }
4388*6236dae4SAndroid Build Coastguard Worker }
4389*6236dae4SAndroid Build Coastguard Worker 
4390*6236dae4SAndroid Build Coastguard Worker /*
4391*6236dae4SAndroid Build Coastguard Worker  * Heavily modified from:
4392*6236dae4SAndroid Build Coastguard Worker  * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
4393*6236dae4SAndroid Build Coastguard Worker  */
4394*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
4395*6236dae4SAndroid Build Coastguard Worker                                          const char *pinnedpubkey)
4396*6236dae4SAndroid Build Coastguard Worker {
4397*6236dae4SAndroid Build Coastguard Worker   /* Scratch */
4398*6236dae4SAndroid Build Coastguard Worker   int len1 = 0, len2 = 0;
4399*6236dae4SAndroid Build Coastguard Worker   unsigned char *buff1 = NULL, *temp = NULL;
4400*6236dae4SAndroid Build Coastguard Worker 
4401*6236dae4SAndroid Build Coastguard Worker   /* Result is returned to caller */
4402*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
4403*6236dae4SAndroid Build Coastguard Worker 
4404*6236dae4SAndroid Build Coastguard Worker   /* if a path was not specified, do not pin */
4405*6236dae4SAndroid Build Coastguard Worker   if(!pinnedpubkey)
4406*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
4407*6236dae4SAndroid Build Coastguard Worker 
4408*6236dae4SAndroid Build Coastguard Worker   if(!cert)
4409*6236dae4SAndroid Build Coastguard Worker     return result;
4410*6236dae4SAndroid Build Coastguard Worker 
4411*6236dae4SAndroid Build Coastguard Worker   do {
4412*6236dae4SAndroid Build Coastguard Worker     /* Begin Gyrations to get the subjectPublicKeyInfo     */
4413*6236dae4SAndroid Build Coastguard Worker     /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
4414*6236dae4SAndroid Build Coastguard Worker 
4415*6236dae4SAndroid Build Coastguard Worker     /* https://groups.google.com/group/mailing.openssl.users/browse_thread
4416*6236dae4SAndroid Build Coastguard Worker        /thread/d61858dae102c6c7 */
4417*6236dae4SAndroid Build Coastguard Worker     len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
4418*6236dae4SAndroid Build Coastguard Worker     if(len1 < 1)
4419*6236dae4SAndroid Build Coastguard Worker       break; /* failed */
4420*6236dae4SAndroid Build Coastguard Worker 
4421*6236dae4SAndroid Build Coastguard Worker     buff1 = temp = malloc(len1);
4422*6236dae4SAndroid Build Coastguard Worker     if(!buff1)
4423*6236dae4SAndroid Build Coastguard Worker       break; /* failed */
4424*6236dae4SAndroid Build Coastguard Worker 
4425*6236dae4SAndroid Build Coastguard Worker     /* https://docs.openssl.org/master/man3/d2i_X509/ */
4426*6236dae4SAndroid Build Coastguard Worker     len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
4427*6236dae4SAndroid Build Coastguard Worker 
4428*6236dae4SAndroid Build Coastguard Worker     /*
4429*6236dae4SAndroid Build Coastguard Worker      * These checks are verifying we got back the same values as when we
4430*6236dae4SAndroid Build Coastguard Worker      * sized the buffer. it is pretty weak since they should always be the
4431*6236dae4SAndroid Build Coastguard Worker      * same. But it gives us something to test.
4432*6236dae4SAndroid Build Coastguard Worker      */
4433*6236dae4SAndroid Build Coastguard Worker     if((len1 != len2) || !temp || ((temp - buff1) != len1))
4434*6236dae4SAndroid Build Coastguard Worker       break; /* failed */
4435*6236dae4SAndroid Build Coastguard Worker 
4436*6236dae4SAndroid Build Coastguard Worker     /* End Gyrations */
4437*6236dae4SAndroid Build Coastguard Worker 
4438*6236dae4SAndroid Build Coastguard Worker     /* The one good exit point */
4439*6236dae4SAndroid Build Coastguard Worker     result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
4440*6236dae4SAndroid Build Coastguard Worker   } while(0);
4441*6236dae4SAndroid Build Coastguard Worker 
4442*6236dae4SAndroid Build Coastguard Worker   if(buff1)
4443*6236dae4SAndroid Build Coastguard Worker     free(buff1);
4444*6236dae4SAndroid Build Coastguard Worker 
4445*6236dae4SAndroid Build Coastguard Worker   return result;
4446*6236dae4SAndroid Build Coastguard Worker }
4447*6236dae4SAndroid Build Coastguard Worker 
4448*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) &&  \
4449*6236dae4SAndroid Build Coastguard Worker   !(defined(LIBRESSL_VERSION_NUMBER) && \
4450*6236dae4SAndroid Build Coastguard Worker     LIBRESSL_VERSION_NUMBER < 0x3060000fL) && \
4451*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_IS_BORINGSSL) && \
4452*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_IS_AWSLC) && \
4453*6236dae4SAndroid Build Coastguard Worker   !defined(CURL_DISABLE_VERBOSE_STRINGS)
4454*6236dae4SAndroid Build Coastguard Worker static void infof_certstack(struct Curl_easy *data, const SSL *ssl)
4455*6236dae4SAndroid Build Coastguard Worker {
4456*6236dae4SAndroid Build Coastguard Worker   STACK_OF(X509) *certstack;
4457*6236dae4SAndroid Build Coastguard Worker   long verify_result;
4458*6236dae4SAndroid Build Coastguard Worker   int num_cert_levels;
4459*6236dae4SAndroid Build Coastguard Worker   int cert_level;
4460*6236dae4SAndroid Build Coastguard Worker 
4461*6236dae4SAndroid Build Coastguard Worker   verify_result = SSL_get_verify_result(ssl);
4462*6236dae4SAndroid Build Coastguard Worker   if(verify_result != X509_V_OK)
4463*6236dae4SAndroid Build Coastguard Worker     certstack = SSL_get_peer_cert_chain(ssl);
4464*6236dae4SAndroid Build Coastguard Worker   else
4465*6236dae4SAndroid Build Coastguard Worker     certstack = SSL_get0_verified_chain(ssl);
4466*6236dae4SAndroid Build Coastguard Worker   num_cert_levels = sk_X509_num(certstack);
4467*6236dae4SAndroid Build Coastguard Worker 
4468*6236dae4SAndroid Build Coastguard Worker   for(cert_level = 0; cert_level < num_cert_levels; cert_level++) {
4469*6236dae4SAndroid Build Coastguard Worker     char cert_algorithm[80] = "";
4470*6236dae4SAndroid Build Coastguard Worker     char group_name_final[80] = "";
4471*6236dae4SAndroid Build Coastguard Worker     const X509_ALGOR *palg_cert = NULL;
4472*6236dae4SAndroid Build Coastguard Worker     const ASN1_OBJECT *paobj_cert = NULL;
4473*6236dae4SAndroid Build Coastguard Worker     X509 *current_cert;
4474*6236dae4SAndroid Build Coastguard Worker     EVP_PKEY *current_pkey;
4475*6236dae4SAndroid Build Coastguard Worker     int key_bits;
4476*6236dae4SAndroid Build Coastguard Worker     int key_sec_bits;
4477*6236dae4SAndroid Build Coastguard Worker     int get_group_name;
4478*6236dae4SAndroid Build Coastguard Worker     const char *type_name;
4479*6236dae4SAndroid Build Coastguard Worker 
4480*6236dae4SAndroid Build Coastguard Worker     current_cert = sk_X509_value(certstack, cert_level);
4481*6236dae4SAndroid Build Coastguard Worker 
4482*6236dae4SAndroid Build Coastguard Worker     X509_get0_signature(NULL, &palg_cert, current_cert);
4483*6236dae4SAndroid Build Coastguard Worker     X509_ALGOR_get0(&paobj_cert, NULL, NULL, palg_cert);
4484*6236dae4SAndroid Build Coastguard Worker     OBJ_obj2txt(cert_algorithm, sizeof(cert_algorithm), paobj_cert, 0);
4485*6236dae4SAndroid Build Coastguard Worker 
4486*6236dae4SAndroid Build Coastguard Worker     current_pkey = X509_get0_pubkey(current_cert);
4487*6236dae4SAndroid Build Coastguard Worker     key_bits = EVP_PKEY_bits(current_pkey);
4488*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER < 0x30000000L)
4489*6236dae4SAndroid Build Coastguard Worker #define EVP_PKEY_get_security_bits EVP_PKEY_security_bits
4490*6236dae4SAndroid Build Coastguard Worker #endif
4491*6236dae4SAndroid Build Coastguard Worker     key_sec_bits = EVP_PKEY_get_security_bits(current_pkey);
4492*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
4493*6236dae4SAndroid Build Coastguard Worker     {
4494*6236dae4SAndroid Build Coastguard Worker       char group_name[80] = "";
4495*6236dae4SAndroid Build Coastguard Worker       get_group_name = EVP_PKEY_get_group_name(current_pkey, group_name,
4496*6236dae4SAndroid Build Coastguard Worker                                                sizeof(group_name), NULL);
4497*6236dae4SAndroid Build Coastguard Worker       msnprintf(group_name_final, sizeof(group_name_final), "/%s", group_name);
4498*6236dae4SAndroid Build Coastguard Worker     }
4499*6236dae4SAndroid Build Coastguard Worker     type_name = EVP_PKEY_get0_type_name(current_pkey);
4500*6236dae4SAndroid Build Coastguard Worker #else
4501*6236dae4SAndroid Build Coastguard Worker     get_group_name = 0;
4502*6236dae4SAndroid Build Coastguard Worker     type_name = NULL;
4503*6236dae4SAndroid Build Coastguard Worker #endif
4504*6236dae4SAndroid Build Coastguard Worker 
4505*6236dae4SAndroid Build Coastguard Worker     infof(data,
4506*6236dae4SAndroid Build Coastguard Worker           "  Certificate level %d: "
4507*6236dae4SAndroid Build Coastguard Worker           "Public key type %s%s (%d/%d Bits/secBits), signed using %s",
4508*6236dae4SAndroid Build Coastguard Worker           cert_level, type_name ? type_name : "?",
4509*6236dae4SAndroid Build Coastguard Worker           get_group_name == 0 ? "" : group_name_final,
4510*6236dae4SAndroid Build Coastguard Worker           key_bits, key_sec_bits, cert_algorithm);
4511*6236dae4SAndroid Build Coastguard Worker   }
4512*6236dae4SAndroid Build Coastguard Worker }
4513*6236dae4SAndroid Build Coastguard Worker #else
4514*6236dae4SAndroid Build Coastguard Worker #define infof_certstack(data, ssl)
4515*6236dae4SAndroid Build Coastguard Worker #endif
4516*6236dae4SAndroid Build Coastguard Worker 
4517*6236dae4SAndroid Build Coastguard Worker #define MAX_CERT_NAME_LENGTH 2048
4518*6236dae4SAndroid Build Coastguard Worker 
4519*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_oss_check_peer_cert(struct Curl_cfilter *cf,
4520*6236dae4SAndroid Build Coastguard Worker                                   struct Curl_easy *data,
4521*6236dae4SAndroid Build Coastguard Worker                                   struct ossl_ctx *octx,
4522*6236dae4SAndroid Build Coastguard Worker                                   struct ssl_peer *peer)
4523*6236dae4SAndroid Build Coastguard Worker {
4524*6236dae4SAndroid Build Coastguard Worker   struct connectdata *conn = cf->conn;
4525*6236dae4SAndroid Build Coastguard Worker   struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
4526*6236dae4SAndroid Build Coastguard Worker   struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
4527*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
4528*6236dae4SAndroid Build Coastguard Worker   long lerr;
4529*6236dae4SAndroid Build Coastguard Worker   X509 *issuer;
4530*6236dae4SAndroid Build Coastguard Worker   BIO *fp = NULL;
4531*6236dae4SAndroid Build Coastguard Worker   char error_buffer[256]="";
4532*6236dae4SAndroid Build Coastguard Worker   const char *ptr;
4533*6236dae4SAndroid Build Coastguard Worker   BIO *mem = BIO_new(BIO_s_mem());
4534*6236dae4SAndroid Build Coastguard Worker   bool strict = (conn_config->verifypeer || conn_config->verifyhost);
4535*6236dae4SAndroid Build Coastguard Worker   struct dynbuf dname;
4536*6236dae4SAndroid Build Coastguard Worker 
4537*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
4538*6236dae4SAndroid Build Coastguard Worker 
4539*6236dae4SAndroid Build Coastguard Worker   Curl_dyn_init(&dname, MAX_CERT_NAME_LENGTH);
4540*6236dae4SAndroid Build Coastguard Worker 
4541*6236dae4SAndroid Build Coastguard Worker   if(!mem) {
4542*6236dae4SAndroid Build Coastguard Worker     failf(data,
4543*6236dae4SAndroid Build Coastguard Worker           "BIO_new return NULL, " OSSL_PACKAGE
4544*6236dae4SAndroid Build Coastguard Worker           " error %s",
4545*6236dae4SAndroid Build Coastguard Worker           ossl_strerror(ERR_get_error(), error_buffer,
4546*6236dae4SAndroid Build Coastguard Worker                         sizeof(error_buffer)) );
4547*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
4548*6236dae4SAndroid Build Coastguard Worker   }
4549*6236dae4SAndroid Build Coastguard Worker 
4550*6236dae4SAndroid Build Coastguard Worker   if(data->set.ssl.certinfo)
4551*6236dae4SAndroid Build Coastguard Worker     /* asked to gather certificate info */
4552*6236dae4SAndroid Build Coastguard Worker     (void)ossl_certchain(data, octx->ssl);
4553*6236dae4SAndroid Build Coastguard Worker 
4554*6236dae4SAndroid Build Coastguard Worker   octx->server_cert = SSL_get1_peer_certificate(octx->ssl);
4555*6236dae4SAndroid Build Coastguard Worker   if(!octx->server_cert) {
4556*6236dae4SAndroid Build Coastguard Worker     BIO_free(mem);
4557*6236dae4SAndroid Build Coastguard Worker     if(!strict)
4558*6236dae4SAndroid Build Coastguard Worker       return CURLE_OK;
4559*6236dae4SAndroid Build Coastguard Worker 
4560*6236dae4SAndroid Build Coastguard Worker     failf(data, "SSL: could not get peer certificate");
4561*6236dae4SAndroid Build Coastguard Worker     return CURLE_PEER_FAILED_VERIFICATION;
4562*6236dae4SAndroid Build Coastguard Worker   }
4563*6236dae4SAndroid Build Coastguard Worker 
4564*6236dae4SAndroid Build Coastguard Worker   infof(data, "%s certificate:",
4565*6236dae4SAndroid Build Coastguard Worker         Curl_ssl_cf_is_proxy(cf) ? "Proxy" : "Server");
4566*6236dae4SAndroid Build Coastguard Worker 
4567*6236dae4SAndroid Build Coastguard Worker   result = x509_name_oneline(X509_get_subject_name(octx->server_cert),
4568*6236dae4SAndroid Build Coastguard Worker                              &dname);
4569*6236dae4SAndroid Build Coastguard Worker   infof(data, " subject: %s", result ? "[NONE]" : Curl_dyn_ptr(&dname));
4570*6236dae4SAndroid Build Coastguard Worker 
4571*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_VERBOSE_STRINGS
4572*6236dae4SAndroid Build Coastguard Worker   {
4573*6236dae4SAndroid Build Coastguard Worker     long len;
4574*6236dae4SAndroid Build Coastguard Worker     ASN1_TIME_print(mem, X509_get0_notBefore(octx->server_cert));
4575*6236dae4SAndroid Build Coastguard Worker     len = BIO_get_mem_data(mem, (char **) &ptr);
4576*6236dae4SAndroid Build Coastguard Worker     infof(data, " start date: %.*s", (int)len, ptr);
4577*6236dae4SAndroid Build Coastguard Worker     (void)BIO_reset(mem);
4578*6236dae4SAndroid Build Coastguard Worker 
4579*6236dae4SAndroid Build Coastguard Worker     ASN1_TIME_print(mem, X509_get0_notAfter(octx->server_cert));
4580*6236dae4SAndroid Build Coastguard Worker     len = BIO_get_mem_data(mem, (char **) &ptr);
4581*6236dae4SAndroid Build Coastguard Worker     infof(data, " expire date: %.*s", (int)len, ptr);
4582*6236dae4SAndroid Build Coastguard Worker     (void)BIO_reset(mem);
4583*6236dae4SAndroid Build Coastguard Worker   }
4584*6236dae4SAndroid Build Coastguard Worker #endif
4585*6236dae4SAndroid Build Coastguard Worker 
4586*6236dae4SAndroid Build Coastguard Worker   BIO_free(mem);
4587*6236dae4SAndroid Build Coastguard Worker 
4588*6236dae4SAndroid Build Coastguard Worker   if(conn_config->verifyhost) {
4589*6236dae4SAndroid Build Coastguard Worker     result = ossl_verifyhost(data, conn, peer, octx->server_cert);
4590*6236dae4SAndroid Build Coastguard Worker     if(result) {
4591*6236dae4SAndroid Build Coastguard Worker       X509_free(octx->server_cert);
4592*6236dae4SAndroid Build Coastguard Worker       octx->server_cert = NULL;
4593*6236dae4SAndroid Build Coastguard Worker       Curl_dyn_free(&dname);
4594*6236dae4SAndroid Build Coastguard Worker       return result;
4595*6236dae4SAndroid Build Coastguard Worker     }
4596*6236dae4SAndroid Build Coastguard Worker   }
4597*6236dae4SAndroid Build Coastguard Worker 
4598*6236dae4SAndroid Build Coastguard Worker   result = x509_name_oneline(X509_get_issuer_name(octx->server_cert),
4599*6236dae4SAndroid Build Coastguard Worker                              &dname);
4600*6236dae4SAndroid Build Coastguard Worker   if(result) {
4601*6236dae4SAndroid Build Coastguard Worker     if(strict)
4602*6236dae4SAndroid Build Coastguard Worker       failf(data, "SSL: could not get X509-issuer name");
4603*6236dae4SAndroid Build Coastguard Worker     result = CURLE_PEER_FAILED_VERIFICATION;
4604*6236dae4SAndroid Build Coastguard Worker   }
4605*6236dae4SAndroid Build Coastguard Worker   else {
4606*6236dae4SAndroid Build Coastguard Worker     infof(data, " issuer: %s", Curl_dyn_ptr(&dname));
4607*6236dae4SAndroid Build Coastguard Worker     Curl_dyn_free(&dname);
4608*6236dae4SAndroid Build Coastguard Worker 
4609*6236dae4SAndroid Build Coastguard Worker     /* We could do all sorts of certificate verification stuff here before
4610*6236dae4SAndroid Build Coastguard Worker        deallocating the certificate. */
4611*6236dae4SAndroid Build Coastguard Worker 
4612*6236dae4SAndroid Build Coastguard Worker     /* e.g. match issuer name with provided issuer certificate */
4613*6236dae4SAndroid Build Coastguard Worker     if(conn_config->issuercert || conn_config->issuercert_blob) {
4614*6236dae4SAndroid Build Coastguard Worker       if(conn_config->issuercert_blob) {
4615*6236dae4SAndroid Build Coastguard Worker         fp = BIO_new_mem_buf(conn_config->issuercert_blob->data,
4616*6236dae4SAndroid Build Coastguard Worker                              (int)conn_config->issuercert_blob->len);
4617*6236dae4SAndroid Build Coastguard Worker         if(!fp) {
4618*6236dae4SAndroid Build Coastguard Worker           failf(data,
4619*6236dae4SAndroid Build Coastguard Worker                 "BIO_new_mem_buf NULL, " OSSL_PACKAGE
4620*6236dae4SAndroid Build Coastguard Worker                 " error %s",
4621*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
4622*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)) );
4623*6236dae4SAndroid Build Coastguard Worker           X509_free(octx->server_cert);
4624*6236dae4SAndroid Build Coastguard Worker           octx->server_cert = NULL;
4625*6236dae4SAndroid Build Coastguard Worker           return CURLE_OUT_OF_MEMORY;
4626*6236dae4SAndroid Build Coastguard Worker         }
4627*6236dae4SAndroid Build Coastguard Worker       }
4628*6236dae4SAndroid Build Coastguard Worker       else {
4629*6236dae4SAndroid Build Coastguard Worker         fp = BIO_new(BIO_s_file());
4630*6236dae4SAndroid Build Coastguard Worker         if(!fp) {
4631*6236dae4SAndroid Build Coastguard Worker           failf(data,
4632*6236dae4SAndroid Build Coastguard Worker                 "BIO_new return NULL, " OSSL_PACKAGE
4633*6236dae4SAndroid Build Coastguard Worker                 " error %s",
4634*6236dae4SAndroid Build Coastguard Worker                 ossl_strerror(ERR_get_error(), error_buffer,
4635*6236dae4SAndroid Build Coastguard Worker                               sizeof(error_buffer)) );
4636*6236dae4SAndroid Build Coastguard Worker           X509_free(octx->server_cert);
4637*6236dae4SAndroid Build Coastguard Worker           octx->server_cert = NULL;
4638*6236dae4SAndroid Build Coastguard Worker           return CURLE_OUT_OF_MEMORY;
4639*6236dae4SAndroid Build Coastguard Worker         }
4640*6236dae4SAndroid Build Coastguard Worker 
4641*6236dae4SAndroid Build Coastguard Worker         if(BIO_read_filename(fp, conn_config->issuercert) <= 0) {
4642*6236dae4SAndroid Build Coastguard Worker           if(strict)
4643*6236dae4SAndroid Build Coastguard Worker             failf(data, "SSL: Unable to open issuer cert (%s)",
4644*6236dae4SAndroid Build Coastguard Worker                   conn_config->issuercert);
4645*6236dae4SAndroid Build Coastguard Worker           BIO_free(fp);
4646*6236dae4SAndroid Build Coastguard Worker           X509_free(octx->server_cert);
4647*6236dae4SAndroid Build Coastguard Worker           octx->server_cert = NULL;
4648*6236dae4SAndroid Build Coastguard Worker           return CURLE_SSL_ISSUER_ERROR;
4649*6236dae4SAndroid Build Coastguard Worker         }
4650*6236dae4SAndroid Build Coastguard Worker       }
4651*6236dae4SAndroid Build Coastguard Worker 
4652*6236dae4SAndroid Build Coastguard Worker       issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL);
4653*6236dae4SAndroid Build Coastguard Worker       if(!issuer) {
4654*6236dae4SAndroid Build Coastguard Worker         if(strict)
4655*6236dae4SAndroid Build Coastguard Worker           failf(data, "SSL: Unable to read issuer cert (%s)",
4656*6236dae4SAndroid Build Coastguard Worker                 conn_config->issuercert);
4657*6236dae4SAndroid Build Coastguard Worker         BIO_free(fp);
4658*6236dae4SAndroid Build Coastguard Worker         X509_free(issuer);
4659*6236dae4SAndroid Build Coastguard Worker         X509_free(octx->server_cert);
4660*6236dae4SAndroid Build Coastguard Worker         octx->server_cert = NULL;
4661*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_ISSUER_ERROR;
4662*6236dae4SAndroid Build Coastguard Worker       }
4663*6236dae4SAndroid Build Coastguard Worker 
4664*6236dae4SAndroid Build Coastguard Worker       if(X509_check_issued(issuer, octx->server_cert) != X509_V_OK) {
4665*6236dae4SAndroid Build Coastguard Worker         if(strict)
4666*6236dae4SAndroid Build Coastguard Worker           failf(data, "SSL: Certificate issuer check failed (%s)",
4667*6236dae4SAndroid Build Coastguard Worker                 conn_config->issuercert);
4668*6236dae4SAndroid Build Coastguard Worker         BIO_free(fp);
4669*6236dae4SAndroid Build Coastguard Worker         X509_free(issuer);
4670*6236dae4SAndroid Build Coastguard Worker         X509_free(octx->server_cert);
4671*6236dae4SAndroid Build Coastguard Worker         octx->server_cert = NULL;
4672*6236dae4SAndroid Build Coastguard Worker         return CURLE_SSL_ISSUER_ERROR;
4673*6236dae4SAndroid Build Coastguard Worker       }
4674*6236dae4SAndroid Build Coastguard Worker 
4675*6236dae4SAndroid Build Coastguard Worker       infof(data, " SSL certificate issuer check ok (%s)",
4676*6236dae4SAndroid Build Coastguard Worker             conn_config->issuercert);
4677*6236dae4SAndroid Build Coastguard Worker       BIO_free(fp);
4678*6236dae4SAndroid Build Coastguard Worker       X509_free(issuer);
4679*6236dae4SAndroid Build Coastguard Worker     }
4680*6236dae4SAndroid Build Coastguard Worker 
4681*6236dae4SAndroid Build Coastguard Worker     lerr = SSL_get_verify_result(octx->ssl);
4682*6236dae4SAndroid Build Coastguard Worker     ssl_config->certverifyresult = lerr;
4683*6236dae4SAndroid Build Coastguard Worker     if(lerr != X509_V_OK) {
4684*6236dae4SAndroid Build Coastguard Worker       if(conn_config->verifypeer) {
4685*6236dae4SAndroid Build Coastguard Worker         /* We probably never reach this, because SSL_connect() will fail
4686*6236dae4SAndroid Build Coastguard Worker            and we return earlier if verifypeer is set? */
4687*6236dae4SAndroid Build Coastguard Worker         if(strict)
4688*6236dae4SAndroid Build Coastguard Worker           failf(data, "SSL certificate verify result: %s (%ld)",
4689*6236dae4SAndroid Build Coastguard Worker                 X509_verify_cert_error_string(lerr), lerr);
4690*6236dae4SAndroid Build Coastguard Worker         result = CURLE_PEER_FAILED_VERIFICATION;
4691*6236dae4SAndroid Build Coastguard Worker       }
4692*6236dae4SAndroid Build Coastguard Worker       else
4693*6236dae4SAndroid Build Coastguard Worker         infof(data, " SSL certificate verify result: %s (%ld),"
4694*6236dae4SAndroid Build Coastguard Worker               " continuing anyway.",
4695*6236dae4SAndroid Build Coastguard Worker               X509_verify_cert_error_string(lerr), lerr);
4696*6236dae4SAndroid Build Coastguard Worker     }
4697*6236dae4SAndroid Build Coastguard Worker     else
4698*6236dae4SAndroid Build Coastguard Worker       infof(data, " SSL certificate verify ok.");
4699*6236dae4SAndroid Build Coastguard Worker   }
4700*6236dae4SAndroid Build Coastguard Worker   infof_certstack(data, octx->ssl);
4701*6236dae4SAndroid Build Coastguard Worker 
4702*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
4703*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_OCSP)
4704*6236dae4SAndroid Build Coastguard Worker   if(conn_config->verifystatus && !octx->reused_session) {
4705*6236dae4SAndroid Build Coastguard Worker     /* do not do this after Session ID reuse */
4706*6236dae4SAndroid Build Coastguard Worker     result = verifystatus(cf, data, octx);
4707*6236dae4SAndroid Build Coastguard Worker     if(result) {
4708*6236dae4SAndroid Build Coastguard Worker       /* when verifystatus failed, remove the session id from the cache again
4709*6236dae4SAndroid Build Coastguard Worker          if present */
4710*6236dae4SAndroid Build Coastguard Worker       if(!Curl_ssl_cf_is_proxy(cf)) {
4711*6236dae4SAndroid Build Coastguard Worker         void *old_ssl_sessionid = NULL;
4712*6236dae4SAndroid Build Coastguard Worker         bool incache;
4713*6236dae4SAndroid Build Coastguard Worker         Curl_ssl_sessionid_lock(data);
4714*6236dae4SAndroid Build Coastguard Worker         incache = !(Curl_ssl_getsessionid(cf, data, peer,
4715*6236dae4SAndroid Build Coastguard Worker                                           &old_ssl_sessionid, NULL, NULL));
4716*6236dae4SAndroid Build Coastguard Worker         if(incache) {
4717*6236dae4SAndroid Build Coastguard Worker           infof(data, "Remove session ID again from cache");
4718*6236dae4SAndroid Build Coastguard Worker           Curl_ssl_delsessionid(data, old_ssl_sessionid);
4719*6236dae4SAndroid Build Coastguard Worker         }
4720*6236dae4SAndroid Build Coastguard Worker         Curl_ssl_sessionid_unlock(data);
4721*6236dae4SAndroid Build Coastguard Worker       }
4722*6236dae4SAndroid Build Coastguard Worker 
4723*6236dae4SAndroid Build Coastguard Worker       X509_free(octx->server_cert);
4724*6236dae4SAndroid Build Coastguard Worker       octx->server_cert = NULL;
4725*6236dae4SAndroid Build Coastguard Worker       return result;
4726*6236dae4SAndroid Build Coastguard Worker     }
4727*6236dae4SAndroid Build Coastguard Worker   }
4728*6236dae4SAndroid Build Coastguard Worker #endif
4729*6236dae4SAndroid Build Coastguard Worker 
4730*6236dae4SAndroid Build Coastguard Worker   if(!strict)
4731*6236dae4SAndroid Build Coastguard Worker     /* when not strict, we do not bother about the verify cert problems */
4732*6236dae4SAndroid Build Coastguard Worker     result = CURLE_OK;
4733*6236dae4SAndroid Build Coastguard Worker 
4734*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_PROXY
4735*6236dae4SAndroid Build Coastguard Worker   ptr = Curl_ssl_cf_is_proxy(cf) ?
4736*6236dae4SAndroid Build Coastguard Worker     data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
4737*6236dae4SAndroid Build Coastguard Worker     data->set.str[STRING_SSL_PINNEDPUBLICKEY];
4738*6236dae4SAndroid Build Coastguard Worker #else
4739*6236dae4SAndroid Build Coastguard Worker   ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
4740*6236dae4SAndroid Build Coastguard Worker #endif
4741*6236dae4SAndroid Build Coastguard Worker   if(!result && ptr) {
4742*6236dae4SAndroid Build Coastguard Worker     result = ossl_pkp_pin_peer_pubkey(data, octx->server_cert, ptr);
4743*6236dae4SAndroid Build Coastguard Worker     if(result)
4744*6236dae4SAndroid Build Coastguard Worker       failf(data, "SSL: public key does not match pinned public key");
4745*6236dae4SAndroid Build Coastguard Worker   }
4746*6236dae4SAndroid Build Coastguard Worker 
4747*6236dae4SAndroid Build Coastguard Worker   X509_free(octx->server_cert);
4748*6236dae4SAndroid Build Coastguard Worker   octx->server_cert = NULL;
4749*6236dae4SAndroid Build Coastguard Worker 
4750*6236dae4SAndroid Build Coastguard Worker   return result;
4751*6236dae4SAndroid Build Coastguard Worker }
4752*6236dae4SAndroid Build Coastguard Worker 
4753*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_connect_step3(struct Curl_cfilter *cf,
4754*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_easy *data)
4755*6236dae4SAndroid Build Coastguard Worker {
4756*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
4757*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
4758*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
4759*6236dae4SAndroid Build Coastguard Worker 
4760*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
4761*6236dae4SAndroid Build Coastguard Worker 
4762*6236dae4SAndroid Build Coastguard Worker   /*
4763*6236dae4SAndroid Build Coastguard Worker    * We check certificates to authenticate the server; otherwise we risk
4764*6236dae4SAndroid Build Coastguard Worker    * man-in-the-middle attack; NEVERTHELESS, if we are told explicitly not to
4765*6236dae4SAndroid Build Coastguard Worker    * verify the peer, ignore faults and failures from the server cert
4766*6236dae4SAndroid Build Coastguard Worker    * operations.
4767*6236dae4SAndroid Build Coastguard Worker    */
4768*6236dae4SAndroid Build Coastguard Worker 
4769*6236dae4SAndroid Build Coastguard Worker   result = Curl_oss_check_peer_cert(cf, data, octx, &connssl->peer);
4770*6236dae4SAndroid Build Coastguard Worker   if(!result)
4771*6236dae4SAndroid Build Coastguard Worker     connssl->connecting_state = ssl_connect_done;
4772*6236dae4SAndroid Build Coastguard Worker 
4773*6236dae4SAndroid Build Coastguard Worker   return result;
4774*6236dae4SAndroid Build Coastguard Worker }
4775*6236dae4SAndroid Build Coastguard Worker 
4776*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_connect_common(struct Curl_cfilter *cf,
4777*6236dae4SAndroid Build Coastguard Worker                                     struct Curl_easy *data,
4778*6236dae4SAndroid Build Coastguard Worker                                     bool nonblocking,
4779*6236dae4SAndroid Build Coastguard Worker                                     bool *done)
4780*6236dae4SAndroid Build Coastguard Worker {
4781*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_OK;
4782*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
4783*6236dae4SAndroid Build Coastguard Worker   curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
4784*6236dae4SAndroid Build Coastguard Worker   int what;
4785*6236dae4SAndroid Build Coastguard Worker 
4786*6236dae4SAndroid Build Coastguard Worker   connssl->io_need = CURL_SSL_IO_NEED_NONE;
4787*6236dae4SAndroid Build Coastguard Worker   /* check if the connection has already been established */
4788*6236dae4SAndroid Build Coastguard Worker   if(ssl_connection_complete == connssl->state) {
4789*6236dae4SAndroid Build Coastguard Worker     *done = TRUE;
4790*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
4791*6236dae4SAndroid Build Coastguard Worker   }
4792*6236dae4SAndroid Build Coastguard Worker 
4793*6236dae4SAndroid Build Coastguard Worker   if(ssl_connect_1 == connssl->connecting_state) {
4794*6236dae4SAndroid Build Coastguard Worker     /* Find out how much more time we are allowed */
4795*6236dae4SAndroid Build Coastguard Worker     const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
4796*6236dae4SAndroid Build Coastguard Worker 
4797*6236dae4SAndroid Build Coastguard Worker     if(timeout_ms < 0) {
4798*6236dae4SAndroid Build Coastguard Worker       /* no need to continue if time is already up */
4799*6236dae4SAndroid Build Coastguard Worker       failf(data, "SSL connection timeout");
4800*6236dae4SAndroid Build Coastguard Worker       return CURLE_OPERATION_TIMEDOUT;
4801*6236dae4SAndroid Build Coastguard Worker     }
4802*6236dae4SAndroid Build Coastguard Worker 
4803*6236dae4SAndroid Build Coastguard Worker     result = ossl_connect_step1(cf, data);
4804*6236dae4SAndroid Build Coastguard Worker     if(result)
4805*6236dae4SAndroid Build Coastguard Worker       goto out;
4806*6236dae4SAndroid Build Coastguard Worker   }
4807*6236dae4SAndroid Build Coastguard Worker 
4808*6236dae4SAndroid Build Coastguard Worker   while(ssl_connect_2 == connssl->connecting_state) {
4809*6236dae4SAndroid Build Coastguard Worker 
4810*6236dae4SAndroid Build Coastguard Worker     /* check allowed time left */
4811*6236dae4SAndroid Build Coastguard Worker     const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
4812*6236dae4SAndroid Build Coastguard Worker 
4813*6236dae4SAndroid Build Coastguard Worker     if(timeout_ms < 0) {
4814*6236dae4SAndroid Build Coastguard Worker       /* no need to continue if time already is up */
4815*6236dae4SAndroid Build Coastguard Worker       failf(data, "SSL connection timeout");
4816*6236dae4SAndroid Build Coastguard Worker       result = CURLE_OPERATION_TIMEDOUT;
4817*6236dae4SAndroid Build Coastguard Worker       goto out;
4818*6236dae4SAndroid Build Coastguard Worker     }
4819*6236dae4SAndroid Build Coastguard Worker 
4820*6236dae4SAndroid Build Coastguard Worker     /* if ssl is expecting something, check if it is available. */
4821*6236dae4SAndroid Build Coastguard Worker     if(!nonblocking && connssl->io_need) {
4822*6236dae4SAndroid Build Coastguard Worker       curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
4823*6236dae4SAndroid Build Coastguard Worker         sockfd : CURL_SOCKET_BAD;
4824*6236dae4SAndroid Build Coastguard Worker       curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
4825*6236dae4SAndroid Build Coastguard Worker         sockfd : CURL_SOCKET_BAD;
4826*6236dae4SAndroid Build Coastguard Worker 
4827*6236dae4SAndroid Build Coastguard Worker       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
4828*6236dae4SAndroid Build Coastguard Worker                                timeout_ms);
4829*6236dae4SAndroid Build Coastguard Worker       if(what < 0) {
4830*6236dae4SAndroid Build Coastguard Worker         /* fatal error */
4831*6236dae4SAndroid Build Coastguard Worker         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
4832*6236dae4SAndroid Build Coastguard Worker         result = CURLE_SSL_CONNECT_ERROR;
4833*6236dae4SAndroid Build Coastguard Worker         goto out;
4834*6236dae4SAndroid Build Coastguard Worker       }
4835*6236dae4SAndroid Build Coastguard Worker       if(0 == what) {
4836*6236dae4SAndroid Build Coastguard Worker         /* timeout */
4837*6236dae4SAndroid Build Coastguard Worker         failf(data, "SSL connection timeout");
4838*6236dae4SAndroid Build Coastguard Worker         result = CURLE_OPERATION_TIMEDOUT;
4839*6236dae4SAndroid Build Coastguard Worker         goto out;
4840*6236dae4SAndroid Build Coastguard Worker       }
4841*6236dae4SAndroid Build Coastguard Worker       /* socket is readable or writable */
4842*6236dae4SAndroid Build Coastguard Worker     }
4843*6236dae4SAndroid Build Coastguard Worker 
4844*6236dae4SAndroid Build Coastguard Worker     /* Run transaction, and return to the caller if it failed or if this
4845*6236dae4SAndroid Build Coastguard Worker      * connection is done nonblocking and this loop would execute again. This
4846*6236dae4SAndroid Build Coastguard Worker      * permits the owner of a multi handle to abort a connection attempt
4847*6236dae4SAndroid Build Coastguard Worker      * before step2 has completed while ensuring that a client using select()
4848*6236dae4SAndroid Build Coastguard Worker      * or epoll() will always have a valid fdset to wait on.
4849*6236dae4SAndroid Build Coastguard Worker      */
4850*6236dae4SAndroid Build Coastguard Worker     result = ossl_connect_step2(cf, data);
4851*6236dae4SAndroid Build Coastguard Worker     if(result || (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
4852*6236dae4SAndroid Build Coastguard Worker       goto out;
4853*6236dae4SAndroid Build Coastguard Worker 
4854*6236dae4SAndroid Build Coastguard Worker   } /* repeat step2 until all transactions are done. */
4855*6236dae4SAndroid Build Coastguard Worker 
4856*6236dae4SAndroid Build Coastguard Worker   if(ssl_connect_3 == connssl->connecting_state) {
4857*6236dae4SAndroid Build Coastguard Worker     result = ossl_connect_step3(cf, data);
4858*6236dae4SAndroid Build Coastguard Worker     if(result)
4859*6236dae4SAndroid Build Coastguard Worker       goto out;
4860*6236dae4SAndroid Build Coastguard Worker   }
4861*6236dae4SAndroid Build Coastguard Worker 
4862*6236dae4SAndroid Build Coastguard Worker   if(ssl_connect_done == connssl->connecting_state) {
4863*6236dae4SAndroid Build Coastguard Worker     connssl->state = ssl_connection_complete;
4864*6236dae4SAndroid Build Coastguard Worker     *done = TRUE;
4865*6236dae4SAndroid Build Coastguard Worker   }
4866*6236dae4SAndroid Build Coastguard Worker   else
4867*6236dae4SAndroid Build Coastguard Worker     *done = FALSE;
4868*6236dae4SAndroid Build Coastguard Worker 
4869*6236dae4SAndroid Build Coastguard Worker   /* Reset our connect state machine */
4870*6236dae4SAndroid Build Coastguard Worker   connssl->connecting_state = ssl_connect_1;
4871*6236dae4SAndroid Build Coastguard Worker 
4872*6236dae4SAndroid Build Coastguard Worker out:
4873*6236dae4SAndroid Build Coastguard Worker   return result;
4874*6236dae4SAndroid Build Coastguard Worker }
4875*6236dae4SAndroid Build Coastguard Worker 
4876*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_connect_nonblocking(struct Curl_cfilter *cf,
4877*6236dae4SAndroid Build Coastguard Worker                                          struct Curl_easy *data,
4878*6236dae4SAndroid Build Coastguard Worker                                          bool *done)
4879*6236dae4SAndroid Build Coastguard Worker {
4880*6236dae4SAndroid Build Coastguard Worker   return ossl_connect_common(cf, data, TRUE, done);
4881*6236dae4SAndroid Build Coastguard Worker }
4882*6236dae4SAndroid Build Coastguard Worker 
4883*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_connect(struct Curl_cfilter *cf,
4884*6236dae4SAndroid Build Coastguard Worker                              struct Curl_easy *data)
4885*6236dae4SAndroid Build Coastguard Worker {
4886*6236dae4SAndroid Build Coastguard Worker   CURLcode result;
4887*6236dae4SAndroid Build Coastguard Worker   bool done = FALSE;
4888*6236dae4SAndroid Build Coastguard Worker 
4889*6236dae4SAndroid Build Coastguard Worker   result = ossl_connect_common(cf, data, FALSE, &done);
4890*6236dae4SAndroid Build Coastguard Worker   if(result)
4891*6236dae4SAndroid Build Coastguard Worker     return result;
4892*6236dae4SAndroid Build Coastguard Worker 
4893*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(done);
4894*6236dae4SAndroid Build Coastguard Worker 
4895*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
4896*6236dae4SAndroid Build Coastguard Worker }
4897*6236dae4SAndroid Build Coastguard Worker 
4898*6236dae4SAndroid Build Coastguard Worker static bool ossl_data_pending(struct Curl_cfilter *cf,
4899*6236dae4SAndroid Build Coastguard Worker                               const struct Curl_easy *data)
4900*6236dae4SAndroid Build Coastguard Worker {
4901*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
4902*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
4903*6236dae4SAndroid Build Coastguard Worker 
4904*6236dae4SAndroid Build Coastguard Worker   (void)data;
4905*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(connssl && octx);
4906*6236dae4SAndroid Build Coastguard Worker   if(octx->ssl && SSL_pending(octx->ssl))
4907*6236dae4SAndroid Build Coastguard Worker     return TRUE;
4908*6236dae4SAndroid Build Coastguard Worker   return FALSE;
4909*6236dae4SAndroid Build Coastguard Worker }
4910*6236dae4SAndroid Build Coastguard Worker 
4911*6236dae4SAndroid Build Coastguard Worker static ssize_t ossl_send(struct Curl_cfilter *cf,
4912*6236dae4SAndroid Build Coastguard Worker                          struct Curl_easy *data,
4913*6236dae4SAndroid Build Coastguard Worker                          const void *mem,
4914*6236dae4SAndroid Build Coastguard Worker                          size_t len,
4915*6236dae4SAndroid Build Coastguard Worker                          CURLcode *curlcode)
4916*6236dae4SAndroid Build Coastguard Worker {
4917*6236dae4SAndroid Build Coastguard Worker   /* SSL_write() is said to return 'int' while write() and send() returns
4918*6236dae4SAndroid Build Coastguard Worker      'size_t' */
4919*6236dae4SAndroid Build Coastguard Worker   int err;
4920*6236dae4SAndroid Build Coastguard Worker   char error_buffer[256];
4921*6236dae4SAndroid Build Coastguard Worker   sslerr_t sslerror;
4922*6236dae4SAndroid Build Coastguard Worker   int memlen;
4923*6236dae4SAndroid Build Coastguard Worker   int rc;
4924*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
4925*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
4926*6236dae4SAndroid Build Coastguard Worker 
4927*6236dae4SAndroid Build Coastguard Worker   (void)data;
4928*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
4929*6236dae4SAndroid Build Coastguard Worker 
4930*6236dae4SAndroid Build Coastguard Worker   ERR_clear_error();
4931*6236dae4SAndroid Build Coastguard Worker 
4932*6236dae4SAndroid Build Coastguard Worker   connssl->io_need = CURL_SSL_IO_NEED_NONE;
4933*6236dae4SAndroid Build Coastguard Worker   memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
4934*6236dae4SAndroid Build Coastguard Worker   rc = SSL_write(octx->ssl, mem, memlen);
4935*6236dae4SAndroid Build Coastguard Worker 
4936*6236dae4SAndroid Build Coastguard Worker   if(rc <= 0) {
4937*6236dae4SAndroid Build Coastguard Worker     err = SSL_get_error(octx->ssl, rc);
4938*6236dae4SAndroid Build Coastguard Worker 
4939*6236dae4SAndroid Build Coastguard Worker     switch(err) {
4940*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_WANT_READ:
4941*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_RECV;
4942*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_AGAIN;
4943*6236dae4SAndroid Build Coastguard Worker       rc = -1;
4944*6236dae4SAndroid Build Coastguard Worker       goto out;
4945*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_WANT_WRITE:
4946*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_AGAIN;
4947*6236dae4SAndroid Build Coastguard Worker       rc = -1;
4948*6236dae4SAndroid Build Coastguard Worker       goto out;
4949*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_SYSCALL:
4950*6236dae4SAndroid Build Coastguard Worker     {
4951*6236dae4SAndroid Build Coastguard Worker       int sockerr = SOCKERRNO;
4952*6236dae4SAndroid Build Coastguard Worker 
4953*6236dae4SAndroid Build Coastguard Worker       if(octx->io_result == CURLE_AGAIN) {
4954*6236dae4SAndroid Build Coastguard Worker         *curlcode = CURLE_AGAIN;
4955*6236dae4SAndroid Build Coastguard Worker         rc = -1;
4956*6236dae4SAndroid Build Coastguard Worker         goto out;
4957*6236dae4SAndroid Build Coastguard Worker       }
4958*6236dae4SAndroid Build Coastguard Worker       sslerror = ERR_get_error();
4959*6236dae4SAndroid Build Coastguard Worker       if(sslerror)
4960*6236dae4SAndroid Build Coastguard Worker         ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
4961*6236dae4SAndroid Build Coastguard Worker       else if(sockerr)
4962*6236dae4SAndroid Build Coastguard Worker         Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
4963*6236dae4SAndroid Build Coastguard Worker       else
4964*6236dae4SAndroid Build Coastguard Worker         msnprintf(error_buffer, sizeof(error_buffer), "%s",
4965*6236dae4SAndroid Build Coastguard Worker                   SSL_ERROR_to_str(err));
4966*6236dae4SAndroid Build Coastguard Worker 
4967*6236dae4SAndroid Build Coastguard Worker       failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
4968*6236dae4SAndroid Build Coastguard Worker             error_buffer, sockerr);
4969*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_SEND_ERROR;
4970*6236dae4SAndroid Build Coastguard Worker       rc = -1;
4971*6236dae4SAndroid Build Coastguard Worker       goto out;
4972*6236dae4SAndroid Build Coastguard Worker     }
4973*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_SSL: {
4974*6236dae4SAndroid Build Coastguard Worker       /*  A failure in the SSL library occurred, usually a protocol error.
4975*6236dae4SAndroid Build Coastguard Worker           The OpenSSL error queue contains more information on the error. */
4976*6236dae4SAndroid Build Coastguard Worker       sslerror = ERR_get_error();
4977*6236dae4SAndroid Build Coastguard Worker       failf(data, "SSL_write() error: %s",
4978*6236dae4SAndroid Build Coastguard Worker             ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
4979*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_SEND_ERROR;
4980*6236dae4SAndroid Build Coastguard Worker       rc = -1;
4981*6236dae4SAndroid Build Coastguard Worker       goto out;
4982*6236dae4SAndroid Build Coastguard Worker     }
4983*6236dae4SAndroid Build Coastguard Worker     default:
4984*6236dae4SAndroid Build Coastguard Worker       /* a true error */
4985*6236dae4SAndroid Build Coastguard Worker       failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
4986*6236dae4SAndroid Build Coastguard Worker             SSL_ERROR_to_str(err), SOCKERRNO);
4987*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_SEND_ERROR;
4988*6236dae4SAndroid Build Coastguard Worker       rc = -1;
4989*6236dae4SAndroid Build Coastguard Worker       goto out;
4990*6236dae4SAndroid Build Coastguard Worker     }
4991*6236dae4SAndroid Build Coastguard Worker   }
4992*6236dae4SAndroid Build Coastguard Worker   *curlcode = CURLE_OK;
4993*6236dae4SAndroid Build Coastguard Worker 
4994*6236dae4SAndroid Build Coastguard Worker out:
4995*6236dae4SAndroid Build Coastguard Worker   return (ssize_t)rc; /* number of bytes */
4996*6236dae4SAndroid Build Coastguard Worker }
4997*6236dae4SAndroid Build Coastguard Worker 
4998*6236dae4SAndroid Build Coastguard Worker static ssize_t ossl_recv(struct Curl_cfilter *cf,
4999*6236dae4SAndroid Build Coastguard Worker                          struct Curl_easy *data,   /* transfer */
5000*6236dae4SAndroid Build Coastguard Worker                          char *buf,                /* store read data here */
5001*6236dae4SAndroid Build Coastguard Worker                          size_t buffersize,        /* max amount to read */
5002*6236dae4SAndroid Build Coastguard Worker                          CURLcode *curlcode)
5003*6236dae4SAndroid Build Coastguard Worker {
5004*6236dae4SAndroid Build Coastguard Worker   char error_buffer[256];
5005*6236dae4SAndroid Build Coastguard Worker   unsigned long sslerror;
5006*6236dae4SAndroid Build Coastguard Worker   ssize_t nread;
5007*6236dae4SAndroid Build Coastguard Worker   int buffsize;
5008*6236dae4SAndroid Build Coastguard Worker   struct connectdata *conn = cf->conn;
5009*6236dae4SAndroid Build Coastguard Worker   struct ssl_connect_data *connssl = cf->ctx;
5010*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
5011*6236dae4SAndroid Build Coastguard Worker 
5012*6236dae4SAndroid Build Coastguard Worker   (void)data;
5013*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
5014*6236dae4SAndroid Build Coastguard Worker 
5015*6236dae4SAndroid Build Coastguard Worker   ERR_clear_error();
5016*6236dae4SAndroid Build Coastguard Worker 
5017*6236dae4SAndroid Build Coastguard Worker   connssl->io_need = CURL_SSL_IO_NEED_NONE;
5018*6236dae4SAndroid Build Coastguard Worker   buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
5019*6236dae4SAndroid Build Coastguard Worker   nread = (ssize_t)SSL_read(octx->ssl, buf, buffsize);
5020*6236dae4SAndroid Build Coastguard Worker 
5021*6236dae4SAndroid Build Coastguard Worker   if(nread <= 0) {
5022*6236dae4SAndroid Build Coastguard Worker     /* failed SSL_read */
5023*6236dae4SAndroid Build Coastguard Worker     int err = SSL_get_error(octx->ssl, (int)nread);
5024*6236dae4SAndroid Build Coastguard Worker 
5025*6236dae4SAndroid Build Coastguard Worker     switch(err) {
5026*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_NONE: /* this is not an error */
5027*6236dae4SAndroid Build Coastguard Worker       break;
5028*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_ZERO_RETURN: /* no more data */
5029*6236dae4SAndroid Build Coastguard Worker       /* close_notify alert */
5030*6236dae4SAndroid Build Coastguard Worker       if(cf->sockindex == FIRSTSOCKET)
5031*6236dae4SAndroid Build Coastguard Worker         /* mark the connection for close if it is indeed the control
5032*6236dae4SAndroid Build Coastguard Worker            connection */
5033*6236dae4SAndroid Build Coastguard Worker         connclose(conn, "TLS close_notify");
5034*6236dae4SAndroid Build Coastguard Worker       break;
5035*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_WANT_READ:
5036*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_AGAIN;
5037*6236dae4SAndroid Build Coastguard Worker       nread = -1;
5038*6236dae4SAndroid Build Coastguard Worker       goto out;
5039*6236dae4SAndroid Build Coastguard Worker     case SSL_ERROR_WANT_WRITE:
5040*6236dae4SAndroid Build Coastguard Worker       connssl->io_need = CURL_SSL_IO_NEED_SEND;
5041*6236dae4SAndroid Build Coastguard Worker       *curlcode = CURLE_AGAIN;
5042*6236dae4SAndroid Build Coastguard Worker       nread = -1;
5043*6236dae4SAndroid Build Coastguard Worker       goto out;
5044*6236dae4SAndroid Build Coastguard Worker     default:
5045*6236dae4SAndroid Build Coastguard Worker       /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
5046*6236dae4SAndroid Build Coastguard Worker          value/errno" */
5047*6236dae4SAndroid Build Coastguard Worker       /* https://docs.openssl.org/master/man3/ERR_get_error/ */
5048*6236dae4SAndroid Build Coastguard Worker       if(octx->io_result == CURLE_AGAIN) {
5049*6236dae4SAndroid Build Coastguard Worker         *curlcode = CURLE_AGAIN;
5050*6236dae4SAndroid Build Coastguard Worker         nread = -1;
5051*6236dae4SAndroid Build Coastguard Worker         goto out;
5052*6236dae4SAndroid Build Coastguard Worker       }
5053*6236dae4SAndroid Build Coastguard Worker       sslerror = ERR_get_error();
5054*6236dae4SAndroid Build Coastguard Worker       if((nread < 0) || sslerror) {
5055*6236dae4SAndroid Build Coastguard Worker         /* If the return code was negative or there actually is an error in the
5056*6236dae4SAndroid Build Coastguard Worker            queue */
5057*6236dae4SAndroid Build Coastguard Worker         int sockerr = SOCKERRNO;
5058*6236dae4SAndroid Build Coastguard Worker         if(sslerror)
5059*6236dae4SAndroid Build Coastguard Worker           ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
5060*6236dae4SAndroid Build Coastguard Worker         else if(sockerr && err == SSL_ERROR_SYSCALL)
5061*6236dae4SAndroid Build Coastguard Worker           Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
5062*6236dae4SAndroid Build Coastguard Worker         else
5063*6236dae4SAndroid Build Coastguard Worker           msnprintf(error_buffer, sizeof(error_buffer), "%s",
5064*6236dae4SAndroid Build Coastguard Worker                     SSL_ERROR_to_str(err));
5065*6236dae4SAndroid Build Coastguard Worker         failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d",
5066*6236dae4SAndroid Build Coastguard Worker               error_buffer, sockerr);
5067*6236dae4SAndroid Build Coastguard Worker         *curlcode = CURLE_RECV_ERROR;
5068*6236dae4SAndroid Build Coastguard Worker         nread = -1;
5069*6236dae4SAndroid Build Coastguard Worker         goto out;
5070*6236dae4SAndroid Build Coastguard Worker       }
5071*6236dae4SAndroid Build Coastguard Worker       /* For debug builds be a little stricter and error on any
5072*6236dae4SAndroid Build Coastguard Worker          SSL_ERROR_SYSCALL. For example a server may have closed the connection
5073*6236dae4SAndroid Build Coastguard Worker          abruptly without a close_notify alert. For compatibility with older
5074*6236dae4SAndroid Build Coastguard Worker          peers we do not do this by default. #4624
5075*6236dae4SAndroid Build Coastguard Worker 
5076*6236dae4SAndroid Build Coastguard Worker          We can use this to gauge how many users may be affected, and
5077*6236dae4SAndroid Build Coastguard Worker          if it goes ok eventually transition to allow in dev and release with
5078*6236dae4SAndroid Build Coastguard Worker          the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */
5079*6236dae4SAndroid Build Coastguard Worker #ifdef DEBUGBUILD
5080*6236dae4SAndroid Build Coastguard Worker       if(err == SSL_ERROR_SYSCALL) {
5081*6236dae4SAndroid Build Coastguard Worker         int sockerr = SOCKERRNO;
5082*6236dae4SAndroid Build Coastguard Worker         if(sockerr)
5083*6236dae4SAndroid Build Coastguard Worker           Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
5084*6236dae4SAndroid Build Coastguard Worker         else {
5085*6236dae4SAndroid Build Coastguard Worker           msnprintf(error_buffer, sizeof(error_buffer),
5086*6236dae4SAndroid Build Coastguard Worker                     "Connection closed abruptly");
5087*6236dae4SAndroid Build Coastguard Worker         }
5088*6236dae4SAndroid Build Coastguard Worker         failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d"
5089*6236dae4SAndroid Build Coastguard Worker               " (Fatal because this is a curl debug build)",
5090*6236dae4SAndroid Build Coastguard Worker               error_buffer, sockerr);
5091*6236dae4SAndroid Build Coastguard Worker         *curlcode = CURLE_RECV_ERROR;
5092*6236dae4SAndroid Build Coastguard Worker         nread = -1;
5093*6236dae4SAndroid Build Coastguard Worker         goto out;
5094*6236dae4SAndroid Build Coastguard Worker       }
5095*6236dae4SAndroid Build Coastguard Worker #endif
5096*6236dae4SAndroid Build Coastguard Worker     }
5097*6236dae4SAndroid Build Coastguard Worker   }
5098*6236dae4SAndroid Build Coastguard Worker 
5099*6236dae4SAndroid Build Coastguard Worker out:
5100*6236dae4SAndroid Build Coastguard Worker   return nread;
5101*6236dae4SAndroid Build Coastguard Worker }
5102*6236dae4SAndroid Build Coastguard Worker 
5103*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,
5104*6236dae4SAndroid Build Coastguard Worker                                          struct dynbuf *binding)
5105*6236dae4SAndroid Build Coastguard Worker {
5106*6236dae4SAndroid Build Coastguard Worker   /* required for X509_get_signature_nid support */
5107*6236dae4SAndroid Build Coastguard Worker #if OPENSSL_VERSION_NUMBER > 0x10100000L
5108*6236dae4SAndroid Build Coastguard Worker   X509 *cert;
5109*6236dae4SAndroid Build Coastguard Worker   int algo_nid;
5110*6236dae4SAndroid Build Coastguard Worker   const EVP_MD *algo_type;
5111*6236dae4SAndroid Build Coastguard Worker   const char *algo_name;
5112*6236dae4SAndroid Build Coastguard Worker   unsigned int length;
5113*6236dae4SAndroid Build Coastguard Worker   unsigned char buf[EVP_MAX_MD_SIZE];
5114*6236dae4SAndroid Build Coastguard Worker 
5115*6236dae4SAndroid Build Coastguard Worker   const char prefix[] = "tls-server-end-point:";
5116*6236dae4SAndroid Build Coastguard Worker   struct connectdata *conn = data->conn;
5117*6236dae4SAndroid Build Coastguard Worker   struct Curl_cfilter *cf = conn->cfilter[sockindex];
5118*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = NULL;
5119*6236dae4SAndroid Build Coastguard Worker 
5120*6236dae4SAndroid Build Coastguard Worker   do {
5121*6236dae4SAndroid Build Coastguard Worker     const struct Curl_cftype *cft = cf->cft;
5122*6236dae4SAndroid Build Coastguard Worker     struct ssl_connect_data *connssl = cf->ctx;
5123*6236dae4SAndroid Build Coastguard Worker 
5124*6236dae4SAndroid Build Coastguard Worker     if(cft->name && !strcmp(cft->name, "SSL")) {
5125*6236dae4SAndroid Build Coastguard Worker       octx = (struct ossl_ctx *)connssl->backend;
5126*6236dae4SAndroid Build Coastguard Worker       break;
5127*6236dae4SAndroid Build Coastguard Worker     }
5128*6236dae4SAndroid Build Coastguard Worker 
5129*6236dae4SAndroid Build Coastguard Worker     if(cf->next)
5130*6236dae4SAndroid Build Coastguard Worker       cf = cf->next;
5131*6236dae4SAndroid Build Coastguard Worker 
5132*6236dae4SAndroid Build Coastguard Worker   } while(cf->next);
5133*6236dae4SAndroid Build Coastguard Worker 
5134*6236dae4SAndroid Build Coastguard Worker   if(!octx) {
5135*6236dae4SAndroid Build Coastguard Worker     failf(data, "Failed to find the SSL filter");
5136*6236dae4SAndroid Build Coastguard Worker     return CURLE_BAD_FUNCTION_ARGUMENT;
5137*6236dae4SAndroid Build Coastguard Worker   }
5138*6236dae4SAndroid Build Coastguard Worker 
5139*6236dae4SAndroid Build Coastguard Worker   cert = SSL_get1_peer_certificate(octx->ssl);
5140*6236dae4SAndroid Build Coastguard Worker   if(!cert) {
5141*6236dae4SAndroid Build Coastguard Worker     /* No server certificate, don't do channel binding */
5142*6236dae4SAndroid Build Coastguard Worker     return CURLE_OK;
5143*6236dae4SAndroid Build Coastguard Worker   }
5144*6236dae4SAndroid Build Coastguard Worker 
5145*6236dae4SAndroid Build Coastguard Worker   if(!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &algo_nid, NULL)) {
5146*6236dae4SAndroid Build Coastguard Worker     failf(data,
5147*6236dae4SAndroid Build Coastguard Worker           "Unable to find digest NID for certificate signature algorithm");
5148*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_INVALIDCERTSTATUS;
5149*6236dae4SAndroid Build Coastguard Worker   }
5150*6236dae4SAndroid Build Coastguard Worker 
5151*6236dae4SAndroid Build Coastguard Worker   /* https://datatracker.ietf.org/doc/html/rfc5929#section-4.1 */
5152*6236dae4SAndroid Build Coastguard Worker   if(algo_nid == NID_md5 || algo_nid == NID_sha1) {
5153*6236dae4SAndroid Build Coastguard Worker     algo_type = EVP_sha256();
5154*6236dae4SAndroid Build Coastguard Worker   }
5155*6236dae4SAndroid Build Coastguard Worker   else {
5156*6236dae4SAndroid Build Coastguard Worker     algo_type = EVP_get_digestbynid(algo_nid);
5157*6236dae4SAndroid Build Coastguard Worker     if(!algo_type) {
5158*6236dae4SAndroid Build Coastguard Worker       algo_name = OBJ_nid2sn(algo_nid);
5159*6236dae4SAndroid Build Coastguard Worker       failf(data, "Could not find digest algorithm %s (NID %d)",
5160*6236dae4SAndroid Build Coastguard Worker             algo_name ? algo_name : "(null)", algo_nid);
5161*6236dae4SAndroid Build Coastguard Worker       return CURLE_SSL_INVALIDCERTSTATUS;
5162*6236dae4SAndroid Build Coastguard Worker     }
5163*6236dae4SAndroid Build Coastguard Worker   }
5164*6236dae4SAndroid Build Coastguard Worker 
5165*6236dae4SAndroid Build Coastguard Worker   if(!X509_digest(cert, algo_type, buf, &length)) {
5166*6236dae4SAndroid Build Coastguard Worker     failf(data, "X509_digest() failed");
5167*6236dae4SAndroid Build Coastguard Worker     return CURLE_SSL_INVALIDCERTSTATUS;
5168*6236dae4SAndroid Build Coastguard Worker   }
5169*6236dae4SAndroid Build Coastguard Worker 
5170*6236dae4SAndroid Build Coastguard Worker   /* Append "tls-server-end-point:" */
5171*6236dae4SAndroid Build Coastguard Worker   if(Curl_dyn_addn(binding, prefix, sizeof(prefix) - 1) != CURLE_OK)
5172*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
5173*6236dae4SAndroid Build Coastguard Worker   /* Append digest */
5174*6236dae4SAndroid Build Coastguard Worker   if(Curl_dyn_addn(binding, buf, length))
5175*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
5176*6236dae4SAndroid Build Coastguard Worker 
5177*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
5178*6236dae4SAndroid Build Coastguard Worker #else
5179*6236dae4SAndroid Build Coastguard Worker   /* No X509_get_signature_nid support */
5180*6236dae4SAndroid Build Coastguard Worker   (void)data; /* unused */
5181*6236dae4SAndroid Build Coastguard Worker   (void)sockindex; /* unused */
5182*6236dae4SAndroid Build Coastguard Worker   (void)binding; /* unused */
5183*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
5184*6236dae4SAndroid Build Coastguard Worker #endif
5185*6236dae4SAndroid Build Coastguard Worker }
5186*6236dae4SAndroid Build Coastguard Worker 
5187*6236dae4SAndroid Build Coastguard Worker static size_t ossl_version(char *buffer, size_t size)
5188*6236dae4SAndroid Build Coastguard Worker {
5189*6236dae4SAndroid Build Coastguard Worker #ifdef LIBRESSL_VERSION_NUMBER
5190*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_OPENSSL_VERSION
5191*6236dae4SAndroid Build Coastguard Worker   char *p;
5192*6236dae4SAndroid Build Coastguard Worker   size_t count;
5193*6236dae4SAndroid Build Coastguard Worker   const char *ver = OpenSSL_version(OPENSSL_VERSION);
5194*6236dae4SAndroid Build Coastguard Worker   const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */
5195*6236dae4SAndroid Build Coastguard Worker   if(strncasecompare(ver, expected, sizeof(expected) - 1)) {
5196*6236dae4SAndroid Build Coastguard Worker     ver += sizeof(expected) - 1;
5197*6236dae4SAndroid Build Coastguard Worker   }
5198*6236dae4SAndroid Build Coastguard Worker   count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver);
5199*6236dae4SAndroid Build Coastguard Worker   for(p = buffer; *p; ++p) {
5200*6236dae4SAndroid Build Coastguard Worker     if(ISBLANK(*p))
5201*6236dae4SAndroid Build Coastguard Worker       *p = '_';
5202*6236dae4SAndroid Build Coastguard Worker   }
5203*6236dae4SAndroid Build Coastguard Worker   return count;
5204*6236dae4SAndroid Build Coastguard Worker #else
5205*6236dae4SAndroid Build Coastguard Worker   return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
5206*6236dae4SAndroid Build Coastguard Worker                    OSSL_PACKAGE,
5207*6236dae4SAndroid Build Coastguard Worker                    (LIBRESSL_VERSION_NUMBER >> 28) & 0xf,
5208*6236dae4SAndroid Build Coastguard Worker                    (LIBRESSL_VERSION_NUMBER >> 20) & 0xff,
5209*6236dae4SAndroid Build Coastguard Worker                    (LIBRESSL_VERSION_NUMBER >> 12) & 0xff);
5210*6236dae4SAndroid Build Coastguard Worker #endif
5211*6236dae4SAndroid Build Coastguard Worker #elif defined(OPENSSL_IS_BORINGSSL)
5212*6236dae4SAndroid Build Coastguard Worker #ifdef CURL_BORINGSSL_VERSION
5213*6236dae4SAndroid Build Coastguard Worker   return msnprintf(buffer, size, "%s/%s",
5214*6236dae4SAndroid Build Coastguard Worker                    OSSL_PACKAGE,
5215*6236dae4SAndroid Build Coastguard Worker                    CURL_BORINGSSL_VERSION);
5216*6236dae4SAndroid Build Coastguard Worker #else
5217*6236dae4SAndroid Build Coastguard Worker   return msnprintf(buffer, size, OSSL_PACKAGE);
5218*6236dae4SAndroid Build Coastguard Worker #endif
5219*6236dae4SAndroid Build Coastguard Worker #elif defined(OPENSSL_IS_AWSLC)
5220*6236dae4SAndroid Build Coastguard Worker   return msnprintf(buffer, size, "%s/%s",
5221*6236dae4SAndroid Build Coastguard Worker                    OSSL_PACKAGE,
5222*6236dae4SAndroid Build Coastguard Worker                    AWSLC_VERSION_NUMBER_STRING);
5223*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING)
5224*6236dae4SAndroid Build Coastguard Worker   return msnprintf(buffer, size, "%s/%s",
5225*6236dae4SAndroid Build Coastguard Worker                    OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING));
5226*6236dae4SAndroid Build Coastguard Worker #else
5227*6236dae4SAndroid Build Coastguard Worker   /* not LibreSSL, BoringSSL and not using OpenSSL_version */
5228*6236dae4SAndroid Build Coastguard Worker 
5229*6236dae4SAndroid Build Coastguard Worker   char sub[3];
5230*6236dae4SAndroid Build Coastguard Worker   unsigned long ssleay_value;
5231*6236dae4SAndroid Build Coastguard Worker   sub[2]='\0';
5232*6236dae4SAndroid Build Coastguard Worker   sub[1]='\0';
5233*6236dae4SAndroid Build Coastguard Worker   ssleay_value = OpenSSL_version_num();
5234*6236dae4SAndroid Build Coastguard Worker   if(ssleay_value < 0x906000) {
5235*6236dae4SAndroid Build Coastguard Worker     ssleay_value = SSLEAY_VERSION_NUMBER;
5236*6236dae4SAndroid Build Coastguard Worker     sub[0]='\0';
5237*6236dae4SAndroid Build Coastguard Worker   }
5238*6236dae4SAndroid Build Coastguard Worker   else {
5239*6236dae4SAndroid Build Coastguard Worker     if(ssleay_value&0xff0) {
5240*6236dae4SAndroid Build Coastguard Worker       int minor_ver = (ssleay_value >> 4) & 0xff;
5241*6236dae4SAndroid Build Coastguard Worker       if(minor_ver > 26) {
5242*6236dae4SAndroid Build Coastguard Worker         /* handle extended version introduced for 0.9.8za */
5243*6236dae4SAndroid Build Coastguard Worker         sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1);
5244*6236dae4SAndroid Build Coastguard Worker         sub[0] = 'z';
5245*6236dae4SAndroid Build Coastguard Worker       }
5246*6236dae4SAndroid Build Coastguard Worker       else {
5247*6236dae4SAndroid Build Coastguard Worker         sub[0] = (char) (minor_ver + 'a' - 1);
5248*6236dae4SAndroid Build Coastguard Worker       }
5249*6236dae4SAndroid Build Coastguard Worker     }
5250*6236dae4SAndroid Build Coastguard Worker     else
5251*6236dae4SAndroid Build Coastguard Worker       sub[0]='\0';
5252*6236dae4SAndroid Build Coastguard Worker   }
5253*6236dae4SAndroid Build Coastguard Worker 
5254*6236dae4SAndroid Build Coastguard Worker   return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s"
5255*6236dae4SAndroid Build Coastguard Worker #ifdef OPENSSL_FIPS
5256*6236dae4SAndroid Build Coastguard Worker                    "-fips"
5257*6236dae4SAndroid Build Coastguard Worker #endif
5258*6236dae4SAndroid Build Coastguard Worker                    ,
5259*6236dae4SAndroid Build Coastguard Worker                    OSSL_PACKAGE,
5260*6236dae4SAndroid Build Coastguard Worker                    (ssleay_value >> 28) & 0xf,
5261*6236dae4SAndroid Build Coastguard Worker                    (ssleay_value >> 20) & 0xff,
5262*6236dae4SAndroid Build Coastguard Worker                    (ssleay_value >> 12) & 0xff,
5263*6236dae4SAndroid Build Coastguard Worker                    sub);
5264*6236dae4SAndroid Build Coastguard Worker #endif /* OPENSSL_IS_BORINGSSL */
5265*6236dae4SAndroid Build Coastguard Worker }
5266*6236dae4SAndroid Build Coastguard Worker 
5267*6236dae4SAndroid Build Coastguard Worker /* can be called with data == NULL */
5268*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_random(struct Curl_easy *data,
5269*6236dae4SAndroid Build Coastguard Worker                             unsigned char *entropy, size_t length)
5270*6236dae4SAndroid Build Coastguard Worker {
5271*6236dae4SAndroid Build Coastguard Worker   int rc;
5272*6236dae4SAndroid Build Coastguard Worker   if(data) {
5273*6236dae4SAndroid Build Coastguard Worker     if(ossl_seed(data)) /* Initiate the seed if not already done */
5274*6236dae4SAndroid Build Coastguard Worker       return CURLE_FAILED_INIT; /* could not seed for some reason */
5275*6236dae4SAndroid Build Coastguard Worker   }
5276*6236dae4SAndroid Build Coastguard Worker   else {
5277*6236dae4SAndroid Build Coastguard Worker     if(!rand_enough())
5278*6236dae4SAndroid Build Coastguard Worker       return CURLE_FAILED_INIT;
5279*6236dae4SAndroid Build Coastguard Worker   }
5280*6236dae4SAndroid Build Coastguard Worker   /* RAND_bytes() returns 1 on success, 0 otherwise.  */
5281*6236dae4SAndroid Build Coastguard Worker   rc = RAND_bytes(entropy, (ossl_valsize_t)curlx_uztosi(length));
5282*6236dae4SAndroid Build Coastguard Worker   return (rc == 1 ? CURLE_OK : CURLE_FAILED_INIT);
5283*6236dae4SAndroid Build Coastguard Worker }
5284*6236dae4SAndroid Build Coastguard Worker 
5285*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
5286*6236dae4SAndroid Build Coastguard Worker static CURLcode ossl_sha256sum(const unsigned char *tmp, /* input */
5287*6236dae4SAndroid Build Coastguard Worker                                size_t tmplen,
5288*6236dae4SAndroid Build Coastguard Worker                                unsigned char *sha256sum /* output */,
5289*6236dae4SAndroid Build Coastguard Worker                                size_t unused)
5290*6236dae4SAndroid Build Coastguard Worker {
5291*6236dae4SAndroid Build Coastguard Worker   EVP_MD_CTX *mdctx;
5292*6236dae4SAndroid Build Coastguard Worker   unsigned int len = 0;
5293*6236dae4SAndroid Build Coastguard Worker   (void) unused;
5294*6236dae4SAndroid Build Coastguard Worker 
5295*6236dae4SAndroid Build Coastguard Worker   mdctx = EVP_MD_CTX_create();
5296*6236dae4SAndroid Build Coastguard Worker   if(!mdctx)
5297*6236dae4SAndroid Build Coastguard Worker     return CURLE_OUT_OF_MEMORY;
5298*6236dae4SAndroid Build Coastguard Worker   if(!EVP_DigestInit(mdctx, EVP_sha256())) {
5299*6236dae4SAndroid Build Coastguard Worker     EVP_MD_CTX_destroy(mdctx);
5300*6236dae4SAndroid Build Coastguard Worker     return CURLE_FAILED_INIT;
5301*6236dae4SAndroid Build Coastguard Worker   }
5302*6236dae4SAndroid Build Coastguard Worker   EVP_DigestUpdate(mdctx, tmp, tmplen);
5303*6236dae4SAndroid Build Coastguard Worker   EVP_DigestFinal_ex(mdctx, sha256sum, &len);
5304*6236dae4SAndroid Build Coastguard Worker   EVP_MD_CTX_destroy(mdctx);
5305*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
5306*6236dae4SAndroid Build Coastguard Worker }
5307*6236dae4SAndroid Build Coastguard Worker #endif
5308*6236dae4SAndroid Build Coastguard Worker 
5309*6236dae4SAndroid Build Coastguard Worker static bool ossl_cert_status_request(void)
5310*6236dae4SAndroid Build Coastguard Worker {
5311*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
5312*6236dae4SAndroid Build Coastguard Worker   !defined(OPENSSL_NO_OCSP)
5313*6236dae4SAndroid Build Coastguard Worker   return TRUE;
5314*6236dae4SAndroid Build Coastguard Worker #else
5315*6236dae4SAndroid Build Coastguard Worker   return FALSE;
5316*6236dae4SAndroid Build Coastguard Worker #endif
5317*6236dae4SAndroid Build Coastguard Worker }
5318*6236dae4SAndroid Build Coastguard Worker 
5319*6236dae4SAndroid Build Coastguard Worker static void *ossl_get_internals(struct ssl_connect_data *connssl,
5320*6236dae4SAndroid Build Coastguard Worker                                 CURLINFO info)
5321*6236dae4SAndroid Build Coastguard Worker {
5322*6236dae4SAndroid Build Coastguard Worker   /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
5323*6236dae4SAndroid Build Coastguard Worker   struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
5324*6236dae4SAndroid Build Coastguard Worker   DEBUGASSERT(octx);
5325*6236dae4SAndroid Build Coastguard Worker   return info == CURLINFO_TLS_SESSION ?
5326*6236dae4SAndroid Build Coastguard Worker     (void *)octx->ssl_ctx : (void *)octx->ssl;
5327*6236dae4SAndroid Build Coastguard Worker }
5328*6236dae4SAndroid Build Coastguard Worker 
5329*6236dae4SAndroid Build Coastguard Worker const struct Curl_ssl Curl_ssl_openssl = {
5330*6236dae4SAndroid Build Coastguard Worker   { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */
5331*6236dae4SAndroid Build Coastguard Worker 
5332*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_CA_PATH |
5333*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_CAINFO_BLOB |
5334*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_CERTINFO |
5335*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_PINNEDPUBKEY |
5336*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_SSL_CTX |
5337*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
5338*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_TLS13_CIPHERSUITES |
5339*6236dae4SAndroid Build Coastguard Worker #endif
5340*6236dae4SAndroid Build Coastguard Worker #ifdef USE_ECH
5341*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_ECH |
5342*6236dae4SAndroid Build Coastguard Worker #endif
5343*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_CA_CACHE |
5344*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_HTTPS_PROXY |
5345*6236dae4SAndroid Build Coastguard Worker   SSLSUPP_CIPHER_LIST,
5346*6236dae4SAndroid Build Coastguard Worker 
5347*6236dae4SAndroid Build Coastguard Worker   sizeof(struct ossl_ctx),
5348*6236dae4SAndroid Build Coastguard Worker 
5349*6236dae4SAndroid Build Coastguard Worker   ossl_init,                /* init */
5350*6236dae4SAndroid Build Coastguard Worker   ossl_cleanup,             /* cleanup */
5351*6236dae4SAndroid Build Coastguard Worker   ossl_version,             /* version */
5352*6236dae4SAndroid Build Coastguard Worker   Curl_none_check_cxn,      /* check_cxn */
5353*6236dae4SAndroid Build Coastguard Worker   ossl_shutdown,            /* shutdown */
5354*6236dae4SAndroid Build Coastguard Worker   ossl_data_pending,        /* data_pending */
5355*6236dae4SAndroid Build Coastguard Worker   ossl_random,              /* random */
5356*6236dae4SAndroid Build Coastguard Worker   ossl_cert_status_request, /* cert_status_request */
5357*6236dae4SAndroid Build Coastguard Worker   ossl_connect,             /* connect */
5358*6236dae4SAndroid Build Coastguard Worker   ossl_connect_nonblocking, /* connect_nonblocking */
5359*6236dae4SAndroid Build Coastguard Worker   Curl_ssl_adjust_pollset,  /* adjust_pollset */
5360*6236dae4SAndroid Build Coastguard Worker   ossl_get_internals,       /* get_internals */
5361*6236dae4SAndroid Build Coastguard Worker   ossl_close,               /* close_one */
5362*6236dae4SAndroid Build Coastguard Worker   ossl_close_all,           /* close_all */
5363*6236dae4SAndroid Build Coastguard Worker   ossl_set_engine,          /* set_engine */
5364*6236dae4SAndroid Build Coastguard Worker   ossl_set_engine_default,  /* set_engine_default */
5365*6236dae4SAndroid Build Coastguard Worker   ossl_engines_list,        /* engines_list */
5366*6236dae4SAndroid Build Coastguard Worker   Curl_none_false_start,    /* false_start */
5367*6236dae4SAndroid Build Coastguard Worker #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
5368*6236dae4SAndroid Build Coastguard Worker   ossl_sha256sum,           /* sha256sum */
5369*6236dae4SAndroid Build Coastguard Worker #else
5370*6236dae4SAndroid Build Coastguard Worker   NULL,                     /* sha256sum */
5371*6236dae4SAndroid Build Coastguard Worker #endif
5372*6236dae4SAndroid Build Coastguard Worker   NULL,                     /* use of data in this connection */
5373*6236dae4SAndroid Build Coastguard Worker   NULL,                     /* remote of data from this connection */
5374*6236dae4SAndroid Build Coastguard Worker   ossl_recv,                /* recv decrypted data */
5375*6236dae4SAndroid Build Coastguard Worker   ossl_send,                /* send data to encrypt */
5376*6236dae4SAndroid Build Coastguard Worker   ossl_get_channel_binding  /* get_channel_binding */
5377*6236dae4SAndroid Build Coastguard Worker };
5378*6236dae4SAndroid Build Coastguard Worker 
5379*6236dae4SAndroid Build Coastguard Worker #endif /* USE_OPENSSL */
5380