Coverage Report

Created: 2025-11-24 06:58

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