Coverage Report

Created: 2025-11-11 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/isc/tls.c
Line
Count
Source
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
#include <inttypes.h>
15
#include <netinet/in.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <sys/socket.h>
19
#if HAVE_LIBNGHTTP2
20
#include <nghttp2/nghttp2.h>
21
#endif /* HAVE_LIBNGHTTP2 */
22
#include <arpa/inet.h>
23
24
#include <openssl/bn.h>
25
#include <openssl/conf.h>
26
#include <openssl/crypto.h>
27
#include <openssl/dh.h>
28
#include <openssl/err.h>
29
#include <openssl/evp.h>
30
#include <openssl/opensslv.h>
31
#include <openssl/rand.h>
32
#include <openssl/rsa.h>
33
#include <openssl/x509_vfy.h>
34
#include <openssl/x509v3.h>
35
36
#include <isc/atomic.h>
37
#include <isc/crypto.h>
38
#include <isc/ht.h>
39
#include <isc/log.h>
40
#include <isc/magic.h>
41
#include <isc/mem.h>
42
#include <isc/mutex.h>
43
#include <isc/once.h>
44
#include <isc/random.h>
45
#include <isc/refcount.h>
46
#include <isc/rwlock.h>
47
#include <isc/sockaddr.h>
48
#include <isc/thread.h>
49
#include <isc/tls.h>
50
#include <isc/util.h>
51
52
#include "openssl_shim.h"
53
54
#define COMMON_SSL_OPTIONS \
55
0
  (SSL_OP_NO_COMPRESSION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
56
57
void
58
0
isc_tlsctx_free(isc_tlsctx_t **ctxp) {
59
0
  SSL_CTX *ctx = NULL;
60
0
  REQUIRE(ctxp != NULL && *ctxp != NULL);
61
62
0
  ctx = *ctxp;
63
0
  *ctxp = NULL;
64
65
0
  SSL_CTX_free(ctx);
66
0
}
67
68
void
69
0
isc_tlsctx_attach(isc_tlsctx_t *src, isc_tlsctx_t **ptarget) {
70
0
  REQUIRE(src != NULL);
71
0
  REQUIRE(ptarget != NULL && *ptarget == NULL);
72
73
0
  RUNTIME_CHECK(SSL_CTX_up_ref(src) == 1);
74
75
0
  *ptarget = src;
76
0
}
77
78
/*
79
 * Callback invoked by the SSL library whenever a new TLS pre-master secret
80
 * needs to be logged.
81
 */
82
static void
83
0
sslkeylogfile_append(const SSL *ssl ISC_ATTR_UNUSED, const char *line) {
84
0
  isc_log_write(ISC_LOGCATEGORY_SSLKEYLOG, ISC_LOGMODULE_CRYPTO,
85
0
          ISC_LOG_INFO, "%s", line);
86
0
}
87
88
/*
89
 * Enable TLS pre-master secret logging if the SSLKEYLOGFILE environment
90
 * variable is set.  This needs to be done on a per-context basis as that is
91
 * how SSL_CTX_set_keylog_callback() works.
92
 */
93
static void
94
0
sslkeylogfile_init(isc_tlsctx_t *ctx) {
95
0
  if (getenv("SSLKEYLOGFILE") != NULL) {
96
0
    SSL_CTX_set_keylog_callback(ctx, sslkeylogfile_append);
97
0
  }
98
0
}
99
100
isc_result_t
101
0
isc_tlsctx_createclient(isc_tlsctx_t **ctxp) {
102
0
  unsigned long err;
103
0
  char errbuf[256];
104
0
  SSL_CTX *ctx = NULL;
105
0
  const SSL_METHOD *method = NULL;
106
107
0
  REQUIRE(ctxp != NULL && *ctxp == NULL);
108
109
0
  method = TLS_client_method();
110
0
  if (method == NULL) {
111
0
    goto ssl_error;
112
0
  }
113
0
  ctx = SSL_CTX_new(method);
114
0
  if (ctx == NULL) {
115
0
    goto ssl_error;
116
0
  }
117
118
0
  SSL_CTX_set_options(ctx, COMMON_SSL_OPTIONS);
119
120
0
  SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
121
122
0
  sslkeylogfile_init(ctx);
123
124
0
  *ctxp = ctx;
125
126
0
  return ISC_R_SUCCESS;
127
128
0
ssl_error:
129
0
  err = ERR_get_error();
130
0
  ERR_error_string_n(err, errbuf, sizeof(errbuf));
131
0
  isc_log_write(ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
132
0
          ISC_LOG_ERROR, "Error initializing TLS context: %s",
133
0
          errbuf);
134
135
0
  return ISC_R_TLSERROR;
136
0
}
137
138
isc_result_t
139
isc_tlsctx_load_certificate(isc_tlsctx_t *ctx, const char *keyfile,
140
0
          const char *certfile) {
141
0
  int rv;
142
0
  REQUIRE(ctx != NULL);
143
0
  REQUIRE(keyfile != NULL);
144
0
  REQUIRE(certfile != NULL);
145
146
0
  rv = SSL_CTX_use_certificate_chain_file(ctx, certfile);
147
0
  if (rv != 1) {
148
0
    unsigned long err = ERR_peek_last_error();
149
0
    char errbuf[1024] = { 0 };
150
0
    ERR_error_string_n(err, errbuf, sizeof(errbuf));
151
0
    isc_log_write(
152
0
      ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
153
0
      ISC_LOG_ERROR,
154
0
      "SSL_CTX_use_certificate_chain_file: '%s' failed: %s",
155
0
      certfile, errbuf);
156
0
    return ISC_R_TLSERROR;
157
0
  }
158
0
  rv = SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM);
159
0
  if (rv != 1) {
160
0
    unsigned long err = ERR_peek_last_error();
161
0
    char errbuf[1024] = { 0 };
162
0
    ERR_error_string_n(err, errbuf, sizeof(errbuf));
163
0
    isc_log_write(ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
164
0
            ISC_LOG_ERROR,
165
0
            "SSL_CTX_use_PrivateKey_file: '%s' failed: %s",
166
0
            keyfile, errbuf);
167
0
    return ISC_R_TLSERROR;
168
0
  }
169
170
0
  return ISC_R_SUCCESS;
171
0
}
172
173
isc_result_t
174
isc_tlsctx_createserver(const char *keyfile, const char *certfile,
175
0
      isc_tlsctx_t **ctxp) {
176
0
  int rv;
177
0
  unsigned long err;
178
0
  bool ephemeral = (keyfile == NULL && certfile == NULL);
179
0
  X509 *cert = NULL;
180
0
  EVP_PKEY *pkey = NULL;
181
0
  SSL_CTX *ctx = NULL;
182
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
183
0
  EC_KEY *eckey = NULL;
184
#else
185
  EVP_PKEY_CTX *pkey_ctx = NULL;
186
  EVP_PKEY *params_pkey = NULL;
187
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
188
0
  char errbuf[256];
189
0
  const SSL_METHOD *method = NULL;
190
191
0
  REQUIRE(ctxp != NULL && *ctxp == NULL);
192
0
  REQUIRE((keyfile == NULL) == (certfile == NULL));
193
194
0
  method = TLS_server_method();
195
0
  if (method == NULL) {
196
0
    goto ssl_error;
197
0
  }
198
0
  ctx = SSL_CTX_new(method);
199
0
  if (ctx == NULL) {
200
0
    goto ssl_error;
201
0
  }
202
0
  RUNTIME_CHECK(ctx != NULL);
203
204
0
  SSL_CTX_set_options(ctx, COMMON_SSL_OPTIONS);
205
206
0
  SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
207
208
0
  if (ephemeral) {
209
0
    const int group_nid = NID_X9_62_prime256v1;
210
211
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
212
0
    eckey = EC_KEY_new_by_curve_name(group_nid);
213
0
    if (eckey == NULL) {
214
0
      goto ssl_error;
215
0
    }
216
217
    /* Generate the key. */
218
0
    rv = EC_KEY_generate_key(eckey);
219
0
    if (rv != 1) {
220
0
      goto ssl_error;
221
0
    }
222
0
    pkey = EVP_PKEY_new();
223
0
    if (pkey == NULL) {
224
0
      goto ssl_error;
225
0
    }
226
0
    rv = EVP_PKEY_set1_EC_KEY(pkey, eckey);
227
0
    if (rv != 1) {
228
0
      goto ssl_error;
229
0
    }
230
231
    /* Use a named curve and uncompressed point conversion form. */
232
0
    EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(pkey),
233
0
             OPENSSL_EC_NAMED_CURVE);
234
0
    EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(pkey),
235
0
             POINT_CONVERSION_UNCOMPRESSED);
