Coverage Report

Created: 2026-09-14 07:04

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