Coverage Report

Created: 2026-01-10 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/rdata/generic/tkey_249.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
/* draft-ietf-dnsext-tkey-01.txt */
15
16
#ifndef RDATA_GENERIC_TKEY_249_C
17
#define RDATA_GENERIC_TKEY_249_C
18
19
11.3k
#define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META)
20
21
static isc_result_t
22
312
fromtext_tkey(ARGS_FROMTEXT) {
23
312
  isc_token_t token;
24
312
  dns_rcode_t rcode;
25
312
  isc_buffer_t buffer;
26
312
  long i;
27
312
  char *e;
28
29
312
  REQUIRE(type == dns_rdatatype_tkey);
30
31
312
  UNUSED(type);
32
312
  UNUSED(rdclass);
33
312
  UNUSED(callbacks);
34
35
  /*
36
   * Algorithm.
37
   */
38
312
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
39
312
              false));
40
310
  buffer_fromregion(&buffer, &token.value.as_region);
41
310
  if (origin == NULL) {
42
310
    origin = dns_rootname;
43
310
  }
44
310
  RETTOK(dns_name_wirefromtext(&buffer, origin, options, target));
45
46
  /*
47
   * Inception.
48
   */
49
309
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
50
309
              false));
51
307
  RETERR(uint32_tobuffer(token.value.as_ulong, target));
52
53
  /*
54
   * Expiration.
55
   */
56
307
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
57
307
              false));
58
306
  RETERR(uint32_tobuffer(token.value.as_ulong, target));
59
60
  /*
61
   * Mode.
62
   */
63
306
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
64
306
              false));
65
305
  if (token.value.as_ulong > 0xffffU) {
66
16
    RETTOK(ISC_R_RANGE);
67
16
  }
68
289
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
69
70
  /*
71
   * Error.
72
   */
73
289
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
74
289
              false));
75
272
  if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) !=
76
272
      ISC_R_SUCCESS)
77
198
  {
78
198
    i = strtol(DNS_AS_STR(token), &e, 10);
79
198
    if (*e != 0) {
80
59
      RETTOK(DNS_R_UNKNOWN);
81
59
    }
82
139
    if (i < 0 || i > 0xffff) {
83
113
      RETTOK(ISC_R_RANGE);
84
113
    }
85
26
    rcode = (dns_rcode_t)i;
86
26
  }
87
100
  RETERR(uint16_tobuffer(rcode, target));
88
89
  /*
90
   * Key Size.
91
   */
92
100
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
93
100
              false));
94
66
  if (token.value.as_ulong > 0xffffU) {
95
17
    RETTOK(ISC_R_RANGE);
96
17
  }
97
49
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
98
99
  /*
100
   * Key Data.
101
   */
102
49
  RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
103
104
  /*
105
   * Other Size.
106
   */
107
38
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
108
38
              false));
109
37
  if (token.value.as_ulong > 0xffffU) {
110
17
    RETTOK(ISC_R_RANGE);
111
17
  }
112
20
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
113
114
  /*
115
   * Other Data.
116
   */
117
20
  return isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong);