236
237
    /* Cleanup */
238
0
    EC_KEY_free(eckey);
239
0
    eckey = NULL;
240
#else
241
    /* Generate the key's parameters. */
242
    pkey_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
243
    if (pkey_ctx == NULL) {
244
      goto ssl_error;
245
    }
246
    rv = EVP_PKEY_paramgen_init(pkey_ctx);
247
    if (rv != 1) {
248
      goto ssl_error;
249
    }
250
    rv = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkey_ctx,
251
                  group_nid);
252
    if (rv != 1) {
253
      goto ssl_error;
254
    }
255
    rv = EVP_PKEY_paramgen(pkey_ctx, &params_pkey);
256
    if (rv != 1 || params_pkey == NULL) {
257
      goto ssl_error;
258
    }
259
    EVP_PKEY_CTX_free(pkey_ctx);
260
261
    /* Generate the key. */
262
    pkey_ctx = EVP_PKEY_CTX_new(params_pkey, NULL);
263
    if (pkey_ctx == NULL) {
264
      goto ssl_error;
265
    }
266
    rv = EVP_PKEY_keygen_init(pkey_ctx);
267
    if (rv != 1) {
268
      goto ssl_error;
269
    }
270
    rv = EVP_PKEY_keygen(pkey_ctx, &pkey);
271
    if (rv != 1 || pkey == NULL) {
272
      goto ssl_error;
273
    }
274
275
    /* Cleanup */
276
    EVP_PKEY_free(params_pkey);
277
    params_pkey = NULL;
278
    EVP_PKEY_CTX_free(pkey_ctx);
279
    pkey_ctx = NULL;
280
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
281
282
0
    cert = X509_new();
283
0
    if (cert == NULL) {
284
0
      goto ssl_error;
285
0
    }
286
287
0
    ASN1_INTEGER_set(X509_get_serialNumber(cert),
288
0
         (long)isc_random32());
289
290
    /*
291
     * Set the "not before" property 5 minutes into the past to
292
     * accommodate with some possible clock skew across systems.
293
     */
294
0
    X509_gmtime_adj(X509_getm_notBefore(cert), -300);
295
296
    /*
297
     * We set the vailidy for 10 years.
298
     */
299
0
    X509_gmtime_adj(X509_getm_notAfter(cert), 3650 * 24 * 3600);
300
301
0
    X509_set_pubkey(cert, pkey);
302
303
0
    X509_NAME *name = X509_get_subject_name(cert);
304
305
0
    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
306
0
             (const unsigned char *)"AQ", -1, -1,
307
0
             0);
308
0
    X509_NAME_add_entry_by_txt(
309
0
      name, "O", MBSTRING_ASC,
310
0
      (const unsigned char *)"BIND9 ephemeral "
311
0
                 "certificate",
312
0
      -1, -1, 0);
313
0
    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
314
0
             (const unsigned char *)"bind9.local",
315
0
             -1, -1, 0);
316
317
0
    X509_set_issuer_name(cert, name);
318
0
    X509_sign(cert, pkey, isc__crypto_sha256);
319
0
    rv = SSL_CTX_use_certificate(ctx, cert);
320
0
    if (rv != 1) {
321
0
      goto ssl_error;
322
0
    }
323
0
    rv = SSL_CTX_use_PrivateKey(ctx, pkey);
324
0
    if (rv != 1) {
325
0
      goto ssl_error;
326
0
    }
327
328
0
    X509_free(cert);
329
0
    EVP_PKEY_free(pkey);
330
0
  } else {
331
0
    isc_result_t result;
332
0
    result = isc_tlsctx_load_certificate(ctx, keyfile, certfile);
333
0
    if (result != ISC_R_SUCCESS) {
334
0
      goto ssl_error;
335
0
    }
336
0
  }
337
338
0
  sslkeylogfile_init(ctx);
339
340
0
  *ctxp = ctx;
341
0
  return ISC_R_SUCCESS;
342
343
0
ssl_error:
344
0
  err = ERR_get_error();
345
0
  ERR_error_string_n(err, errbuf, sizeof(errbuf));
346
0
  isc_log_write(ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
347
0
          ISC_LOG_ERROR, "Error initializing TLS context: %s",
348
0
          errbuf);
349
350
0
  if (ctx != NULL) {
351
0
    SSL_CTX_free(ctx);
352
0
  }
353
0
  if (cert != NULL) {
354
0
    X509_free(cert);
355
0
  }
356
0
  if (pkey != NULL) {
357
0
    EVP_PKEY_free(pkey);
358
0
  }
359
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
360
0
  if (eckey != NULL) {
361
0
    EC_KEY_free(eckey);
362
0
  }
363
#else
364
  if (params_pkey != NULL) {
365
    EVP_PKEY_free(params_pkey);
366
  }
367
  if (pkey_ctx != NULL) {
368
    EVP_PKEY_CTX_free(pkey_ctx);
369
  }
370
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
371
372
0
  return ISC_R_TLSERROR;
