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, ¶ms, 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