Coverage Report

Created: 2026-01-09 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/kasp.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
/*! \file */
15
16
#include <string.h>
17
18
#include <isc/assertions.h>
19
#include <isc/buffer.h>
20
#include <isc/file.h>
21
#include <isc/hex.h>
22
#include <isc/log.h>
23
#include <isc/mem.h>
24
#include <isc/util.h>
25
26
#include <dns/kasp.h>
27
#include <dns/keyvalues.h>
28
29
#include <dst/dst.h>
30
31
/* Default TTLsig (maximum zone ttl) */
32
0
#define DEFAULT_TTLSIG 604800 /* one week */
33
34
void
35
0
dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp) {
36
0
  dns_kasp_t *kasp;
37
0
  dns_kasp_t k = {
38
0
    .magic = DNS_KASP_MAGIC,
39
0
    .digests = ISC_LIST_INITIALIZER,
40
0
    .keys = ISC_LIST_INITIALIZER,
41
0
    .link = ISC_LINK_INITIALIZER,
42
0
  };
43
44
0
  REQUIRE(name != NULL);
45
0
  REQUIRE(kaspp != NULL && *kaspp == NULL);
46
47
0
  kasp = isc_mem_get(mctx, sizeof(*kasp));
48
0
  *kasp = k;
49
50
0
  kasp->mctx = NULL;
51
0
  isc_mem_attach(mctx, &kasp->mctx);
52
0
  kasp->name = isc_mem_strdup(mctx, name);
53
0
  isc_mutex_init(&kasp->lock);
54
0
  isc_refcount_init(&kasp->references, 1);
55
56
0
  *kaspp = kasp;
57
0
}
58
59
void
60
0
dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp) {
61
0
  REQUIRE(DNS_KASP_VALID(source));
62
0
  REQUIRE(targetp != NULL && *targetp == NULL);
63
64
0
  isc_refcount_increment(&source->references);
65
0
  *targetp = source;
66
0
}
67
68
static void
69
0
destroy(dns_kasp_t *kasp) {
70
0
  REQUIRE(!ISC_LINK_LINKED(kasp, link));
71
72
0
  ISC_LIST_FOREACH(kasp->keys, key, link) {
73
0
    ISC_LIST_UNLINK(kasp->keys, key, link);
74
0
    dns_kasp_key_destroy(key);
75
0
  }
76
0
  INSIST(ISC_LIST_EMPTY(kasp->keys));
77
78
0
  ISC_LIST_FOREACH(kasp->digests, digest, link) {
79
0
    ISC_LIST_UNLINK(kasp->digests, digest, link);
80
0
    isc_mem_put(kasp->mctx, digest, sizeof(*digest));
81
0
  }
82
0
  INSIST(ISC_LIST_EMPTY(kasp->digests));
83
84
0
  isc_mutex_destroy(&kasp->lock);
85
0
  isc_mem_free(kasp->mctx, kasp->name);
86
0
  isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp));