373
0
}
374
375
static long
376
0
get_tls_version_disable_bit(const isc_tls_protocol_version_t tls_ver) {
377
0
  long bit = 0;
378
379
0
  switch (tls_ver) {
380
0
  case ISC_TLS_PROTO_VER_1_2:
381
0
#ifdef SSL_OP_NO_TLSv1_2
382
0
    bit = SSL_OP_NO_TLSv1_2;
383
#else
384
    bit = 0;
385
#endif
386
0
    break;
387
0
  case ISC_TLS_PROTO_VER_1_3:
388
0
#ifdef SSL_OP_NO_TLSv1_3
389
0
    bit = SSL_OP_NO_TLSv1_3;
390
#else
391
    bit = 0;
392
#endif
393
0
    break;
394
0
  default:
395
0
    UNREACHABLE();
396
0
    break;
397
0
  };
398
399
0
  return bit;
400
0
}
401
402
bool
403
0
isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver) {
404
0
  return get_tls_version_disable_bit(tls_ver) != 0;
405
0
}
406
407
isc_tls_protocol_version_t
408
0
isc_tls_protocol_name_to_version(const char *name) {
409
0
  REQUIRE(name != NULL);
410
411
0
  if (strcasecmp(name, "TLSv1.2") == 0) {
412
0
    return ISC_TLS_PROTO_VER_1_2;
413
0
  } else if (strcasecmp(name, "TLSv1.3") == 0) {
414
0
    return ISC_TLS_PROTO_VER_1_3;
415
0
  }
416
417
0
  return ISC_TLS_PROTO_VER_UNDEFINED;
418
0
}
419
420
void
421
0
isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions) {
422
0
  REQUIRE(ctx != NULL);
423
0
  REQUIRE(tls_versions != 0);
424
0
  long set_options = 0;
425
0
  long clear_options = 0;
426
0
  uint32_t versions = tls_versions;
427
428
  /*
429
   * The code below might be initially hard to follow because of the
430
   * double negation that OpenSSL enforces.
431
   *
432
   * Taking into account that OpenSSL provides bits to *disable*
433
   * specific protocol versions, like SSL_OP_NO_TLSv1_2,
434
   * SSL_OP_NO_TLSv1_3, etc., the code has the following logic:
435
   *
436
   * If a protocol version is not specified in the bitmask, get the
437
   * bit that disables it and add it to the set of TLS options to
438
   * set ('set_options'). Otherwise, if a protocol version is set,
439
   * add the bit to the set of options to clear ('clear_options').
440
   */
441
442
  /* TLS protocol versions are defined as powers of two. */
443
0
  for (uint32_t tls_ver = ISC_TLS_PROTO_VER_1_2;
444
0
       tls_ver < ISC_TLS_PROTO_VER_UNDEFINED; tls_ver <<= 1)
445
0
  {
446
0
    if ((tls_versions & tls_ver) == 0) {
447
0
      set_options |= get_tls_version_disable_bit(tls_ver);
448
0
    } else {
449
      /*
450
       * Only supported versions should ever be passed to the
451
       * function SSL_CTX_clear_options. For example, in order
452
       * to enable TLS v1.2, we have to clear
453
       * SSL_OP_NO_TLSv1_2. Insist that the configuration file
454
       * was verified properly, so we are not trying to enable
455
       * an unsupported TLS version.
456
       */
457
0
      INSIST(isc_tls_protocol_supported(tls_ver));
458
0
      clear_options |= get_tls_version_disable_bit(tls_ver);
459
0
    }
460
0
    versions &= ~(tls_ver);
461
0
  }
462
463
  /* All versions should be processed at this point, thus the value
464
   * must equal zero. If it is not, then some garbage has been
465
   * passed to the function; this situation is worth
466
   * investigation. */
467
0
  INSIST(versions == 0);
468
469
0
  (void)SSL_CTX_set_options(ctx, set_options);
470
0
  (void)SSL_CTX_clear_options(ctx, clear_options);
471
0
}
472
473
bool
474
0
isc_tlsctx_load_dhparams(isc_tlsctx_t *ctx, const char *dhparams_file) {
475
0
  REQUIRE(ctx != NULL);
476
0
  REQUIRE(dhparams_file != NULL);
477
0
  REQUIRE(*dhparams_file != '\0');
478
479
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
480
  /* OpenSSL < 3.0 */
481
0
  DH *dh = NULL;
482
0
  FILE *paramfile;
483
484
0
  paramfile = fopen(dhparams_file, "r");
485
486
0
  if (paramfile) {
487
0
    int check = 0;
488
0
    dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
489
0
    fclose(paramfile);
490
491
0
    if (dh == NULL) {
492
0
      return false;
493
0
    } else if (DH_check(dh, &check) != 1 || check != 0) {
494
0
      DH_free(dh);
495
0
      return false;
496
0
    }
497
0
  } else {
498
0
    return false;
499
0
  }
500
501
0
  if (SSL_CTX_set_tmp_dh(ctx, dh) != 1) {
502
0
    DH_free(dh);
503
0
    return false;
504
0
  }
505
506
0
  DH_free(dh);
507
#else
508
  /* OpenSSL >= 3.0: low level DH APIs are deprecated in OpenSSL 3.0 */
509
  EVP_PKEY *dh = NULL;
510
  BIO *bio = NULL;
511
512
  bio = BIO_new_file(dhparams_file, "r");
513
  if (bio == NULL) {
514
    return false;
515
  }
516
517
  dh = PEM_read_bio_Parameters(bio, NULL);
518
  if (dh == NULL) {
519
    BIO_free(bio);
520
    return false;
521
  }
522
523
  if (SSL_CTX_set0_tmp_dh_pkey(ctx, dh) != 1) {
524
    BIO_free(bio);
525
    EVP_PKEY_free(dh);
526
    return false;
527
  }
528
529
  /* No need to call EVP_PKEY_free(dh) as the "dh" is owned by the
530
   * SSL context at this point. */
531
532
  BIO_free(bio);
533
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
534
535
0
  return true;
536
0
}
537
538
bool
539
0
isc_tls_cipherlist_valid(const char *cipherlist) {
540
0
  isc_tlsctx_t *tmp_ctx = NULL;
541
0
  const SSL_METHOD *method = NULL;
542
0
  bool result;
543
0
  REQUIRE(cipherlist != NULL);
544
545
0
  if (*cipherlist == '\0') {
546
0
    return false;
547
0
  }
548
549
0
  method = TLS_server_method();
550
0
  if (method == NULL) {
551
0
    return false;
552
0
  }
553
0
  tmp_ctx = SSL_CTX_new(method);
554
0
  if (tmp_ctx == NULL) {
555
0
    return false;
556
0
  }
557
558
0
  result = SSL_CTX_set_cipher_list(tmp_ctx, cipherlist) == 1;
559
560
0
  isc_tlsctx_free(&tmp_ctx);
561
562
0
  return result;
563
0
}
564
565
void
566
0
isc_tlsctx_set_cipherlist(isc_tlsctx_t *ctx, const char *cipherlist) {
567
0
  REQUIRE(ctx != NULL);
568
0
  REQUIRE(cipherlist != NULL);
569
0
  REQUIRE(*cipherlist != '\0');
570
571
0
  RUNTIME_CHECK(SSL_CTX_set_cipher_list(ctx, cipherlist) == 1);
572
0
}
573
574
bool
575
0
isc_tls_cipher_suites_valid(const char *cipher_suites) {
576
0
  isc_tlsctx_t *tmp_ctx = NULL;
577
0
  const SSL_METHOD *method = NULL;
578
0
  bool result;
579
0
  REQUIRE(cipher_suites != NULL);
580
581
0
  if (*cipher_suites == '\0') {
582
0
    return false;
583
0
  }
584
585
0
  method = TLS_server_method();
586
0
  if (method == NULL) {
587
0
    return false;
588
0
  }
589
0
  tmp_ctx = SSL_CTX_new(method);
590
0
  if (tmp_ctx == NULL) {
591
0
    return false;
592
0
  }
593
594
0
  result = SSL_CTX_set_ciphersuites(tmp_ctx, cipher_suites) == 1;
595
596
0
  isc_tlsctx_free(&tmp_ctx);
597
598
0
  return result;
599
0
}
600
601
void
602
0
isc_tlsctx_set_cipher_suites(isc_tlsctx_t *ctx, const char *cipher_suites) {
603
0
  REQUIRE(ctx != NULL);
604
0
  REQUIRE(cipher_suites != NULL);
605
0
  REQUIRE(*cipher_suites != '\0');
606
607
0
  RUNTIME_CHECK(SSL_CTX_set_ciphersuites(ctx, cipher_suites) == 1);
608
0
}
609
610
void
611
0
isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer) {
612
0
  REQUIRE(ctx != NULL);
613
614
0
  if (prefer) {
615
0
    (void)SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
616
0
  } else {
617
0
    (void)SSL_CTX_clear_options(ctx,
618
0
              SSL_OP_CIPHER_SERVER_PREFERENCE);
619
0
  }
620
0
}
621
622
void
623
0
isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use) {
624
0
  REQUIRE(ctx != NULL);
625
626
0
  if (!use) {
627
0
    (void)SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
628
0
  } else {
629
0
    (void)SSL_CTX_clear_options(ctx, SSL_OP_NO_TICKET);
630
0
  }
631
0
}
632
633
isc_tls_t *
634
0
isc_tls_create(isc_tlsctx_t *ctx) {
635
0
  isc_tls_t *newctx = NULL;
636
637
0
  REQUIRE(ctx != NULL);
638
639
0
  newctx = SSL_new(ctx);
640
0
  if (newctx == NULL) {
641
0
    char errbuf[256];
642
0
    unsigned long err = ERR_get_error();
643
644
0
    ERR_error_string_n(err, errbuf, sizeof(errbuf));
645
0
    fprintf(stderr, "%s:SSL_new(%p) -> %s\n", __func__, ctx,
646
0
      errbuf);
647
0
  }
648
649
0
  return newctx;
650
0
}
651
652
void
653
0
isc_tls_free(isc_tls_t **tlsp) {
654
0
  isc_tls_t *tls = NULL;
655
0
  REQUIRE(tlsp != NULL && *tlsp != NULL);
656
657
0
  tls = *tlsp;
658
0
  *tlsp = NULL;
659
0
  SSL_free(tls);
660
0
}
661
662
const char *
663
0
isc_tls_verify_peer_result_string(isc_tls_t *tls) {
664
0
  REQUIRE(tls != NULL);
665
666
0
  return X509_verify_cert_error_string(SSL_get_verify_result(tls));
667
0
}
668
669
#if HAVE_LIBNGHTTP2
670
#ifndef OPENSSL_NO_NEXTPROTONEG
671
/*
672
 * NPN TLS extension client callback.
673
 */
