Coverage Report

Created: 2026-01-09 07:14

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