87
0
}
88
89
void
90
0
dns_kasp_detach(dns_kasp_t **kaspp) {
91
0
  REQUIRE(kaspp != NULL && DNS_KASP_VALID(*kaspp));
92
93
0
  dns_kasp_t *kasp = *kaspp;
94
0
  *kaspp = NULL;
95
96
0
  if (isc_refcount_decrement(&kasp->references) == 1) {
97
0
    destroy(kasp);
98
0
  }
99
0
}
100
101
const char *
102
0
dns_kasp_getname(dns_kasp_t *kasp) {
103
0
  REQUIRE(DNS_KASP_VALID(kasp));
104
105
0
  return kasp->name;
106
0
}
107
108
void
109
0
dns_kasp_freeze(dns_kasp_t *kasp) {
110
0
  REQUIRE(DNS_KASP_VALID(kasp));
111
0
  REQUIRE(!kasp->frozen);
112
113
0
  kasp->frozen = true;
114
0
}
115
116
void
117
0
dns_kasp_thaw(dns_kasp_t *kasp) {
118
0
  REQUIRE(DNS_KASP_VALID(kasp));
119
0
  REQUIRE(kasp->frozen);
120
121
0
  kasp->frozen = false;
122
0
}
123
124
uint32_t
125
0
dns_kasp_signdelay(dns_kasp_t *kasp) {
126
0
  REQUIRE(DNS_KASP_VALID(kasp));
127
0
  REQUIRE(kasp->frozen);
128
129
0
  return kasp->signatures_validity - kasp->signatures_refresh;
130
0
}
131
132
uint32_t
133
0
dns_kasp_sigjitter(dns_kasp_t *kasp) {
134
0
  REQUIRE(DNS_KASP_VALID(kasp));
135
0
  REQUIRE(kasp->frozen);
136
137
0
  return kasp->signatures_jitter;
138
0
}
139
140
void
141
0
dns_kasp_setsigjitter(dns_kasp_t *kasp, uint32_t value) {
142
0
  REQUIRE(DNS_KASP_VALID(kasp));
143
0
  REQUIRE(!kasp->frozen);
144
145
0
  kasp->signatures_jitter = value;
146
0
}
147
148
uint32_t
149
0
dns_kasp_sigrefresh(dns_kasp_t *kasp) {
150
0
  REQUIRE(DNS_KASP_VALID(kasp));
151
0
  REQUIRE(kasp->frozen);
152
153
0
  return kasp->signatures_refresh;
154
0
}
155
156
void
157
0
dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value) {
158
0
  REQUIRE(DNS_KASP_VALID(kasp));
159
0
  REQUIRE(!kasp->frozen);
160
161
0
  kasp->signatures_refresh = value;
162
0
}
163
164
uint32_t
165
0
dns_kasp_sigvalidity(dns_kasp_t *kasp) {
166
0
  REQUIRE(DNS_KASP_VALID(kasp));
167
0
  REQUIRE(kasp->frozen);
168
169
0
  return kasp->signatures_validity;
170
0
}
171
172
void
173
0
dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value) {
174
0
  REQUIRE(DNS_KASP_VALID(kasp));
175
0
  REQUIRE(!kasp->frozen);
176
177
0
  kasp->signatures_validity = value;
178
0
}
179
180
uint32_t
181
0
dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp) {
182
0
  REQUIRE(DNS_KASP_VALID(kasp));
183
0
  REQUIRE(kasp->frozen);
184
185
0
  return kasp->signatures_validity_dnskey;
186
0
}
187
188
void
189
0
dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value) {
190
0
  REQUIRE(DNS_KASP_VALID(kasp));
191
0
  REQUIRE(!kasp->frozen);
192
193
0
  kasp->signatures_validity_dnskey = value;
194
0
}
195
196
dns_ttl_t
197
0
dns_kasp_dnskeyttl(dns_kasp_t *kasp) {
198
0
  REQUIRE(DNS_KASP_VALID(kasp));
199
0
  REQUIRE(kasp->frozen);
200
201
0
  return kasp->dnskey_ttl;
202
0
}
203
204
void
205
0
dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
206
0
  REQUIRE(DNS_KASP_VALID(kasp));
207
0
  REQUIRE(!kasp->frozen);
208
209
0
  kasp->dnskey_ttl = ttl;