674
static int
675
select_next_proto_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
676
0
         const unsigned char *in, unsigned int inlen, void *arg) {
677
0
  UNUSED(ssl);
678
0
  UNUSED(arg);
679
680
0
  if (nghttp2_select_next_protocol(out, outlen, in, inlen) <= 0) {
681
0
    return SSL_TLSEXT_ERR_NOACK;
682
0
  }
683
0
  return SSL_TLSEXT_ERR_OK;
684
0
}
685
#endif /* !OPENSSL_NO_NEXTPROTONEG */
686
687
void
688
0
isc_tlsctx_enable_http2client_alpn(isc_tlsctx_t *ctx) {
689
0
  REQUIRE(ctx != NULL);
690
691
0
#ifndef OPENSSL_NO_NEXTPROTONEG
692
0
  SSL_CTX_set_next_proto_select_cb(ctx, select_next_proto_cb, NULL);
693
0
#endif /* !OPENSSL_NO_NEXTPROTONEG */
694
695
0
  SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)NGHTTP2_PROTO_ALPN,
696
0
        NGHTTP2_PROTO_ALPN_LEN);
697
0
}
698
699
#ifndef OPENSSL_NO_NEXTPROTONEG
700
static int
701
next_proto_cb(isc_tls_t *ssl, const unsigned char **data, unsigned int *len,
702
0
        void *arg) {
703
0
  UNUSED(ssl);
704
0
  UNUSED(arg);
705
706
0
  *data = (const unsigned char *)NGHTTP2_PROTO_ALPN;
707
0
  *len = (unsigned int)NGHTTP2_PROTO_ALPN_LEN;
708
0
  return SSL_TLSEXT_ERR_OK;
709
0
}
710
#endif /* !OPENSSL_NO_NEXTPROTONEG */
711
712
static int
713
alpn_select_proto_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
714
0
         const unsigned char *in, unsigned int inlen, void *arg) {
715
0
  int ret;
716
717
0
  UNUSED(ssl);
718
0
  UNUSED(arg);
719
720
0
  ret = nghttp2_select_next_protocol((unsigned char **)(uintptr_t)out,
721
0
             outlen, in, inlen);
722
723
0
  if (ret != 1) {
724
0
    return SSL_TLSEXT_ERR_NOACK;
725
0
  }
726
727
0
  return SSL_TLSEXT_ERR_OK;
728
0
}
729
730
void
731
0
isc_tlsctx_enable_http2server_alpn(isc_tlsctx_t *tls) {
732
0
  REQUIRE(tls != NULL);
733
734
0
#ifndef OPENSSL_NO_NEXTPROTONEG
735
0
  SSL_CTX_set_next_protos_advertised_cb(tls, next_proto_cb, NULL);
736
0
#endif // OPENSSL_NO_NEXTPROTONEG
737
0
  SSL_CTX_set_alpn_select_cb(tls, alpn_select_proto_cb, NULL);
738
0
}
739
#endif /* HAVE_LIBNGHTTP2 */
740
741
void
742
isc_tls_get_selected_alpn(isc_tls_t *tls, const unsigned char **alpn,
743
0
        unsigned int *alpnlen) {
744
0
  REQUIRE(tls != NULL);
745
0
  REQUIRE(alpn != NULL);
746
0
  REQUIRE(alpnlen != NULL);
747
748
0
#ifndef OPENSSL_NO_NEXTPROTONEG
749
0
  SSL_get0_next_proto_negotiated(tls, alpn, alpnlen);
750
0
#endif
751
0
  if (*alpn == NULL) {
752
0
    SSL_get0_alpn_selected(tls, alpn, alpnlen);
753
0
  }
754
0
}
755
756
static bool
757
protoneg_check_protocol(const uint8_t **pout, uint8_t *pout_len,
758
      const uint8_t *in, size_t in_len, const uint8_t *key,
759
0
      size_t key_len) {
760
0
  for (size_t i = 0; i + key_len <= in_len; i += (size_t)(in[i] + 1)) {
761
0
    if (memcmp(&in[i], key, key_len) == 0) {
762
0
      *pout = (const uint8_t *)(&in[i + 1]);
763
0
      *pout_len = in[i];
764
0
      return true;
765
0
    }
766
0
  }
767
0
  return false;
768
0
}
769
770
/* dot prepended by its length (3 bytes) */
771
0
#define DOT_PROTO_ALPN     "\x3" ISC_TLS_DOT_PROTO_ALPN_ID
772
0
#define DOT_PROTO_ALPN_LEN (sizeof(DOT_PROTO_ALPN) - 1)
773
774
static bool
775
dot_select_next_protocol(const uint8_t **pout, uint8_t *pout_len,
776
0
       const uint8_t *in, size_t in_len) {
777
0
  return protoneg_check_protocol(pout, pout_len, in, in_len,
778
0
               (const uint8_t *)DOT_PROTO_ALPN,
779
0
               DOT_PROTO_ALPN_LEN);
780
0
}
781
782
void
783
0
isc_tlsctx_enable_dot_client_alpn(isc_tlsctx_t *ctx) {
784
0
  REQUIRE(ctx != NULL);
785
786
0
  SSL_CTX_set_alpn_protos(ctx, (const uint8_t *)DOT_PROTO_ALPN,
787
0
        DOT_PROTO_ALPN_LEN);
788
0
}
789
790
static int
791
dot_alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
792
       unsigned char *outlen, const unsigned char *in,
