Coverage Report

Created: 2026-02-26 06:45

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