210
0
}
211
212
uint32_t
213
0
dns_kasp_purgekeys(dns_kasp_t *kasp) {
214
0
  REQUIRE(DNS_KASP_VALID(kasp));
215
0
  REQUIRE(kasp->frozen);
216
217
0
  return kasp->purge_keys;
218
0
}
219
220
void
221
0
dns_kasp_setpurgekeys(dns_kasp_t *kasp, uint32_t value) {
222
0
  REQUIRE(DNS_KASP_VALID(kasp));
223
0
  REQUIRE(!kasp->frozen);
224
225
0
  kasp->purge_keys = value;
226
0
}
227
228
uint32_t
229
0
dns_kasp_publishsafety(dns_kasp_t *kasp) {
230
0
  REQUIRE(DNS_KASP_VALID(kasp));
231
0
  REQUIRE(kasp->frozen);
232
233
0
  return kasp->publish_safety;
234
0
}
235
236
void
237
0
dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value) {
238
0
  REQUIRE(DNS_KASP_VALID(kasp));
239
0
  REQUIRE(!kasp->frozen);
240
241
0
  kasp->publish_safety = value;
242
0
}
243
244
uint32_t
245
0
dns_kasp_retiresafety(dns_kasp_t *kasp) {
246
0
  REQUIRE(DNS_KASP_VALID(kasp));
247
0
  REQUIRE(kasp->frozen);
248
249
0
  return kasp->retire_safety;
250
0
}
251
252
void
253
0
dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value) {
254
0
  REQUIRE(DNS_KASP_VALID(kasp));
255
0
  REQUIRE(!kasp->frozen);
256
257
0
  kasp->retire_safety = value;
258
0
}
259
260
bool
261
0
dns_kasp_inlinesigning(dns_kasp_t *kasp) {
262
0
  REQUIRE(DNS_KASP_VALID(kasp));
263
0
  REQUIRE(kasp->frozen);
264
265
0
  return kasp->inline_signing;
266
0
}
267
268
void
269
0
dns_kasp_setinlinesigning(dns_kasp_t *kasp, bool value) {
270
0
  REQUIRE(DNS_KASP_VALID(kasp));
271
0
  REQUIRE(!kasp->frozen);
272
273
0
  kasp->inline_signing = value;
274
0
}
275
276
bool
277
0
dns_kasp_manualmode(dns_kasp_t *kasp) {
278
0
  REQUIRE(DNS_KASP_VALID(kasp));
279
0
  REQUIRE(kasp->frozen);
280
281
0
  return kasp->manual_mode;
282
0
}
283
284
void
285
0
dns_kasp_setmanualmode(dns_kasp_t *kasp, bool value) {
286
0
  REQUIRE(DNS_KASP_VALID(kasp));
287
0
  REQUIRE(!kasp->frozen);
288
289
0
  kasp->manual_mode = value;
290
0
}
291
292
dns_ttl_t
293
0
dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback) {
294
0
  REQUIRE(DNS_KASP_VALID(kasp));
295
0
  REQUIRE(kasp->frozen);
296
297
0
  if (kasp->zone_max_ttl == 0 && fallback) {
298
0
    return DEFAULT_TTLSIG;
299
0
  }
300
0
  return kasp->zone_max_ttl;
301
0
}
302
303
void
304
0
dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
305
0
  REQUIRE(DNS_KASP_VALID(kasp));
306
0
  REQUIRE(!kasp->frozen);
307
308
0
  kasp->zone_max_ttl = ttl;
309
0
}
310
311
uint32_t
312
0
dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) {
313
0
  REQUIRE(DNS_KASP_VALID(kasp));
314
0
  REQUIRE(kasp->frozen);
315
316
0
  return kasp->zone_propagation_delay;
317
0
}
318
319
void
320
0
dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) {
321
0
  REQUIRE(DNS_KASP_VALID(kasp));
322
0
  REQUIRE(!kasp->frozen);
323
324
0
  kasp->zone_propagation_delay = value;
325
0
}
326
327
dns_ttl_t
328
0
dns_kasp_dsttl(dns_kasp_t *kasp) {
329
0
  REQUIRE(DNS_KASP_VALID(kasp));
330
0
  REQUIRE(kasp->frozen);
331
332
0
  return kasp->parent_ds_ttl;
333
0
}
334
335
void
336
0
dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
337
0
  REQUIRE(DNS_KASP_VALID(kasp));
338
0
  REQUIRE(!kasp->frozen);
339
340
0
  kasp->parent_ds_ttl = ttl;
