Coverage Report

Created: 2026-02-26 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/rdata/generic/sig_24.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
/* RFC2535 */
15
16
#ifndef RDATA_GENERIC_SIG_24_C
17
#define RDATA_GENERIC_SIG_24_C
18
19
17.0k
#define RRTYPE_SIG_ATTRIBUTES (0)
20
21
static isc_result_t
22
818
fromtext_sig(ARGS_FROMTEXT) {
23
818
  isc_token_t token;
24
818
  unsigned char alg, c;
25
818
  long i;
26
818
  dns_rdatatype_t covered;
27
818
  char *e;
28
818
  isc_result_t result;
29
818
  isc_buffer_t buffer;
30
818
  uint32_t time_signed, time_expire;
31
818
  unsigned int used;
32
33
818
  REQUIRE(type == dns_rdatatype_sig);
34
35
818
  UNUSED(type);
36
818
  UNUSED(rdclass);
37
818
  UNUSED(callbacks);
38
39
  /*
40
   * Type covered.
41
   */
42
818
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
43
818
              false));
44
812
  result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
45
812
  if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
46
783
    i = strtol(DNS_AS_STR(token), &e, 10);
47
783
    if (i < 0 || i > 65535) {
48
244
      RETTOK(ISC_R_RANGE);
49
244
    }
50
539
    if (*e != 0) {
51
143
      RETTOK(result);
52
143
    }
53
396
    covered = (dns_rdatatype_t)i;
54
396
  }
55
425
  RETERR(uint16_tobuffer(covered, target));
56
57
  /*
58
   * Algorithm.
59
   */
60
425
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
61
425
              false));
62
366
  RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
63
311
  RETERR(mem_tobuffer(target, &alg, 1));
64
65
  /*
66
   * Labels.
67
   */
68
311
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
69
311
              false));
70
307
  if (token.value.as_ulong > 0xffU) {
71
42
    RETTOK(ISC_R_RANGE);
72
42
  }
73
265
  c = (unsigned char)token.value.as_ulong;
74
265
  RETERR(mem_tobuffer(target, &c, 1));
75
76
  /*
77
   * Original ttl.
78
   */
79
265
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
80
265
              false));
81
250
  RETERR(uint32_tobuffer(token.value.as_ulong, target));
82
83
  /*
84
   * Signature expiration.
85
   */
86
250
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
87
250
              false));
88
248
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
89
245
  RETERR(uint32_tobuffer(time_expire, target));
90
91
  /*
92
   * Time signed.
93
   */
94
245
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
95
245
              false));
96
243
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
97
241
  RETERR(uint32_tobuffer(time_signed, target));
98
99
  /*
100
   * Key footprint.
101
   */
102
241
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
103
241
              false));
104
239
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
105
106
  /*
107
   * Signer.
108
   */
109
237
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
110
237
              false));
111
235
  buffer_fromregion(&buffer, &token.value.as_region);
112
235
  if (origin == NULL) {
113
5
    origin = dns_rootname;
114
5
  }
115
235
  RETTOK(dns_name_wirefromtext(&buffer, origin, options, target));
116
117
  /*
118
   * Sig.
119
   */
120
233
  used = isc_buffer_usedlength(target);
121
122
233
  RETERR(isc_base64_tobuffer(lexer, target, isc_one_or_more));
123
124
231
  if (alg == DNS_KEYALG_PRIVATEDNS || alg == DNS_KEYALG_PRIVATEOID) {
125
8
    isc_buffer_t b;
126
127
    /*
128
     * Set up 'b' so that the signature data can be parsed.
129
     */
130
8
    b = *target;
131
8
    b.active = b.used;
132
8
    b.current = used;
133
134
8
    RETERR(check_private(&b, alg));
135
7
  }
136
137
230
  return ISC_R_SUCCESS;
