Coverage Report

Created: 2025-07-18 07:03

/src/bind9/lib/dns/kasp.c
Line
Count
Source (jump to first uncovered line)
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
dns_ttl_t
277
0
dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback) {
278
0
  REQUIRE(DNS_KASP_VALID(kasp));
279
0
  REQUIRE(kasp->frozen);
280
281
0
  if (kasp->zone_max_ttl == 0 && fallback) {
282
0
    return DEFAULT_TTLSIG;
283
0
  }
284
0
  return kasp->zone_max_ttl;
285
0
}
286
287
void
288
0
dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
289
0
  REQUIRE(DNS_KASP_VALID(kasp));
290
0
  REQUIRE(!kasp->frozen);
291
292
0
  kasp->zone_max_ttl = ttl;
293
0
}
294
295
uint32_t
296
0
dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) {
297
0
  REQUIRE(DNS_KASP_VALID(kasp));
298
0
  REQUIRE(kasp->frozen);
299
300
0
  return kasp->zone_propagation_delay;
301
0
}
302
303
void
304
0
dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) {
305
0
  REQUIRE(DNS_KASP_VALID(kasp));
306
0
  REQUIRE(!kasp->frozen);
307
308
0
  kasp->zone_propagation_delay = value;
309
0
}
310
311
dns_ttl_t
312
0
dns_kasp_dsttl(dns_kasp_t *kasp) {
313
0
  REQUIRE(DNS_KASP_VALID(kasp));
314
0
  REQUIRE(kasp->frozen);
315
316
0
  return kasp->parent_ds_ttl;
317
0
}
318
319
void
320
0
dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
321
0
  REQUIRE(DNS_KASP_VALID(kasp));
322
0
  REQUIRE(!kasp->frozen);
323
324
0
  kasp->parent_ds_ttl = ttl;