118
20
}
119
120
static isc_result_t
121
2.29k
totext_tkey(ARGS_TOTEXT) {
122
2.29k
  isc_region_t sr, dr;
123
2.29k
  char buf[sizeof("4294967295 ")];
124
2.29k
  unsigned long n;
125
2.29k
  dns_name_t name;
126
2.29k
  dns_name_t prefix;
127
2.29k
  unsigned int opts;
128
129
2.29k
  REQUIRE(rdata->type == dns_rdatatype_tkey);
130
2.29k
  REQUIRE(rdata->length != 0);
131
132
2.29k
  dns_rdata_toregion(rdata, &sr);
133
134
  /*
135
   * Algorithm.
136
   */
137
2.29k
  dns_name_init(&name);
138
2.29k
  dns_name_init(&prefix);
139
2.29k
  dns_name_fromregion(&name, &sr);
140
2.29k
  opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT
141
2.29k
               : 0;
142
2.29k
  RETERR(dns_name_totext(&prefix, opts, target));
143
2.29k
  RETERR(str_totext(" ", target));
144
2.29k
  isc_region_consume(&sr, name_length(&name));
145
146
  /*
147
   * Inception.
148
   */
149
2.29k
  n = uint32_fromregion(&sr);
150
2.29k
  isc_region_consume(&sr, 4);
151
2.29k
  snprintf(buf, sizeof(buf), "%lu ", n);
152
2.29k
  RETERR(str_totext(buf, target));
153
154
  /*
155
   * Expiration.
156
   */
157
2.29k
  n = uint32_fromregion(&sr);
158
2.29k
  isc_region_consume(&sr, 4);
159
2.29k
  snprintf(buf, sizeof(buf), "%lu ", n);
160
2.29k
  RETERR(str_totext(buf, target));
161
162
  /*
163
   * Mode.
164
   */
165
2.29k
  n = uint16_fromregion(&sr);
166
2.29k
  isc_region_consume(&sr, 2);
167
2.29k
  snprintf(buf, sizeof(buf), "%lu ", n);
168
2.29k
  RETERR(str_totext(buf, target));
169
170
  /*
171
   * Error.
172
   */
173
2.29k
  n = uint16_fromregion(&sr);
174
2.29k
  isc_region_consume(&sr, 2);
175
2.29k
  if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) {
176
2.29k
    RETERR(str_totext(" ", target));
177
2.29k
  } else {
178
0
    snprintf(buf, sizeof(buf), "%lu ", n);
179
0
    RETERR(str_totext(buf, target));
180
0
  }
181
182
  /*
183
   * Key Size.
184
   */
185
2.29k
  n = uint16_fromregion(&sr);
186
2.29k
  isc_region_consume(&sr, 2);
187
2.29k
  snprintf(buf, sizeof(buf), "%lu", n);
188
2.29k
  RETERR(str_totext(buf, target));
189
190
  /*
191
   * Key Data.
192
   */
193
2.29k
  REQUIRE(n <= sr.length);
194
2.29k
  dr = sr;
195
2.29k
  dr.length = n;
196
2.29k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
197
0
    RETERR(str_totext(" (", target));
198
0
  }
199
2.29k
  RETERR(str_totext(tctx->linebreak, target));
200
2.29k
  if (tctx->width == 0) { /* No splitting */
201
0
    RETERR(isc_base64_totext(&dr, 60, "", target));
202
2.29k
  } else {
203
2.29k
    RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak,
204
2.29k
           target));
205
2.29k
  }
206
2.29k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
207
0
    RETERR(str_totext(" ) ", target));
208
2.29k
  } else {
209
2.29k
    RETERR(str_totext(" ", target));
210
2.29k
  }
211
2.29k
  isc_region_consume(&sr, n);
212
213
  /*
214
   * Other Size.
215
   */
216
2.29k
  n = uint16_fromregion(&sr);
217
2.29k
  isc_region_consume(&sr, 2);
218
2.29k
  snprintf(buf, sizeof(buf), "%lu", n);
219
2.29k
  RETERR(str_totext(buf, target));
220
221
  /*
222
   * Other Data.
223
   */
224
2.29k
  REQUIRE(n <= sr.length);
225
2.29k
  if (n != 0U) {
226
1.20k
    dr = sr;
227
1.20k
    dr.length = n;
228
1.20k
    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
229
0
      RETERR(str_totext(" (", target));
230
0
    }
231
1.20k
    RETERR(str_totext(tctx->linebreak, target));
232
1.20k
    if (tctx->width == 0) { /* No splitting */
233
0
      RETERR(isc_base64_totext(&dr, 60, "", target));
234
1.20k
    } else {
235
1.20k
      RETERR(isc_base64_totext(&dr, tctx->width - 2,
236
1.20k
             tctx->linebreak, target));
237
1.20k
    }