793
0
       unsigned int inlen, void *arg) {
794
0
  bool ret;
795
796
0
  UNUSED(ssl);
797
0
  UNUSED(arg);
798
799
0
  ret = dot_select_next_protocol(out, outlen, in, inlen);
800
801
0
  if (!ret) {
802
0
    return SSL_TLSEXT_ERR_NOACK;
803
0
  }
804
805
0
  return SSL_TLSEXT_ERR_OK;
806
0
}
807
808
void
809
0
isc_tlsctx_enable_dot_server_alpn(isc_tlsctx_t *tls) {
810
0
  REQUIRE(tls != NULL);
811
812
0
  SSL_CTX_set_alpn_select_cb(tls, dot_alpn_select_proto_cb, NULL);
813
0
}
814
815
isc_result_t
816
isc_tlsctx_enable_peer_verification(isc_tlsctx_t *tlsctx, const bool is_server,
817
            isc_tls_cert_store_t *store,
818
            const char *hostname,
819
0
            bool hostname_ignore_subject) {
820
0
  int ret = 0;
821
0
  REQUIRE(tlsctx != NULL);
822
0
  REQUIRE(store != NULL);
823
824
  /* Set the hostname/IP address. */
825
0
  if (!is_server && hostname != NULL && *hostname != '\0') {
826
0
    struct in6_addr sa6;
827
0
    struct in_addr sa;
828
0
    X509_VERIFY_PARAM *param = SSL_CTX_get0_param(tlsctx);
829
0
    unsigned int hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
830
831
    /* It might be an IP address. */
832
0
    if (inet_pton(AF_INET6, hostname, &sa6) == 1 ||
833
0
        inet_pton(AF_INET, hostname, &sa) == 1)
834
0
    {
835
0
      ret = X509_VERIFY_PARAM_set1_ip_asc(param, hostname);
836
0
    } else {
837
      /* It seems that it is a host name. Let's set it. */
838
0
      ret = X509_VERIFY_PARAM_set1_host(param, hostname, 0);
839
0
    }
840
0
    if (ret != 1) {
841
0
      ERR_clear_error();
842
0
      return ISC_R_FAILURE;
843
0
    }
844
845
0
#ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT
846
    /*
847
     * According to the RFC 8310, Section 8.1, Subject field MUST
848
     * NOT be inspected when verifying a hostname when using
849
     * DoT. Only SubjectAltName must be checked instead. That is
850
     * not the case for HTTPS, though.
851
     *
852
     * Unfortunately, some quite old versions of OpenSSL (< 1.1.1)
853
     * might lack the functionality to implement that. It should
854
     * have very little real-world consequences, as most of the
855
     * production-ready certificates issued by real CAs will have
856
     * SubjectAltName set. In such a case, the Subject field is
857
     * ignored.
858
     */
859
0
    if (hostname_ignore_subject) {
860
0
      hostflags |= X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
861
0
    }
862
#else
863
    UNUSED(hostname_ignore_subject);
864
#endif
865
0
    X509_VERIFY_PARAM_set_hostflags(param, hostflags);
866
0
  }
867
868
  /* "Attach" the cert store to the context */
869
0
  SSL_CTX_set1_cert_store(tlsctx, store);
870
871
  /* enable verification */
872
0
  if (is_server) {
873
0
    SSL_CTX_set_verify(tlsctx,
874
0
           SSL_VERIFY_PEER |
875
0
             SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
876
0
           NULL);
877
0
  } else {
878
0
    SSL_CTX_set_verify(tlsctx, SSL_VERIFY_PEER, NULL);
879
0
  }
880
881
0
  return ISC_R_SUCCESS;
882
0
}
883
884
isc_result_t
885
0
isc_tlsctx_load_client_ca_names(isc_tlsctx_t *ctx, const char *ca_bundle_file) {
886
0
  STACK_OF(X509_NAME) * cert_names;
887
0
  REQUIRE(ctx != NULL);
888
0
  REQUIRE(ca_bundle_file != NULL);
889
890
0
  cert_names = SSL_load_client_CA_file(ca_bundle_file);
891
0
  if (cert_names == NULL) {
892
0
    ERR_clear_error();
893
0
    return ISC_R_FAILURE;
894
0
  }
895
896
0
  SSL_CTX_set_client_CA_list(ctx, cert_names);
897
898
0
  return ISC_R_SUCCESS;
899
0
}
900
901
isc_result_t
902
isc_tls_cert_store_create(const char *ca_bundle_filename,
903
0
        isc_tls_cert_store_t **pstore) {
904
0
  int ret = 0;
905
0
  isc_tls_cert_store_t *store = NULL;
906
0
  REQUIRE(pstore != NULL && *pstore == NULL);
907
908
0
  store = X509_STORE_new();
909
0
  if (store == NULL) {
910
0
    goto error;
911
0
  }
912
913
  /* Let's treat empty string as the default (system wide) store */
914
0
  if (ca_bundle_filename != NULL && *ca_bundle_filename == '\0') {
915
0
    ca_bundle_filename = NULL;
916
0
  }
917
918
0
  if (ca_bundle_filename == NULL) {
919
0
    ret = X509_STORE_set_default_paths(store);
920
0
  } else {
921
0
    ret = X509_STORE_load_locations(store, ca_bundle_filename,
922
0
            NULL);
923
0
  }
924
925
0
  if (ret == 0) {
926
0
    goto error;
927
0
  }
928
929
0
  *pstore = store;
930
0
  return ISC_R_SUCCESS;
931
932
0
error:
933
0
  ERR_clear_error();
934
0
  if (store != NULL) {
935
0
    X509_STORE_free(store);
936
0
  }
937
0
  return ISC_R_FAILURE;
938
0
}
939
940
void
941
0
isc_tls_cert_store_free(isc_tls_cert_store_t **pstore) {
942
0
  isc_tls_cert_store_t *store;
943
0
  REQUIRE(pstore != NULL && *pstore != NULL);
944
945
0
  store = *pstore;
946
947
0
  X509_STORE_free(store);
948
949
0
  *pstore = NULL;
950
0
}
951
952
0
#define TLSCTX_CACHE_MAGIC    ISC_MAGIC('T', 'l', 'S', 'c')
953
#define VALID_TLSCTX_CACHE(t) ISC_MAGIC_VALID(t, TLSCTX_CACHE_MAGIC)
954
955
0
#define TLSCTX_CLIENT_SESSION_CACHE_MAGIC ISC_MAGIC('T', 'l', 'C', 'c')
956
#define VALID_TLSCTX_CLIENT_SESSION_CACHE(t) \
957
  ISC_MAGIC_VALID(t, TLSCTX_CLIENT_SESSION_CACHE_MAGIC)
958
959
typedef struct isc_tlsctx_cache_entry {
960
  /*
961
   * We need a TLS context entry for each transport on both IPv4 and
962
   * IPv6 in order to avoid cluttering a context-specific
963
   * session-resumption cache.
964
   */
965
  isc_tlsctx_t *ctx[isc_tlsctx_cache_count - 1][2];
966
  isc_tlsctx_client_session_cache_t
967
    *client_sess_cache[isc_tlsctx_cache_count - 1][2];
968
  /*
969
   * One certificate store is enough for all the contexts defined
970
   * above. We need that for peer validation.
971
   */
972
  isc_tls_cert_store_t *ca_store;
973
} isc_tlsctx_cache_entry_t;
974
975
struct isc_tlsctx_cache {
976
  uint32_t magic;
977
  isc_refcount_t references;
978
  isc_mem_t *mctx;
979
980
  isc_rwlock_t rwlock;
981
  isc_ht_t *data;
982
};
983
984
void
985
0
isc_tlsctx_cache_create(isc_mem_t *mctx, isc_tlsctx_cache_t **cachep) {
986
0
  isc_tlsctx_cache_t *nc;
987
988
0
  REQUIRE(cachep != NULL && *cachep == NULL);
989
0
  nc = isc_mem_get(mctx, sizeof(*nc));
990
991
0
  *nc = (isc_tlsctx_cache_t){ .magic = TLSCTX_CACHE_MAGIC };
992
0
  isc_refcount_init(&nc->references, 1);
993
0
  isc_mem_attach(mctx, &nc->mctx);
994
995
0
  isc_ht_init(&nc->data, mctx, 5, ISC_HT_CASE_SENSITIVE);
996
0
  isc_rwlock_init(&nc->rwlock);
997
998
0
  *cachep = nc;
999
0
}
1000
1001
void
1002
isc_tlsctx_cache_attach(isc_tlsctx_cache_t *source,
1003
0
      isc_tlsctx_cache_t **targetp) {
1004
0
  REQUIRE(VALID_TLSCTX_CACHE(source));
1005
0
  REQUIRE(targetp != NULL && *targetp == NULL);
1006
1007
0
  isc_refcount_increment(&source->references);
1008
1009
0
  *targetp = source;
1010
0
}
1011
1012
static void
1013
0
tlsctx_cache_entry_destroy(isc_mem_t *mctx, isc_tlsctx_cache_entry_t *entry) {
1014
0
  size_t i, k;
1015
1016
0
  for (i = 0; i < (isc_tlsctx_cache_count - 1); i++) {
1017
0
    for (k = 0; k < 2; k++) {
1018
0
      if (entry->ctx[i][k] != NULL) {
1019
0
        isc_tlsctx_free(&entry->ctx[i][k]);
1020
0
      }
1021
1022
0
      if (entry->client_sess_cache[i][k] != NULL) {
1023
0
        isc_tlsctx_client_session_cache_detach(
1024
0
          &entry->client_sess_cache[i][k]);
1025
0
      }
1026
0
    }
1027
0
  }
1028
0
  if (entry->ca_store != NULL) {
1029
0
    isc_tls_cert_store_free(&entry->ca_store);
1030
0
  }
1031
0
  isc_mem_put(mctx, entry, sizeof(*entry));
1032
0
}
1033
1034
static void
1035
0
tlsctx_cache_destroy(isc_tlsctx_cache_t *cache) {
1036
0
  isc_ht_iter_t *it = NULL;
1037
0
  isc_result_t result;
1038
1039
0
  cache->magic = 0;
1040
1041
0
  isc_refcount_destroy(&cache->references);
1042
1043
0
  isc_ht_iter_create(cache->data, &it);
1044
0
  for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
1045
0
       result = isc_ht_iter_delcurrent_next(it))
1046
0
  {
1047
0
    isc_tlsctx_cache_entry_t *entry = NULL;
1048
0
    isc_ht_iter_current(it, (void **)&entry);
1049
0
    tlsctx_cache_entry_destroy(cache->mctx, entry);
1050
0
  }
1051
1052
0
  isc_ht_iter_destroy(&it);
1053
0
  isc_ht_destroy(&cache->data);
1054
0
  isc_rwlock_destroy(&cache->rwlock);
1055
0
  isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