325
0
}
326
327
uint32_t
328
0
dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) {
329
0
  REQUIRE(DNS_KASP_VALID(kasp));
330
0
  REQUIRE(kasp->frozen);
331
332
0
  return kasp->parent_propagation_delay;
333
0
}
334
335
void
336
0
dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) {
337
0
  REQUIRE(DNS_KASP_VALID(kasp));
338
0
  REQUIRE(!kasp->frozen);
339
340
0
  kasp->parent_propagation_delay = value;
341
0
}
342
343
isc_result_t
344
0
dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp) {
345
0
  REQUIRE(kaspp != NULL && *kaspp == NULL);
346
347
0
  if (list == NULL) {
348
0
    return ISC_R_NOTFOUND;
349
0
  }
350
351
0
  ISC_LIST_FOREACH (*list, kasp, link) {
352
0
    if (strcmp(kasp->name, name) == 0) {
353
0
      dns_kasp_attach(kasp, kaspp);
354
0
      return ISC_R_SUCCESS;
355
0
    }
356
0
  }
357
358
0
  return ISC_R_NOTFOUND;
359
0
}
360
361
dns_kasp_keylist_t
362
0
dns_kasp_keys(dns_kasp_t *kasp) {
363
0
  REQUIRE(DNS_KASP_VALID(kasp));
364
0
  REQUIRE(kasp->frozen);
365
366
0
  return kasp->keys;
367
0
}
368
369
bool
370
0
dns_kasp_keylist_empty(dns_kasp_t *kasp) {
371
0
  REQUIRE(DNS_KASP_VALID(kasp));
372
373
0
  return ISC_LIST_EMPTY(kasp->keys);
374
0
}
375
376
void
377
0
dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key) {
378
0
  REQUIRE(DNS_KASP_VALID(kasp));
379
0
  REQUIRE(!kasp->frozen);
380
0
  REQUIRE(key != NULL);
381
382
0
  ISC_LIST_APPEND(kasp->keys, key, link);
383
0
}
384
385
void
386
0
dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp) {
387
0
  dns_kasp_key_t *key = NULL;
388
0
  dns_kasp_key_t k = { .tag_max = 0xffff, .length = -1 };
389
390
0
  REQUIRE(DNS_KASP_VALID(kasp));
391
0
  REQUIRE(keyp != NULL && *keyp == NULL);
392
393
0
  key = isc_mem_get(kasp->mctx, sizeof(*key));
394
0
  *key = k;
395
396
0
  key->mctx = NULL;
397
0
  isc_mem_attach(kasp->mctx, &key->mctx);
398
399
0
  ISC_LINK_INIT(key, link);
400
401
0
  *keyp = key;
402
0
}
403
404
void
405
0
dns_kasp_key_destroy(dns_kasp_key_t *key) {
406
0
  REQUIRE(key != NULL);
407
408
0
  if (key->keystore != NULL) {
409
0
    dns_keystore_detach(&key->keystore);
410
0
  }
411
0
  isc_mem_putanddetach(&key->mctx, key, sizeof(*key));
412
0
}
413
414
uint32_t
415
0
dns_kasp_key_algorithm(dns_kasp_key_t *key) {
416
0
  REQUIRE(key != NULL);
417
418
0
  return key->algorithm;
419
0
}
420
421
unsigned int
422
0
dns_kasp_key_size(dns_kasp_key_t *key) {
423
0
  unsigned int size = 0;
424
0
  unsigned int min = 0;
425
426
0
  REQUIRE(key != NULL);
427
428
0
  switch (key->algorithm) {
429
0
  case DST_ALG_RSASHA1:
430
0
  case DST_ALG_NSEC3RSASHA1:
431
0
  case DST_ALG_RSASHA256:
432
0
  case DST_ALG_RSASHA512:
433
0
  case DST_ALG_RSASHA256PRIVATEOID:
434
0
  case DST_ALG_RSASHA512PRIVATEOID:
435
0
    min = (key->algorithm == DST_ALG_RSASHA512) ? 1024 : 512;
436
0
    if (key->length > -1) {
437
0
      size = (unsigned int)key->length;
438
0
      if (size < min) {
439
0
        size = min;
440
0
      }
441
0
      if (size > 4096) {
442
0
        size = 4096;
443
0
      }
444
0
    } else {
445
0
      size = 2048;
446
0
    }
447
0
    break;
448
0
  case DST_ALG_ECDSA256:
449
0
    size = 256;
450
0
    break;
451
0
  case DST_ALG_ECDSA384:
452
0
    size = 384;
453
0
    break;
454
0
  case DST_ALG_ED25519:
455
0
    size = 256;
456
0
    break;
457
0
  case DST_ALG_ED448:
458
0
    size = 456;
459
0
    break;
460
0
  default:
461
    /* unsupported */
462
0
    break;
463
0
  }
464
0
  return size;
465
0
}
466
467
uint32_t
468
0
dns_kasp_key_lifetime(dns_kasp_key_t *key) {
469
0
  REQUIRE(key != NULL);
470
471
0
  return key->lifetime;
472
0
}
473
474
dns_keystore_t *
475
0
dns_kasp_key_keystore(dns_kasp_key_t *key) {
476
0
  REQUIRE(key != NULL);
477
478
0
  return key->keystore;
479
0
}
480
481
bool
482
0
dns_kasp_key_ksk(dns_kasp_key_t *key) {
483
0
  REQUIRE(key != NULL);
484
485
0
  return key->role & DNS_KASP_KEY_ROLE_KSK;
486
0
}
487
488
bool
489
0
dns_kasp_key_zsk(dns_kasp_key_t *key) {
490
0
  REQUIRE(key != NULL);
491
492
0
  return key->role & DNS_KASP_KEY_ROLE_ZSK;
493
0
}
494
495
uint16_t
496
0
dns_kasp_key_tagmin(dns_kasp_key_t *key) {
497
0
  REQUIRE(key != NULL);
498
0
  return key->tag_min;
499
0
}
500
501
uint16_t
502
0
dns_kasp_key_tagmax(dns_kasp_key_t *key) {
503
0
  REQUIRE(key != NULL);
504
0
  return key->tag_min;
505
0
}
506
507
bool
508
0
dns_kasp_key_match(dns_kasp_key_t *key, dns_dnsseckey_t *dkey) {
509
0
  isc_result_t ret;
510
0
  bool role = false;
511
512
0
  REQUIRE(key != NULL);
513
0
  REQUIRE(dkey != NULL);
514
515
  /* Matching algorithms? */
516
0
  if (dst_key_alg(dkey->key) != dns_kasp_key_algorithm(key)) {
517
0
    return false;
518
0
  }
519
  /* Matching length? */
520
0
  if (dst_key_size(dkey->key) != dns_kasp_key_size(key)) {
521
0
    return false;
522
0
  }
523
  /* Matching role? */
524
0
  ret = dst_key_getbool(dkey->key, DST_BOOL_KSK, &role);
525
0
  if (ret != ISC_R_SUCCESS || role != dns_kasp_key_ksk(key)) {
526
0
    return false;
527
0
  }
528
0
  ret = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &role);
529
0
  if (ret != ISC_R_SUCCESS || role != dns_kasp_key_zsk(key)) {
530
0
    return false;
531
0
  }
532
  /* Valid key tag range? */
533
0
  uint16_t id = dst_key_id(dkey->key);
534
0
  uint16_t rid = dst_key_rid(dkey->key);
535
0
  if (id < key->tag_min || id > key->tag_max) {
536
0
    return false;
537
0
  }
