Coverage Report

Created: 2025-10-10 06:31

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