238
1.20k
    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
239
0
      RETERR(str_totext(" )", target));
240
0
    }
241
1.20k
  }
242
2.29k
  return ISC_R_SUCCESS;
243
2.29k
}
244
245
static isc_result_t
246
3.37k
fromwire_tkey(ARGS_FROMWIRE) {
247
3.37k
  isc_region_t sr;
248
3.37k
  unsigned long n;
249
3.37k
  dns_name_t name;
250
251
3.37k
  REQUIRE(type == dns_rdatatype_tkey);
252
253
3.37k
  UNUSED(type);
254
3.37k
  UNUSED(rdclass);
255
256
3.37k
  dctx = dns_decompress_setpermitted(dctx, false);
257
258
  /*
259
   * Algorithm.
260
   */
261
3.37k
  dns_name_init(&name);
262
3.37k
  RETERR(dns_name_fromwire(&name, source, dctx, target));
263
264
  /*
265
   * Inception: 4
266
   * Expiration: 4
267
   * Mode: 2
268
   * Error: 2
269
   */
270
3.17k
  isc_buffer_activeregion(source, &sr);
271
3.17k
  if (sr.length < 12) {
272
12
    return ISC_R_UNEXPECTEDEND;
273
12
  }
274
3.16k
  RETERR(mem_tobuffer(target, sr.base, 12));
275
2.95k
  isc_region_consume(&sr, 12);
276
2.95k
  isc_buffer_forward(source, 12);
277
278
  /*
279
   * Key Length + Key Data.
280
   */
281
2.95k
  if (sr.length < 2) {
282
10
    return ISC_R_UNEXPECTEDEND;
283
10
  }
284
2.94k
  n = uint16_fromregion(&sr);
285
2.94k
  if (sr.length < n + 2) {
286
21
    return ISC_R_UNEXPECTEDEND;
287
21
  }
288
2.92k
  RETERR(mem_tobuffer(target, sr.base, n + 2));
289
2.85k
  isc_region_consume(&sr, n + 2);
290
2.85k
  isc_buffer_forward(source, n + 2);
291
292
  /*
293
   * Other Length + Other Data.
294
   */
295
2.85k
  if (sr.length < 2) {
296
3
    return ISC_R_UNEXPECTEDEND;
297
3
  }
298
2.84k
  n = uint16_fromregion(&sr);
299
2.84k
  if (sr.length < n + 2) {
300
12
    return ISC_R_UNEXPECTEDEND;
301
12
  }
302
2.83k
  isc_buffer_forward(source, n + 2);
303
2.83k
  return mem_tobuffer(target, sr.base, n + 2);
304
2.84k
}
305
306
static isc_result_t
307
1.15k
towire_tkey(ARGS_TOWIRE) {
308
1.15k
  isc_region_t sr;
309
1.15k
  dns_name_t name;
310
311
1.15k
  REQUIRE(rdata->type == dns_rdatatype_tkey);
312
1.15k
  REQUIRE(rdata->length != 0);
313
314
1.15k
  dns_compress_setpermitted(cctx, false);
315
  /*
316
   * Algorithm.
317
   */
318
1.15k
  dns_rdata_toregion(rdata, &sr);
319
1.15k
  dns_name_init(&name);
320
1.15k
  dns_name_fromregion(&name, &sr);
321
1.15k
  RETERR(dns_name_towire(&name, cctx, target));
322
1.15k
  isc_region_consume(&sr, name_length(&name));
323
324
1.15k
  return mem_tobuffer(target, sr.base, sr.length);
325
1.15k
}
326
327
static int
328
0
compare_tkey(ARGS_COMPARE) {
329
0
  isc_region_t r1;
330
0
  isc_region_t r2;
331
0
  dns_name_t name1;
332
0
  dns_name_t name2;
333
0
  int order;
334
335
0
  REQUIRE(rdata1->type == rdata2->type);
336
0
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
337
0
  REQUIRE(rdata1->type == dns_rdatatype_tkey);
338
0
  REQUIRE(rdata1->length != 0);
339
0
  REQUIRE(rdata2->length != 0);
340
341
  /*
342
   * Algorithm.
343
   */
344
0
  dns_rdata_toregion(rdata1, &r1);
345
0
  dns_rdata_toregion(rdata2, &r2);
346
0
  dns_name_init(&name1);
347
0
  dns_name_init(&name2);
348
0
  dns_name_fromregion(&name1, &r1);
349
0
  dns_name_fromregion(&name2, &r2);
350
0
  if ((order = dns_name_rdatacompare(&name1, &name2)) != 0) {
351
0
    return order;
352
0
  }
353
0
  isc_region_consume(&r1, name_length(&name1));
354
0
  isc_region_consume(&r2, name_length(&name2));
355
0
  return isc_region_compare(&r1, &r2);
356
0
}
357
358
static isc_result_t
359
0
fromstruct_tkey(ARGS_FROMSTRUCT) {
360
0
  dns_rdata_tkey_t *tkey = source;
361
362
0
  REQUIRE(type == dns_rdatatype_tkey);
363
0
  REQUIRE(tkey != NULL);
364
0
  REQUIRE(tkey->common.rdtype == type);
365
0
  REQUIRE(tkey->common.rdclass == rdclass);
366
367
0
  UNUSED(type);
368
0
  UNUSED(rdclass);
369
370
  /*
371
   * Algorithm Name.
372
   */
373
0
  RETERR(name_tobuffer(&tkey->algorithm, target));
374
375
  /*
376
   * Inception: 32 bits.
377
   */
378
0
  RETERR(uint32_tobuffer(tkey->inception, target));
379
380
  /*
381
   * Expire: 32 bits.
382
   */
383
0
  RETERR(uint32_tobuffer(tkey->expire, target));
384
385
  /*
386
   * Mode: 16 bits.
387
   */
388
0
  RETERR(uint16_tobuffer(tkey->mode, target));
389
390
  /*
391
   * Error: 16 bits.
392
   */
393
0
  RETERR(uint16_tobuffer(tkey->error, target));
394
395
  /*
396
   * Key size: 16 bits.
397
   */
398
0
  RETERR(uint16_tobuffer(tkey->keylen, target));
399
400
  /*
401
   * Key.
402
   */
403
0
  RETERR(mem_tobuffer(target, tkey->key, tkey->keylen));
404
405
  /*
406
   * Other size: 16 bits.
407
   */
408
0
  RETERR(uint16_tobuffer(tkey->otherlen, target));
409
410
  /*
411
   * Other data.
412
   */
413
0
  return mem_tobuffer(target, tkey->other, tkey->otherlen);
414
0
}
415
416
static isc_result_t
417
0
tostruct_tkey(ARGS_TOSTRUCT) {
418
0
  dns_rdata_tkey_t *tkey = target;
419
0
  dns_name_t alg;
420
0
  isc_region_t sr;
421
422
0
  REQUIRE(rdata->type == dns_rdatatype_tkey);
423
0
  REQUIRE(tkey != NULL);
424
0
  REQUIRE(rdata->length != 0);
425
426
0
  DNS_RDATACOMMON_INIT(tkey, rdata->type, rdata->rdclass);
427
428
0
  dns_rdata_toregion(rdata, &sr);
429
430
  /*
431
   * Algorithm Name.
432
   */
433
0
  dns_name_init(&alg);
434
0
  dns_name_fromregion(&alg, &sr);
435
0
  dns_name_init(&tkey->algorithm);
436
0
  name_duporclone(&alg, mctx, &tkey->algorithm);
437
0
  isc_region_consume(&sr, name_length(&tkey->algorithm));
438
439
  /*
440
   * Inception.
441
   */
442
0
  tkey->inception = uint32_fromregion(&sr);
443
0
  isc_region_consume(&sr, 4);
444
445
  /*
446
   * Expire.
447
   */
448
0
  tkey->expire = uint32_fromregion(&sr);
449
0
  isc_region_consume(&sr, 4);
450
451
  /*
452
   * Mode.
453
   */
454
0
  tkey->mode = uint16_fromregion(&sr);
455
0
  isc_region_consume(&sr, 2);
456
457
  /*
458
   * Error.
459
   */
460
0
  tkey->error = uint16_fromregion(&sr);
461
0
  isc_region_consume(&sr, 2);
462
463
  /*
464
   * Key size.
465
   */
466
0
  tkey->keylen = uint16_fromregion(&sr);
467
0
  isc_region_consume(&sr, 2);
468
469
  /*
470
   * Key.
471
   */
472
0
  INSIST(tkey->keylen + 2U <= sr.length);
473
0
  tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen);