341
0
}
342
343
uint32_t
344
0
dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) {
345
0
  REQUIRE(DNS_KASP_VALID(kasp));
346
0
  REQUIRE(kasp->frozen);
347
348
0
  return kasp->parent_propagation_delay;
349
0
}
350
351
void
352
0
dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) {
353
0
  REQUIRE(DNS_KASP_VALID(kasp));
354
0
  REQUIRE(!kasp->frozen);
355
356
0
  kasp->parent_propagation_delay = value;
357
0
}
358
359
isc_result_t
360
0
dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp) {
361
0
  REQUIRE(kaspp != NULL && *kaspp == NULL);
362
363
0
  if (list == NULL) {
364
0
    return ISC_R_NOTFOUND;
365
0
  }
366
367
0
  ISC_LIST_FOREACH(*list, kasp, link) {
368
0
    if (strcmp(kasp->name, name) == 0) {
369
0
      dns_kasp_attach(kasp, kaspp);
370
0
      return ISC_R_SUCCESS;
371
0
    }
372
0
  }
373
374
0
  return ISC_R_NOTFOUND;
375
0
}
376
377
dns_kasp_keylist_t
378
0
dns_kasp_keys(dns_kasp_t *kasp) {
379
0
  REQUIRE(DNS_KASP_VALID(kasp));
380
0
  REQUIRE(kasp->frozen);
381
382
0
  return kasp->keys;
383
0
}
384
385
bool
386
0
dns_kasp_keylist_empty(dns_kasp_t *kasp) {
387
0
  REQUIRE(DNS_KASP_VALID(kasp));
388
389
0
  return ISC_LIST_EMPTY(kasp->keys);
390
0
}
391
392
void
393
0
dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key) {
394
0
  REQUIRE(DNS_KASP_VALID(kasp));
395
0
  REQUIRE(!kasp->frozen);
396
0
  REQUIRE(key != NULL);
397
398
0
  ISC_LIST_APPEND(kasp->keys, key, link);
399
0
}
400
401
void
402
0
dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp) {
403
0
  dns_kasp_key_t *key = NULL;
404
0
  dns_kasp_key_t k = { .tag_max = 0xffff, .length = -1 };
405
406
0
  REQUIRE(DNS_KASP_VALID(kasp));
407
0
  REQUIRE(keyp != NULL && *keyp == NULL);
408
409
0
  key = isc_mem_get(kasp->mctx, sizeof(*key));
410
0
  *key = k;
411
412
0
  key->mctx = NULL;
413
0
  isc_mem_attach(kasp->mctx, &key->mctx);
414
415
0
  ISC_LINK_INIT(key, link);
416
417
0
  *keyp = key;
418
0
}
419
420
void
421
0
dns_kasp_key_destroy(dns_kasp_key_t *key) {
422
0
  REQUIRE(key != NULL);
423
424
0
  if (key->keystore != NULL) {
425
0
    dns_keystore_detach(&key->keystore);
426
0
  }
427
0
  isc_mem_putanddetach(&key->mctx, key, sizeof(*key));
428
0
}
429
430
uint32_t
431
0
dns_kasp_key_algorithm(dns_kasp_key_t *key) {
432
0
  REQUIRE(key != NULL);
433
434
0
  return key->algorithm;
435
0
}
436
437
unsigned int
438
0
dns_kasp_key_size(dns_kasp_key_t *key) {
439
0
  unsigned int size = 0;
440
0
  unsigned int min = 0;
441
442
0
  REQUIRE(key != NULL);
443
444
0
  switch (key->algorithm) {
445
0
  case DST_ALG_RSASHA1:
446
0
  case DST_ALG_NSEC3RSASHA1:
447
0
  case DST_ALG_RSASHA256:
448
0
  case DST_ALG_RSASHA512:
449
0
  case DST_ALG_RSASHA256PRIVATEOID:
450
0
  case DST_ALG_RSASHA512PRIVATEOID:
451
0
    min = (key->algorithm == DST_ALG_RSASHA512) ? 1024 : 512;
452
0
    if (key->length > -1) {
453
0
      size = (unsigned int)key->length;
454
0
      if (size < min) {
455
0
        size = min;
456
0
      }
457
0
      if (size > 4096) {
458
0
        size = 4096;
459
0
      }
460
0
    } else {
461
0
      size = 2048;
462
0
    }
463
0
    break;
464
0
  case DST_ALG_ECDSA256:
465
0
    size = 256;
466
0
    break;
467
0
  case DST_ALG_ECDSA384:
468
0
    size = 384;
469
0
    break;
470
0
  case DST_ALG_ED25519:
471
0
    size = 256;
472
0
    break;
473
0
  case DST_ALG_ED448:
474
0
    size = 456;
475
0
    break;
476
0
  default:
477
    /* unsupported */
478
0
    break;
479
0
  }
480
0
  return size;
481
0
}
482
483
uint32_t
484
0
dns_kasp_key_lifetime(dns_kasp_key_t *key) {
485
0
  REQUIRE(key != NULL);
486
487
0
  return key->lifetime;
488
0
}
489
490
dns_keystore_t *
491
0
dns_kasp_key_keystore(dns_kasp_key_t *key) {
492
0
  REQUIRE(key != NULL);
493
494
0
  return key->keystore;
495
0
}
496
497
bool
498
0
dns_kasp_key_ksk(dns_kasp_key_t *key) {
499
0
  REQUIRE(key != NULL);
500
501
0
  return key->role & DNS_KASP_KEY_ROLE_KSK;
502
0
}
503
504
bool
505
0
dns_kasp_key_zsk(dns_kasp_key_t *key) {
506
0
  REQUIRE(key != NULL);
507
508
0
  return key->role & DNS_KASP_KEY_ROLE_ZSK;
509
0
}
510
511
uint16_t
512
0
dns_kasp_key_tagmin(dns_kasp_key_t *key) {
513
0
  REQUIRE(key != NULL);
514
0
  return key->tag_min;
515
0
}
516
517
uint16_t
518
0
dns_kasp_key_tagmax(dns_kasp_key_t *key) {
519
0
  REQUIRE(key != NULL);
520
0
  return key->tag_min;
521
0
}
522
523
bool
524
0
dns_kasp_key_match(dns_kasp_key_t *key, dns_dnsseckey_t *dkey) {
525
0
  isc_result_t result;
526
0
  bool role = false;
527
528
0
  REQUIRE(key != NULL);
529
0
  REQUIRE(dkey != NULL);
530
531
  /* Matching algorithms? */
532
0
  if (dst_key_alg(dkey->key) != dns_kasp_key_algorithm(key)) {
533
0
    return false;
534
0
  }
535
  /* Matching length? */
536
0
  if (dst_key_size(dkey->key) != dns_kasp_key_size(key)) {
537
0
    return false;
538
0
  }
539
  /* Matching role? */
540
0
  result = dst_key_getbool(dkey->key, DST_BOOL_KSK, &role);
541
0
  if (result != ISC_R_SUCCESS || role != dns_kasp_key_ksk(key)) {
542
0
    return false;
543
0
  }
544
0
  result = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &role);
