Coverage Report

Created: 2026-10-22 06:48

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