1056
0
}
1057
1058
void
1059
0
isc_tlsctx_cache_detach(isc_tlsctx_cache_t **cachep) {
1060
0
  isc_tlsctx_cache_t *cache = NULL;
1061
1062
0
  REQUIRE(cachep != NULL);
1063
1064
0
  cache = *cachep;
1065
0
  *cachep = NULL;
1066
1067
0
  REQUIRE(VALID_TLSCTX_CACHE(cache));
1068
1069
0
  if (isc_refcount_decrement(&cache->references) == 1) {
1070
0
    tlsctx_cache_destroy(cache);
1071
0
  }
1072
0
}
1073
1074
isc_result_t
1075
isc_tlsctx_cache_add(
1076
  isc_tlsctx_cache_t *cache, const char *name,
1077
  const isc_tlsctx_cache_transport_t transport, const uint16_t family,
1078
  isc_tlsctx_t *ctx, isc_tls_cert_store_t *store,
1079
  isc_tlsctx_client_session_cache_t *client_sess_cache,
1080
  isc_tlsctx_t **pfound, isc_tls_cert_store_t **pfound_store,
1081
0
  isc_tlsctx_client_session_cache_t **pfound_client_sess_cache) {
1082
0
  isc_result_t result = ISC_R_FAILURE;
1083
0
  size_t name_len, tr_offset;
1084
0
  isc_tlsctx_cache_entry_t *entry = NULL;
1085
0
  bool ipv6;
1086
1087
0
  REQUIRE(VALID_TLSCTX_CACHE(cache));
1088
0
  REQUIRE(client_sess_cache == NULL ||
1089
0
    VALID_TLSCTX_CLIENT_SESSION_CACHE(client_sess_cache));
1090
0
  REQUIRE(name != NULL && *name != '\0');
1091
0
  REQUIRE(transport > isc_tlsctx_cache_none &&
1092
0
    transport < isc_tlsctx_cache_count);
1093
0
  REQUIRE(family == AF_INET || family == AF_INET6);
1094
0
  REQUIRE(ctx != NULL);
1095
1096
0
  tr_offset = (transport - 1);
1097
0
  ipv6 = (family == AF_INET6);
1098
1099
0
  RWLOCK(&cache->rwlock, isc_rwlocktype_write);
1100
1101
0
  name_len = strlen(name);
1102
0
  result = isc_ht_find(cache->data, (const uint8_t *)name, name_len,
1103
0
           (void **)&entry);
1104
0
  if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
1105
0
    isc_tlsctx_client_session_cache_t *found_client_sess_cache;
1106
    /* The entry exists. */
1107
0
    if (pfound != NULL) {
1108
0
      INSIST(*pfound == NULL);
1109
0
      *pfound = entry->ctx[tr_offset][ipv6];
1110
0
    }
1111
1112
0
    if (pfound_store != NULL && entry->ca_store != NULL) {
1113
0
      INSIST(*pfound_store == NULL);
1114
0
      *pfound_store = entry->ca_store;
1115
0
    }
1116
1117
0
    found_client_sess_cache =
1118
0
      entry->client_sess_cache[tr_offset][ipv6];
1119
0
    if (pfound_client_sess_cache != NULL &&
1120
0
        found_client_sess_cache != NULL)
1121
0
    {
1122
0
      INSIST(*pfound_client_sess_cache == NULL);
1123
0
      *pfound_client_sess_cache = found_client_sess_cache;
1124
0
    }
1125
0
    result = ISC_R_EXISTS;
1126
0
  } else if (result == ISC_R_SUCCESS &&
1127
0
       entry->ctx[tr_offset][ipv6] == NULL)
1128
0
  {
1129
    /*
1130
     * The hash table entry exists, but is not filled for this
1131
     * particular transport/IP type combination.
1132
     */
1133
0
    entry->ctx[tr_offset][ipv6] = ctx;
1134
0
    entry->client_sess_cache[tr_offset][ipv6] = client_sess_cache;
1135
    /*
1136
     * As the passed certificates store object is supposed
1137
     * to be internally managed by the cache object anyway,
1138
     * we might destroy the unneeded store object right now.
1139
     */
1140
0
    if (store != NULL && store != entry->ca_store) {
1141
0
      isc_tls_cert_store_free(&store);
1142
0
    }
1143
0
    result = ISC_R_SUCCESS;
1144
0
  } else {
1145
    /*
1146
     * The hash table entry does not exist, let's create one.
1147
     */
1148
0
    INSIST(result != ISC_R_SUCCESS);
1149
0
    entry = isc_mem_get(cache->mctx, sizeof(*entry));
1150
0
    *entry = (isc_tlsctx_cache_entry_t){
1151
0
      .ca_store = store,
1152
0
    };
1153
1154
0
    entry->ctx[tr_offset][ipv6] = ctx;
1155
0
    entry->client_sess_cache[tr_offset][ipv6] = client_sess_cache;
1156
0
    RUNTIME_CHECK(isc_ht_add(cache->data, (const uint8_t *)name,
1157
0
           name_len,
1158
0
           (void *)entry) == ISC_R_SUCCESS);
1159
0
    result = ISC_R_SUCCESS;
1160
0
  }
1161
1162
0
  RWUNLOCK(&cache->rwlock, isc_rwlocktype_write);
1163
1164
0
  return result;
1165
0
}
1166
1167
isc_result_t
1168
isc_tlsctx_cache_find(
1169
  isc_tlsctx_cache_t *cache, const char *name,
1170
  const isc_tlsctx_cache_transport_t transport, const uint16_t family,
1171
  isc_tlsctx_t **pctx, isc_tls_cert_store_t **pstore,
1172
0
  isc_tlsctx_client_session_cache_t **pfound_client_sess_cache) {
1173
0
  isc_result_t result = ISC_R_FAILURE;
1174
0
  size_t tr_offset;
1175
0
  isc_tlsctx_cache_entry_t *entry = NULL;
1176
0
  bool ipv6;
1177
1178
0
  REQUIRE(VALID_TLSCTX_CACHE(cache));
1179
0
  REQUIRE(name != NULL && *name != '\0');
1180
0
  REQUIRE(transport > isc_tlsctx_cache_none &&
1181
0
    transport < isc_tlsctx_cache_count);
1182
0
  REQUIRE(family == AF_INET || family == AF_INET6);
1183
0
  REQUIRE(pctx != NULL && *pctx == NULL);
1184
1185
0
  tr_offset = (transport - 1);
1186
0
  ipv6 = (family == AF_INET6);
1187
1188
0
  RWLOCK(&cache->rwlock, isc_rwlocktype_read);
1189
1190
0
  result = isc_ht_find(cache->data, (const uint8_t *)name, strlen(name),
1191
0
           (void **)&entry);
1192
1193
0
  if (result == ISC_R_SUCCESS && pstore != NULL &&
1194
0
      entry->ca_store != NULL)
1195
0
  {
1196
0
    *pstore = entry->ca_store;
1197
0
  }
1198
1199
0
  if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
1200
0
    isc_tlsctx_client_session_cache_t *found_client_sess_cache =
1201
0
      entry->client_sess_cache[tr_offset][ipv6];
1202
1203
0
    *pctx = entry->ctx[tr_offset][ipv6];
1204
1205
0
    if (pfound_client_sess_cache != NULL &&
1206
0
        found_client_sess_cache != NULL)
1207
0
    {
1208
0
      INSIST(*pfound_client_sess_cache == NULL);
1209
0
      *pfound_client_sess_cache = found_client_sess_cache;
1210
0
    }
1211
0
  } else if (result == ISC_R_SUCCESS &&
1212
0
       entry->ctx[tr_offset][ipv6] == NULL)
1213
0
  {
1214
0
    result = ISC_R_NOTFOUND;
1215
0
  } else {
1216
0
    INSIST(result != ISC_R_SUCCESS);
1217
0
  }
1218
1219
0
  RWUNLOCK(&cache->rwlock, isc_rwlocktype_read);
1220
1221
0
  return result;