138
231
}
139
140
static isc_result_t
141
4.19k
totext_sig(ARGS_TOTEXT) {
142
4.19k
  isc_region_t sr;
143
4.19k
  char buf[sizeof("4294967295")];
144
4.19k
  dns_rdatatype_t covered;
145
4.19k
  unsigned long ttl;
146
4.19k
  unsigned long when;
147
4.19k
  unsigned long exp;
148
4.19k
  unsigned long foot;
149
4.19k
  dns_name_t name;
150
4.19k
  dns_name_t prefix;
151
4.19k
  unsigned int opts;
152
153
4.19k
  REQUIRE(rdata->type == dns_rdatatype_sig);
154
4.19k
  REQUIRE(rdata->length != 0);
155
156
4.19k
  dns_rdata_toregion(rdata, &sr);
157
158
  /*
159
   * Type covered.
160
   */
161
4.19k
  covered = uint16_fromregion(&sr);
162
4.19k
  isc_region_consume(&sr, 2);
163
  /*
164
   * XXXAG We should have something like dns_rdatatype_isknown()
165
   * that does the right thing with type 0.
166
   */
167
4.19k
  if (dns_rdatatype_isknown(covered) && covered != 0) {
168
1.46k
    RETERR(dns_rdatatype_totext(covered, target));
169
2.72k
  } else {
170
2.72k
    snprintf(buf, sizeof(buf), "%u", covered);
171
2.72k
    RETERR(str_totext(buf, target));
172
2.72k
  }
173
4.19k
  RETERR(str_totext(" ", target));
174
175
  /*
176
   * Algorithm.
177
   */
178
4.19k
  snprintf(buf, sizeof(buf), "%u", sr.base[0]);
179
4.19k
  isc_region_consume(&sr, 1);
180
4.19k
  RETERR(str_totext(buf, target));
181
4.19k
  RETERR(str_totext(" ", target));
182
183
  /*
184
   * Labels.
185
   */
186
4.19k
  snprintf(buf, sizeof(buf), "%u", sr.base[0]);
187
4.19k
  isc_region_consume(&sr, 1);
188
4.19k
  RETERR(str_totext(buf, target));
189
4.19k
  RETERR(str_totext(" ", target));
190
191
  /*
192
   * Ttl.
193
   */
194
4.19k
  ttl = uint32_fromregion(&sr);
195
4.19k
  isc_region_consume(&sr, 4);
196
4.19k
  snprintf(buf, sizeof(buf), "%lu", ttl);
197
4.19k
  RETERR(str_totext(buf, target));
198
4.19k
  RETERR(str_totext(" ", target));
199
200
  /*
201
   * Sig exp.
202
   */
203
4.19k
  exp = uint32_fromregion(&sr);
204
4.19k
  isc_region_consume(&sr, 4);
205
4.19k
  RETERR(dns_time32_totext(exp, target));
206
207
4.19k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
208
114
    RETERR(str_totext(" (", target));
209
114
  }
210
4.19k
  RETERR(str_totext(tctx->linebreak, target));
211
212
  /*
213
   * Time signed.
214
   */
215
4.19k
  when = uint32_fromregion(&sr);
216
4.19k
  isc_region_consume(&sr, 4);
217
4.19k
  RETERR(dns_time32_totext(when, target));
218
4.19k
  RETERR(str_totext(" ", target));
219
220
  /*
221
   * Footprint.
222
   */
223
4.19k
  foot = uint16_fromregion(&sr);
224
4.19k
  isc_region_consume(&sr, 2);
225
4.19k
  snprintf(buf, sizeof(buf), "%lu", foot);
226
4.19k
  RETERR(str_totext(buf, target));
227
4.19k
  RETERR(str_totext(" ", target));
228
229
  /*
230
   * Signer.
231
   */
232
4.19k
  dns_name_init(&name);
233
4.19k
  dns_name_init(&prefix);
234
4.19k
  dns_name_fromregion(&name, &sr);
235
4.19k
  isc_region_consume(&sr, name_length(&name));
236
4.19k
  opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT
237
4.19k
               : 0;
238
4.19k
  RETERR(dns_name_totext(&prefix, opts, target));
239
240
  /*
241
   * Sig.
242
   */
243
4.19k
  RETERR(str_totext(tctx->linebreak, target));
244
4.19k
  if (tctx->width == 0) { /* No splitting */
245
0
    RETERR(isc_base64_totext(&sr, 60, "", target));
246
4.19k
  } else {
247
4.19k
    RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak,
248
4.19k
           target));
249
4.19k
  }
250
4.19k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
251
114
    RETERR(str_totext(" )", target));
252
114
  }
253
254
4.19k
  return ISC_R_SUCCESS;
