Coverage Report

Created: 2025-11-11 06:17

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