Coverage Report

Created: 2026-04-12 06:59

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