255
4.19k
}
256
257
static isc_result_t
258
7.01k
fromwire_sig(ARGS_FROMWIRE) {
259
7.01k
  isc_region_t sr;
260
7.01k
  dns_name_t name;
261
7.01k
  unsigned char algorithm;
262
263
7.01k
  REQUIRE(type == dns_rdatatype_sig);
264
265
7.01k
  UNUSED(type);
266
7.01k
  UNUSED(rdclass);
267
268
7.01k
  dctx = dns_decompress_setpermitted(dctx, false);
269
270
7.01k
  isc_buffer_activeregion(source, &sr);
271
  /*
272
   * type covered: 2
273
   * algorithm: 1
274
   * labels: 1
275
   * original ttl: 4
276
   * signature expiration: 4
277
   * time signed: 4
278
   * key footprint: 2
279
   */
280
7.01k
  if (sr.length < 18) {
281
34
    return ISC_R_UNEXPECTEDEND;
282
34
  }
283
284
6.97k
  algorithm = sr.base[2];
285
286
6.97k
  isc_buffer_forward(source, 18);
287
6.97k
  RETERR(mem_tobuffer(target, sr.base, 18));
288
289
  /*
290
   * Signer.
291
   */
292
6.75k
  dns_name_init(&name);
293
6.75k
  RETERR(dns_name_fromwire(&name, source, dctx, target));
294
295
  /*
296
   * Sig.
297
   */
298
6.52k
  isc_buffer_activeregion(source, &sr);
299
6.52k
  if (sr.length == 0) {
300
16
    return ISC_R_UNEXPECTEDEND;
301
16
  }
302
303
6.50k
  if (algorithm == DNS_KEYALG_PRIVATEDNS ||
304
5.97k
      algorithm == DNS_KEYALG_PRIVATEOID)
305
762
  {
306
762
    isc_buffer_t b = *source;
307
762
    RETERR(check_private(&b, algorithm));
308
694
  }
309
310
6.43k
  isc_buffer_forward(source, sr.length);
311
6.43k
  return mem_tobuffer(target, sr.base, sr.length);
312
6.50k
}
313
314
static isc_result_t
315
2.08k
towire_sig(ARGS_TOWIRE) {
316
2.08k
  isc_region_t sr;
317
2.08k
  dns_name_t name;
318
319
2.08k
  REQUIRE(rdata->type == dns_rdatatype_sig);
320
2.08k
  REQUIRE(rdata->length != 0);
321
322
2.08k
  dns_compress_setpermitted(cctx, false);
323
2.08k
  dns_rdata_toregion(rdata, &sr);
324
  /*
325
   * type covered: 2
326
   * algorithm: 1
327
   * labels: 1
328
   * original ttl: 4
329
   * signature expiration: 4
330
   * time signed: 4
331
   * key footprint: 2
332
   */
333
2.08k
  RETERR(mem_tobuffer(target, sr.base, 18));
334
2.08k
  isc_region_consume(&sr, 18);
335
336
  /*
337
   * Signer.
338
   */
339
2.08k
  dns_name_init(&name);
340
2.08k
  dns_name_fromregion(&name, &sr);
341
2.08k
  isc_region_consume(&sr, name_length(&name));
342
2.08k
  RETERR(dns_name_towire(&name, cctx, target));
343
344
  /*
345
   * Signature.
346
   */
347
2.08k
  return mem_tobuffer(target, sr.base, sr.length);
348
2.08k
}
349
350
static int
351
2.35k
compare_sig(ARGS_COMPARE) {
352
2.35k
  isc_region_t r1;
353
2.35k
  isc_region_t r2;
354
2.35k
  dns_name_t name1;
355
2.35k
  dns_name_t name2;
356
2.35k
  int order;
357
358
2.35k
  REQUIRE(rdata1->type == rdata2->type);
359
2.35k
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
360
2.35k
  REQUIRE(rdata1->type == dns_rdatatype_sig);
361
2.35k
  REQUIRE(rdata1->length != 0);
362
2.35k
  REQUIRE(rdata2->length != 0);
363
364
2.35k
  dns_rdata_toregion(rdata1, &r1);
365
2.35k
  dns_rdata_toregion(rdata2, &r2);
366
367
2.35k
  INSIST(r1.length > 18);
368
2.35k
  INSIST(r2.length > 18);
369
2.35k
  r1.length = 18;
370
2.35k
  r2.length = 18;
371
2.35k
  order = isc_region_compare(&r1, &r2);
372
2.35k
  if (order != 0) {
373
1.08k
    return order;
374
1.08k
  }
375
376
1.27k
  dns_name_init(&name1);
377
1.27k
  dns_name_init(&name2);
378
1.27k
  dns_rdata_toregion(rdata1, &r1);
379
1.27k
  dns_rdata_toregion(rdata2, &r2);
380
1.27k
  isc_region_consume(&r1, 18);
381
1.27k
  isc_region_consume(&r2, 18);
382
1.27k
  dns_name_fromregion(&name1, &r1);
383
1.27k
  dns_name_fromregion(&name2, &r2);
384
1.27k
  order = dns_name_rdatacompare(&name1, &name2);
385
1.27k
  if (order != 0) {
386
425
    return order;
387
425
  }
388
389
851
  isc_region_consume(&r1, name_length(&name1));
390
851
  isc_region_consume(&r2, name_length(&name2));
391
392
851
  return isc_region_compare(&r1, &r2);
393
1.27k
}
394
395
static isc_result_t
396
0
fromstruct_sig(ARGS_FROMSTRUCT) {
397
0
  dns_rdata_sig_t *sig = source;
398
399
0
  REQUIRE(type == dns_rdatatype_sig);
400
0
  REQUIRE(sig != NULL);
401
0
  REQUIRE(sig->common.rdtype == type);
402
0
  REQUIRE(sig->common.rdclass == rdclass);
403
0
  REQUIRE(sig->signature != NULL || sig->siglen == 0);
404
405
0
  UNUSED(type);
406
0
  UNUSED(rdclass);
407
408
  /*
409
   * Type covered.
410
   */
411
0
  RETERR(uint16_tobuffer(sig->covered, target));
412
413
  /*
414
   * Algorithm.
415
   */
416
0
  RETERR(uint8_tobuffer(sig->algorithm, target));
417
418
  /*
419
   * Labels.
420
   */
421
0
  RETERR(uint8_tobuffer(sig->labels, target));
422
423
  /*
424
   * Original TTL.
425
   */
426
0
  RETERR(uint32_tobuffer(sig->originalttl, target));
427
428
  /*
429
   * Expire time.
430
   */
431
0
  RETERR(uint32_tobuffer(sig->timeexpire, target));
432
433
  /*
434
   * Time signed.
435
   */
436
0
  RETERR(uint32_tobuffer(sig->timesigned, target));
437
438
  /*
439
   * Key ID.
440
   */
441
0
  RETERR(uint16_tobuffer(sig->keyid, target));
442
443
  /*
444
   * Signer name.
445
   */
446
0
  RETERR(name_tobuffer(&sig->signer, target));
447
448
  /*
449
   * Signature.
450
   */
451
0
  return mem_tobuffer(target, sig->signature, sig->siglen);
452
0
}
453
454
static isc_result_t
455
512
tostruct_sig(ARGS_TOSTRUCT) {
456
512
  isc_region_t sr;
457
512
  dns_rdata_sig_t *sig = target;
458
512
  dns_name_t signer;
459
460
512
  REQUIRE(rdata->type == dns_rdatatype_sig);
461
512
  REQUIRE(sig != NULL);
462
512
  REQUIRE(rdata->length != 0);
463
464
512
  DNS_RDATACOMMON_INIT(sig, rdata->type, rdata->rdclass);
465
466
512
  dns_rdata_toregion(rdata, &sr);
467
468
  /*
469
   * Type covered.
470
   */
471
512
  sig->covered = uint16_fromregion(&sr);
472
512
  isc_region_consume(&sr, 2);
473
474
  /*
475
   * Algorithm.
476
   */
477
512
  sig->algorithm = uint8_fromregion(&sr);
478
512
  isc_region_consume(&sr, 1);
479
480
  /*
481
   * Labels.
482
   */
483
512
  sig->labels = uint8_fromregion(&sr);
484
512
  isc_region_consume(&sr, 1);
485
486
  /*
487
   * Original TTL.
488
   */
489
512
  sig->originalttl = uint32_fromregion(&sr);
490
512
  isc_region_consume(&sr, 4);
491
492
  /*
493
   * Expire time.
494
   */
495
512
  sig->timeexpire = uint32_fromregion(&sr);
496
512
  isc_region_consume(&sr, 4);
497
498
  /*
499
   * Time signed.
500
   */
501
512
  sig->timesigned = uint32_fromregion(&sr);
502
512
  isc_region_consume(&sr, 4);
503
504
  /*
505
   * Key ID.
506
   */
507
512
  sig->keyid = uint16_fromregion(&sr);
508
512
  isc_region_consume(&sr, 2);
509
510
512
  dns_name_init(&signer);
511
512
  dns_name_fromregion(&signer, &sr);
512
512
  dns_name_init(&sig->signer);
513
512
  name_duporclone(&signer, mctx, &sig->signer);
514
512
  isc_region_consume(&sr, name_length(&sig->signer));
515
516
  /*
517
   * Signature.
518
   */
519
512
  sig->siglen = sr.length;
520
512
  sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
521
512
  sig->mctx = mctx;
522
512
  return ISC_R_SUCCESS;
523
512
}
524
525
static void
526
512
freestruct_sig(ARGS_FREESTRUCT) {
527
512
  dns_rdata_sig_t *sig = (dns_rdata_sig_t *)source;
528
529
512
  REQUIRE(sig != NULL);
530
512
  REQUIRE(sig->common.rdtype == dns_rdatatype_sig);
531
532
512
  if (sig->mctx == NULL) {
533
512
    return;
534
512
  }
535
536
0
  dns_name_free(&sig->signer, sig->mctx);
537
0
  if (sig->signature != NULL) {
538
0
    isc_mem_free(sig->mctx, sig->signature);
539
0
  }
540
0
  sig->mctx = NULL;
541
0
}
542
543
static isc_result_t
544
0
additionaldata_sig(ARGS_ADDLDATA) {
545
0
  REQUIRE(rdata->type == dns_rdatatype_sig);
546
547
0
  UNUSED(rdata);
548
0
  UNUSED(owner);
549
0
  UNUSED(add);
550
0
  UNUSED(arg);
551
552
0
  return ISC_R_SUCCESS;
553
0
}
554
555
static isc_result_t
556
0
digest_sig(ARGS_DIGEST) {
557
0
  isc_region_t r1, r2;
558
0
  dns_name_t name;
559
560
0
  REQUIRE(rdata->type == dns_rdatatype_sig);
561
562
0
  dns_rdata_toregion(rdata, &r1);
563
0
  r2 = r1;
564
565
  /*
566
   * Type covered (2) + Algorithm (1) +
567
   * Labels (1) + Original TTL (4) +
568
   * Expire time (4) +  Time signed (4) +
569
   * Key ID (2).
570
   */
571
0
  isc_region_consume(&r2, 18);
572
0
  r1.length = 18;
573
0
  RETERR((digest)(arg, &r1));
574
575
  /* Signer */
576
0
  dns_name_init(&name);
577
0
  dns_name_fromregion(&name, &r2);
578
0
  RETERR(dns_name_digest(&name, digest, arg));
579
0
  isc_region_consume(&r2, name_length(&name));
580
581
  /* Signature */
582
0
  return (digest)(arg, &r2);
583
0
}
584
585
static dns_rdatatype_t
586
5.83k
covers_sig(dns_rdata_t *rdata) {
587
5.83k
  dns_rdatatype_t type;
588
5.83k
  isc_region_t r;
589
590
5.83k
  REQUIRE(rdata->type == dns_rdatatype_sig);
591
592
5.83k
  dns_rdata_toregion(rdata, &r);
593
5.83k
  type = uint16_fromregion(&r);
594
595
5.83k
  return type;
596
5.83k
}
597
598
static bool
599
0
checkowner_sig(ARGS_CHECKOWNER) {
600
0
  REQUIRE(type == dns_rdatatype_sig);
601
602
0
  UNUSED(name);
603
0
  UNUSED(type);
604
0
  UNUSED(rdclass);
605
0
  UNUSED(wildcard);
606
607
0
  return true;
608
0
}
609
610
static bool
611
0
checknames_sig(ARGS_CHECKNAMES) {
612
0
  REQUIRE(rdata->type == dns_rdatatype_sig);
613
614
0
  UNUSED(rdata);
615
0
  UNUSED(owner);
616
0
  UNUSED(bad);
617
618
0
  return true;
619
0
}
620
621
static int
622
0
casecompare_sig(ARGS_COMPARE) {
623
0
  return compare_sig(rdata1, rdata2);
624
0
}
625
#endif /* RDATA_GENERIC_SIG_24_C */