Coverage Report

Created: 2026-10-22 06:56

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