538
0
  if (rid < key->tag_min || rid > key->tag_max) {
539
0
    return false;
540
0
  }
541
542
  /* Found a match. */
543
0
  return true;
544
0
}
545
546
uint8_t
547
0
dns_kasp_nsec3iter(dns_kasp_t *kasp) {
548
0
  REQUIRE(kasp != NULL);
549
0
  REQUIRE(kasp->frozen);
550
0
  REQUIRE(kasp->nsec3);
551
552
0
  return kasp->nsec3param.iterations;
553
0
}
554
555
uint8_t
556
0
dns_kasp_nsec3flags(dns_kasp_t *kasp) {
557
0
  REQUIRE(kasp != NULL);
558
0
  REQUIRE(kasp->frozen);
559
0
  REQUIRE(kasp->nsec3);
560
561
0
  if (kasp->nsec3param.optout) {
562
0
    return 0x01;
563
0
  }
564
0
  return 0x00;
565
0
}
566
567
uint8_t
568
0
dns_kasp_nsec3saltlen(dns_kasp_t *kasp) {
569
0
  REQUIRE(kasp != NULL);
570
0
  REQUIRE(kasp->frozen);
571
0
  REQUIRE(kasp->nsec3);
572
573
0
  return kasp->nsec3param.saltlen;
574
0
}
575
576
bool
577
0
dns_kasp_nsec3(dns_kasp_t *kasp) {
578
0
  REQUIRE(kasp != NULL);
579
0
  REQUIRE(kasp->frozen);
580
581
0
  return kasp->nsec3;
582
0
}
583
584
void
585
0
dns_kasp_setnsec3(dns_kasp_t *kasp, bool nsec3) {
586
0
  REQUIRE(kasp != NULL);
587
0
  REQUIRE(!kasp->frozen);
588
589
0
  kasp->nsec3 = nsec3;
590
0
}
591
592
void
593
dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout,
594
0
           uint8_t saltlen) {
595
0
  REQUIRE(kasp != NULL);
596
0
  REQUIRE(!kasp->frozen);
597
0
  REQUIRE(kasp->nsec3);
598
599
0
  kasp->nsec3param.iterations = iter;
600
0
  kasp->nsec3param.optout = optout;
601
0
  kasp->nsec3param.saltlen = saltlen;
602
0
}
603
604
bool
605
0
dns_kasp_offlineksk(dns_kasp_t *kasp) {
606
0
  REQUIRE(kasp != NULL);
607
0
  REQUIRE(kasp->frozen);
608
609
0
  return kasp->offlineksk;
610
0
}
611
612
void
613
0
dns_kasp_setofflineksk(dns_kasp_t *kasp, bool offlineksk) {
614
0
  REQUIRE(kasp != NULL);
615
0
  REQUIRE(!kasp->frozen);
616
617
0
  kasp->offlineksk = offlineksk;
618
0
}
619
620
bool
621
0
dns_kasp_cdnskey(dns_kasp_t *kasp) {
622
0
  REQUIRE(kasp != NULL);
623
0
  REQUIRE(kasp->frozen);
624
625
0
  return kasp->cdnskey;
626
0
}
627
628
void
629
0
dns_kasp_setcdnskey(dns_kasp_t *kasp, bool cdnskey) {
630
0
  REQUIRE(kasp != NULL);
631
0
  REQUIRE(!kasp->frozen);
632
633
0
  kasp->cdnskey = cdnskey;
634
0
}
635
636
dns_kasp_digestlist_t
637
0
dns_kasp_digests(dns_kasp_t *kasp) {
638
0
  REQUIRE(DNS_KASP_VALID(kasp));
639
0
  REQUIRE(kasp->frozen);
640
641
0
  return kasp->digests;
642
0
}
643
644
void
645
0
dns_kasp_adddigest(dns_kasp_t *kasp, dns_dsdigest_t alg) {
646
0
  dns_kasp_digest_t *digest;
647
648
0
  REQUIRE(DNS_KASP_VALID(kasp));
649
0
  REQUIRE(!kasp->frozen);
650
651
  /* Suppress unsupported algorithms */
652
0
  if (!dst_ds_digest_supported(alg)) {
653
0
    return;
654
0
  }
655
656
  /* Suppress duplicates */
657
0
  ISC_LIST_FOREACH (kasp->digests, d, link) {
658
0
    if (d->digest == alg) {
659
0
      return;
660
0
    }
661
0
  }
662
663
0
  digest = isc_mem_get(kasp->mctx, sizeof(*digest));
664
0
  digest->digest = alg;
665
0
  ISC_LINK_INIT(digest, link);
666
0
  ISC_LIST_APPEND(kasp->digests, digest, link);
667
0
}