1222
0
}
1223
1224
typedef struct client_session_cache_entry client_session_cache_entry_t;
1225
1226
typedef struct client_session_cache_bucket {
1227
  char *bucket_key;
1228
  size_t bucket_key_len;
1229
  /* Cache entries within the bucket (from the oldest to the newest). */
1230
  ISC_LIST(client_session_cache_entry_t) entries;
1231
} client_session_cache_bucket_t;
1232
1233
struct client_session_cache_entry {
1234
  SSL_SESSION *session;
1235
  client_session_cache_bucket_t *bucket; /* "Parent" bucket pointer. */
1236
  ISC_LINK(client_session_cache_entry_t) bucket_link;
1237
  ISC_LINK(client_session_cache_entry_t) cache_link;
1238
};
1239
1240
struct isc_tlsctx_client_session_cache {
1241
  uint32_t magic;
1242
  isc_refcount_t references;
1243
  isc_mem_t *mctx;
1244
1245
  /*
1246
   * We need to keep a reference to the related TLS context in order
1247
   * to ensure that it remains valid while the TLS client sessions
1248
   * cache object is valid, as every TLS session object
1249
   * (SSL_SESSION) is "tied" to a particular context.
1250
   */
1251
  isc_tlsctx_t *ctx;
1252
1253
  /*
1254
   * The idea is to have one bucket per remote server. Each bucket,
1255
   * can maintain multiple TLS sessions to that server, as BIND
1256
   * might want to establish multiple TLS connections to the remote
1257
   * server at once.
1258
   */
1259
  isc_ht_t *buckets;
1260
1261
  /*
1262
   * The list of all current entries within the cache maintained in
1263
   * LRU-manner, so that the oldest entry might be efficiently
1264
   * removed.
1265
   */
1266
  ISC_LIST(client_session_cache_entry_t) lru_entries;
1267
  /* Number of the entries within the cache. */
1268
  size_t nentries;
1269
  /* Maximum number of the entries within the cache. */
1270
  size_t max_entries;
1271
1272
  isc_mutex_t lock;
1273
};
1274
1275
void
1276
isc_tlsctx_client_session_cache_create(
1277
  isc_mem_t *mctx, isc_tlsctx_t *ctx, const size_t max_entries,
1278
0
  isc_tlsctx_client_session_cache_t **cachep) {
1279
0
  isc_tlsctx_client_session_cache_t *nc;
1280
1281
0
  REQUIRE(ctx != NULL);
1282
0
  REQUIRE(max_entries > 0);
1283
0
  REQUIRE(cachep != NULL && *cachep == NULL);
1284
1285
0
  nc = isc_mem_get(mctx, sizeof(*nc));
1286
1287
0
  *nc = (isc_tlsctx_client_session_cache_t){ .max_entries = max_entries };
1288
0
  isc_refcount_init(&nc->references, 1);
1289
0
  isc_mem_attach(mctx, &nc->mctx);
1290
0
  isc_tlsctx_attach(ctx, &nc->ctx);
1291
1292
0
  isc_ht_init(&nc->buckets, mctx, 5, ISC_HT_CASE_SENSITIVE);
1293
0
  ISC_LIST_INIT(nc->lru_entries);
1294
0
  isc_mutex_init(&nc->lock);
1295
1296
0
  nc->magic = TLSCTX_CLIENT_SESSION_CACHE_MAGIC;
1297
1298
0
  *cachep = nc;
1299
0
}
1300
1301
void
1302
isc_tlsctx_client_session_cache_attach(
1303
  isc_tlsctx_client_session_cache_t *source,
1304
0
  isc_tlsctx_client_session_cache_t **targetp) {
1305
0
  REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(source));
1306
0
  REQUIRE(targetp != NULL && *targetp == NULL);
1307
1308
0
  isc_refcount_increment(&source->references);
1309
1310
0
  *targetp = source;