474
0
  isc_region_consume(&sr, tkey->keylen);
475
476
  /*
477
   * Other size.
478
   */
479
0
  tkey->otherlen = uint16_fromregion(&sr);
480
0
  isc_region_consume(&sr, 2);
481
482
  /*
483
   * Other.
484
   */
485
0
  INSIST(tkey->otherlen <= sr.length);
486
0
  tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen);
487
0
  tkey->mctx = mctx;
488
0
  return ISC_R_SUCCESS;
489
0
}
490
491
static void
492
0
freestruct_tkey(ARGS_FREESTRUCT) {
493
0
  dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *)source;
494
495
0
  REQUIRE(tkey != NULL);
496
497
0
  if (tkey->mctx == NULL) {
498
0
    return;
499
0
  }
500
501
0
  dns_name_free(&tkey->algorithm, tkey->mctx);
502
0
  if (tkey->key != NULL) {
503
0
    isc_mem_free(tkey->mctx, tkey->key);
504
0
  }
505
0
  if (tkey->other != NULL) {
506
0
    isc_mem_free(tkey->mctx, tkey->other);
507
0
  }
508
0
  tkey->mctx = NULL;
509
0
}
510
511
static isc_result_t
512
0
additionaldata_tkey(ARGS_ADDLDATA) {
513
0
  REQUIRE(rdata->type == dns_rdatatype_tkey);
514
515
0
  UNUSED(rdata);
516
0
  UNUSED(owner);
517
0
  UNUSED(add);
518
0
  UNUSED(arg);
519
520
0
  return ISC_R_SUCCESS;
521
0
}
522
523
static isc_result_t
524
0
digest_tkey(ARGS_DIGEST) {
525
0
  UNUSED(rdata);
526
0
  UNUSED(digest);
527
0
  UNUSED(arg);
528
529
0
  REQUIRE(rdata->type == dns_rdatatype_tkey);
530
531
0
  return ISC_R_NOTIMPLEMENTED;
532
0
}
533
534
static bool
535
0
checkowner_tkey(ARGS_CHECKOWNER) {
536
0
  REQUIRE(type == dns_rdatatype_tkey);
537
538
0
  UNUSED(name);
539
0
  UNUSED(type);
540
0
  UNUSED(rdclass);
541
0
  UNUSED(wildcard);
542
543
0
  return true;
544
0
}
545
546
static bool
547
0
checknames_tkey(ARGS_CHECKNAMES) {
548
0
  REQUIRE(rdata->type == dns_rdatatype_tkey);
549
550
0
  UNUSED(rdata);
551
0
  UNUSED(owner);
552
0
  UNUSED(bad);
553
554
0
  return true;
555
0
}
556
557
static int
558
0
casecompare_tkey(ARGS_COMPARE) {
559
0
  return compare_tkey(rdata1, rdata2);
560
0
}
561
#endif /* RDATA_GENERIC_TKEY_249_C */