Coverage Report

Created: 2026-01-17 06:34

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