1311
0
}
1312
1313
static void
1314
client_cache_entry_delete(isc_tlsctx_client_session_cache_t *restrict cache,
1315
0
        client_session_cache_entry_t *restrict entry) {
1316
0
  client_session_cache_bucket_t *restrict bucket = entry->bucket;
1317
1318
  /* Unlink and free the cache entry */
1319
0
  ISC_LIST_UNLINK(bucket->entries, entry, bucket_link);
1320
0
  ISC_LIST_UNLINK(cache->lru_entries, entry, cache_link);
1321
0
  cache->nentries--;
1322
0
  (void)SSL_SESSION_free(entry->session);
1323
0
  isc_mem_put(cache->mctx, entry, sizeof(*entry));
1324
1325
  /* The bucket is empty - let's remove it */
1326
0
  if (ISC_LIST_EMPTY(bucket->entries)) {
1327
0
    RUNTIME_CHECK(isc_ht_delete(cache->buckets,
1328
0
              (const uint8_t *)bucket->bucket_key,
1329
0
              bucket->bucket_key_len) ==
1330
0
            ISC_R_SUCCESS);
1331
1332
0
    isc_mem_free(cache->mctx, bucket->bucket_key);
1333
0
    isc_mem_put(cache->mctx, bucket, sizeof(*bucket));
1334
0
  }
1335
0
}
1336
1337
void
1338
isc_tlsctx_client_session_cache_detach(
1339
0
  isc_tlsctx_client_session_cache_t **cachep) {
1340
0
  isc_tlsctx_client_session_cache_t *cache = NULL;
1341
1342
0
  REQUIRE(cachep != NULL);
1343
1344
0
  cache = *cachep;
1345
0
  *cachep = NULL;
1346
1347
0
  REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1348
1349
0
  if (isc_refcount_decrement(&cache->references) != 1) {
1350
0
    return;
1351
0
  }
1352
1353
0
  cache->magic = 0;
1354
1355
0
  isc_refcount_destroy(&cache->references);
1356
1357
0
  ISC_LIST_FOREACH(cache->lru_entries, entry, cache_link) {
1358
0
    client_cache_entry_delete(cache, entry);
1359
0
  }
1360
1361
0
  RUNTIME_CHECK(isc_ht_count(cache->buckets) == 0);
1362
0
  isc_ht_destroy(&cache->buckets);
1363
1364
0
  isc_mutex_destroy(&cache->lock);
1365
0
  isc_tlsctx_free(&cache->ctx);
1366
0
  isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
1367
0
}
1368
1369
void
1370
isc_tlsctx_client_session_cache_keep(isc_tlsctx_client_session_cache_t *cache,
1371
0
             char *remote_peer_name, isc_tls_t *tls) {
1372
0
  size_t name_len;
1373
0
  isc_result_t result;
1374
0
  SSL_SESSION *sess;
1375
0
  client_session_cache_bucket_t *restrict bucket = NULL;
1376
0
  client_session_cache_entry_t *restrict entry = NULL;
1377
1378
0
  REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1379
0
  REQUIRE(remote_peer_name != NULL && *remote_peer_name != '\0');
1380
0
  REQUIRE(tls != NULL);
1381
1382
0
  sess = SSL_get1_session(tls);
1383
0
  if (sess == NULL) {
1384
0
    ERR_clear_error();
1385
0
    return;
1386
0
  } else if (SSL_SESSION_is_resumable(sess) == 0) {
1387
0
    SSL_SESSION_free(sess);
1388
0
    return;
1389
0
  }
1390
1391
0
  SSL_set_session(tls, NULL);
1392
1393
0
  isc_mutex_lock(&cache->lock);
1394
1395
0
  name_len = strlen(remote_peer_name);
1396
0
  result = isc_ht_find(cache->buckets, (const uint8_t *)remote_peer_name,
1397
0
           name_len, (void **)&bucket);
1398
1399
0
  if (result != ISC_R_SUCCESS) {
1400
    /* Let's create a new bucket */
1401
0
    INSIST(bucket == NULL);
1402
0
    bucket = isc_mem_get(cache->mctx, sizeof(*bucket));
1403
0
    *bucket = (client_session_cache_bucket_t){
1404
0
      .bucket_key = isc_mem_strdup(cache->mctx,
1405
0
                 remote_peer_name),
1406
0
      .bucket_key_len = name_len
1407
0
    };
1408
0
    ISC_LIST_INIT(bucket->entries);
1409
0
    RUNTIME_CHECK(isc_ht_add(cache->buckets,
1410
0
           (const uint8_t *)remote_peer_name,
1411
0
           name_len,
1412
0
           (void *)bucket) == ISC_R_SUCCESS);
1413
0
  }
1414
1415
  /* Let's add a new cache entry to the new/found bucket */
1416
0
  entry = isc_mem_get(cache->mctx, sizeof(*entry));
1417
0
  *entry = (client_session_cache_entry_t){ .session = sess,
1418
0
             .bucket = bucket };
1419
0
  ISC_LINK_INIT(entry, bucket_link);
1420
0
  ISC_LINK_INIT(entry, cache_link);
1421
1422
0
  ISC_LIST_APPEND(bucket->entries, entry, bucket_link);
1423
1424
0
  ISC_LIST_APPEND(cache->lru_entries, entry, cache_link);
1425
0
  cache->nentries++;
1426
1427
0
  if (cache->nentries > cache->max_entries) {
1428
    /*
1429
     * Cache overrun. We need to remove the oldest entry from the
1430
     * cache
1431
     */
1432
0
    client_session_cache_entry_t *restrict oldest;
1433
0
    INSIST((cache->nentries - 1) == cache->max_entries);
1434
1435
0
    oldest = ISC_LIST_HEAD(cache->lru_entries);
1436
0
    client_cache_entry_delete(cache, oldest);
1437
0
  }
1438
1439
0
  isc_mutex_unlock(&cache->lock);
1440
0
}
1441
1442
void
1443
isc_tlsctx_client_session_cache_reuse(isc_tlsctx_client_session_cache_t *cache,
1444
0
              char *remote_peer_name, isc_tls_t *tls) {
1445
0
  client_session_cache_bucket_t *restrict bucket = NULL;
1446
0
  client_session_cache_entry_t *restrict entry;
1447
0
  size_t name_len;
1448
0
  isc_result_t result;
1449
1450
0
  REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1451
0
  REQUIRE(remote_peer_name != NULL && *remote_peer_name != '\0');
1452
0
  REQUIRE(tls != NULL);
1453
1454
0
  isc_mutex_lock(&cache->lock);
1455
1456
  /* Let's find the bucket */
1457
0
  name_len = strlen(remote_peer_name);
1458
0
  result = isc_ht_find(cache->buckets, (const uint8_t *)remote_peer_name,
1459
0
           name_len, (void **)&bucket);
1460
1461
0
  if (result != ISC_R_SUCCESS) {
1462
0
    goto exit;
1463
0
  }
1464
1465
0
  INSIST(bucket != NULL);
1466
1467
  /*
1468
   * If the bucket has been found, let's use the newest session from
1469
   * the bucket, as it has the highest chance to be successfully
1470
   * resumed.
1471
   */
1472
0
  INSIST(!ISC_LIST_EMPTY(bucket->entries));
1473
0
  entry = ISC_LIST_TAIL(bucket->entries);
1474
0
  RUNTIME_CHECK(SSL_set_session(tls, entry->session) == 1);
1475
0
  client_cache_entry_delete(cache, entry);
1476
1477
0
exit:
1478
0
  isc_mutex_unlock(&cache->lock);
1479
0
}
1480
1481
void
1482
isc_tlsctx_client_session_cache_keep_sockaddr(
1483
  isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
1484
0
  isc_tls_t *tls) {
1485
0
  char peername[ISC_SOCKADDR_FORMATSIZE] = { 0 };
1486
1487
0
  REQUIRE(remote_peer != NULL);
1488
1489
0
  isc_sockaddr_format(remote_peer, peername, sizeof(peername));
1490
1491
0
  isc_tlsctx_client_session_cache_keep(cache, peername, tls);
1492
0
}
1493
1494
void
1495
isc_tlsctx_client_session_cache_reuse_sockaddr(
1496
  isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
1497
0
  isc_tls_t *tls) {
1498
0
  char peername[ISC_SOCKADDR_FORMATSIZE] = { 0 };
1499
1500
0
  REQUIRE(remote_peer != NULL);
1501
1502
0
  isc_sockaddr_format(remote_peer, peername, sizeof(peername));
1503
1504
0
  isc_tlsctx_client_session_cache_reuse(cache, peername, tls);
1505
0
}
1506
1507
const isc_tlsctx_t *
1508
isc_tlsctx_client_session_cache_getctx(
1509
0
  isc_tlsctx_client_session_cache_t *cache) {
1510
0
  REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1511
0
  return cache->ctx;
1512
0
}
1513
1514
void
1515
0
isc_tlsctx_set_random_session_id_context(isc_tlsctx_t *ctx) {
1516
0
  uint8_t session_id_ctx[SSL_MAX_SID_CTX_LENGTH] = { 0 };
1517
0
  const size_t len = ISC_MIN(20, sizeof(session_id_ctx));
1518
1519
0
  REQUIRE(ctx != NULL);
1520
1521
0
  RUNTIME_CHECK(RAND_bytes(session_id_ctx, len) == 1);
1522
1523
0
  RUNTIME_CHECK(
1524
0
    SSL_CTX_set_session_id_context(ctx, session_id_ctx, len) == 1);
1525
0
}
1526
1527
bool
1528
0
isc_tls_valid_sni_hostname(const char *hostname) {
1529
0
  struct sockaddr_in sa_v4 = { 0 };
1530
0
  struct sockaddr_in6 sa_v6 = { 0 };
1531
0
  int ret = 0;
1532
1533
0
  if (hostname == NULL) {
1534
0
    return false;
1535
0
  }
1536
1537
0
  ret = inet_pton(AF_INET, hostname, &sa_v4.sin_addr);
1538
0
  if (ret == 1) {
1539
0
    return false;
1540
0
  }
1541
1542
0
  ret = inet_pton(AF_INET6, hostname, &sa_v6.sin6_addr);
1543
0
  if (ret == 1) {
1544
0
    return false;
1545
0
  }
1546
1547
0
  return true;
1548
0
}
1549
1550
static isc_result_t
1551
0
isc__tls_toresult(isc_result_t fallback) {
1552
0
  isc_result_t result = fallback;
1553
0
  unsigned long err = ERR_peek_error();
1554
#if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED)
1555
  int lib = ERR_GET_LIB(err);
1556
#endif /* if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) */
1557
0
  int reason = ERR_GET_REASON(err);
1558
1559
0
  switch (reason) {
1560
  /*
1561
   * ERR_* errors are globally unique; others
1562
   * are unique per sublibrary
1563
   */
1564
0
  case ERR_R_MALLOC_FAILURE:
1565
0
    result = ISC_R_NOMEMORY;
1566
0
    break;
1567
0
  default:
1568
#if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED)
1569
    if (lib == ERR_R_ECDSA_LIB &&
1570
        reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED)
1571
    {
1572
      result = ISC_R_NOENTROPY;
1573
      break;
1574
    }
1575
#endif /* if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) */
1576
0
    break;
1577
0
  }
1578
1579
0
  return result;
1580
0
}
1581
1582
isc_result_t
1583
isc__tlserr2result(isc_logcategory_t category, isc_logmodule_t module,
1584
       const char *funcname, isc_result_t fallback,
1585
0
       const char *file, int line) {
1586
0
  isc_result_t result = isc__tls_toresult(fallback);
1587
1588
  /*
1589
   * This is an exception - normally, we don't allow this, but the
1590
   * compatibility shims in dst_openssl.h needs a call that just
1591
   * translates the error code and don't do any logging.
1592
   */
1593
0
  if (category == ISC_LOGCATEGORY_INVALID) {
1594
0
    goto done;
1595
0
  }
1596
1597
0
  isc_log_write(category, module, ISC_LOG_WARNING,
1598
0
          "%s (%s:%d) failed (%s)", funcname, file, line,
1599
0
          isc_result_totext(result));
1600
1601
0
  if (result == ISC_R_NOMEMORY) {
1602
0
    goto done;
1603
0
  }
1604
1605
0
  for (;;) {
1606
0
    const char *func, *data;
1607
0
    int flags;
1608
0
    unsigned long err = ERR_get_error_all(&file, &line, &func,
1609
0
                  &data, &flags);
1610
0
    if (err == 0U) {
1611
0
      break;
1612
0
    }
1613
1614
0
    char buf[256];
1615
0
    ERR_error_string_n(err, buf, sizeof(buf));
1616
1617
0
    isc_log_write(category, module, ISC_LOG_INFO, "%s:%s:%d:%s",
1618
0
            buf, file, line,
1619
0
            ((flags & ERR_TXT_STRING) != 0) ? data : "");
1620
0
  }
1621
1622
0
done:
1623
0
  ERR_clear_error();
1624
0
  return result;
1625
0
}