Coverage Report

Created: 2026-07-16 07:04

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