545
0
  if (result != ISC_R_SUCCESS || role != dns_kasp_key_zsk(key)) {
546
0
    return false;
547
0
  }
548
  /* Valid key tag range? */
549
0
  uint16_t id = dst_key_id(dkey->key);
550
0
  uint16_t rid = dst_key_rid(dkey->key);
551
0
  if (id < key->tag_min || id > key->tag_max) {
552
0
    return false;
553
0
  }
554
0
  if (rid < key->tag_min || rid > key->tag_max) {
555
0
    return false;
556
0
  }
557
558
  /* Found a match. */
559
0
  return true;
560
0
}
561
562
void
563
0
dns_kasp_key_format(dns_kasp_key_t *key, char *cp, unsigned int size) {
564
0
  REQUIRE(key != NULL);
565
0
  REQUIRE(cp != NULL);
566
567
0
  char algstr[DNS_NAME_FORMATSIZE];
568
0
  bool csk = dns_kasp_key_ksk(key) && dns_kasp_key_zsk(key);
569
0
  const char *rolestr = (csk ? "csk"
570
0
           : (dns_kasp_key_ksk(key) ? "ksk" : "zsk"));
571
572
0
  dst_algorithm_format(key->algorithm, algstr, sizeof(algstr));
573
0
  snprintf(cp, size, "%s algorithm:%s length:%u tag-range:%u-%u", rolestr,
574
0
     algstr, dns_kasp_key_size(key), key->tag_min, key->tag_max);
575
0
}
576
577
uint8_t
578
0
dns_kasp_nsec3iter(dns_kasp_t *kasp) {
579
0
  REQUIRE(kasp != NULL);
580
0
  REQUIRE(kasp->frozen);
581
0
  REQUIRE(kasp->nsec3);
582
583
0
  return kasp->nsec3param.iterations;
584
0
}
585
586
uint8_t
587
0
dns_kasp_nsec3flags(dns_kasp_t *kasp) {
588
0
  REQUIRE(kasp != NULL);
589
0
  REQUIRE(kasp->frozen);
590
0
  REQUIRE(kasp->nsec3);
591
592
0
  if (kasp->nsec3param.optout) {
593
0
    return 0x01;
594
0
  }
595
0
  return 0x00;
596
0
}
597
598
uint8_t
599
0
dns_kasp_nsec3saltlen(dns_kasp_t *kasp) {
600
0
  REQUIRE(kasp != NULL);
601
0
  REQUIRE(kasp->frozen);
602
0
  REQUIRE(kasp->nsec3);
603
604
0
  return kasp->nsec3param.saltlen;
605
0
}
606
607
bool
608
0
dns_kasp_nsec3(dns_kasp_t *kasp) {
609
0
  REQUIRE(kasp != NULL);
610
0
  REQUIRE(kasp->frozen);
611
612
0
  return kasp->nsec3;
613
0
}
614
615
void
616
0
dns_kasp_setnsec3(dns_kasp_t *kasp, bool nsec3) {
617
0
  REQUIRE(kasp != NULL);
618
0
  REQUIRE(!kasp->frozen);
619
620
0
  kasp->nsec3 = nsec3;
621
0
}
622
623
void
624
dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout,
625
0
           uint8_t saltlen) {
626
0
  REQUIRE(kasp != NULL);
627
0
  REQUIRE(!kasp->frozen);
628
0
  REQUIRE(kasp->nsec3);
629
630
0
  kasp->nsec3param.iterations = iter;
631
0
  kasp->nsec3param.optout = optout;
632
0
  kasp->nsec3param.saltlen = saltlen;
633
0
}
634
635
bool
636
0
dns_kasp_offlineksk(dns_kasp_t *kasp) {
637
0
  REQUIRE(kasp != NULL);
638
0
  REQUIRE(kasp->frozen);
639
640
0
  return kasp->offlineksk;
641
0
}
642
643
void
644
0
dns_kasp_setofflineksk(dns_kasp_t *kasp, bool offlineksk) {
645
0
  REQUIRE(kasp != NULL);
646
0
  REQUIRE(!kasp->frozen);
647
648
0
  kasp->offlineksk = offlineksk;
649
0
}
650
651
bool
652
0
dns_kasp_cdnskey(dns_kasp_t *kasp) {
653
0
  REQUIRE(kasp != NULL);
654
0
  REQUIRE(kasp->frozen);
655
656
0
  return kasp->cdnskey;
657
0
}
658
659
void
660
0
dns_kasp_setcdnskey(dns_kasp_t *kasp, bool cdnskey) {
661
0
  REQUIRE(kasp != NULL);
662
0
  REQUIRE(!kasp->frozen);
663
664
0
  kasp->cdnskey = cdnskey;
665
0
}
666
667
dns_kasp_digestlist_t
668
0
dns_kasp_digests(dns_kasp_t *kasp) {
669
0
  REQUIRE(DNS_KASP_VALID(kasp));
670
0
  REQUIRE(kasp->frozen);
671
672
0
  return kasp->digests;
673
0
}
674
675
void
676
0
dns_kasp_adddigest(dns_kasp_t *kasp, dns_dsdigest_t alg) {
677
0
  dns_kasp_digest_t *digest;
678
679
0
  REQUIRE(DNS_KASP_VALID(kasp));
680
0
  REQUIRE(!kasp->frozen);
681
682
  /* Suppress unsupported algorithms */
683
0
  if (!dst_ds_digest_supported(alg)) {
684
0
    return;
685
0
  }
686
687
  /* Suppress duplicates */
688
0
  ISC_LIST_FOREACH(kasp->digests, d, link) {
689
0
    if (d->digest == alg) {
690
0
      return;
691
0
    }
692
0
  }
693
694
0
  digest = isc_mem_get(kasp->mctx, sizeof(*digest));
695
0
  digest->digest = alg;
696
0
  ISC_LINK_INIT(digest, link);
697
  ISC_LIST_APPEND(kasp->digests, digest, link);
698
0
}