Coverage Report

Created: 2026-08-31 07:21

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.9k
#define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META)
20
21
static isc_result_t
22
279
fromtext_tkey(ARGS_FROMTEXT) {
23
279
  isc_token_t token;
24
279
  dns_rcode_t rcode;
25
279
  isc_buffer_t buffer;
26
279
  long i;
27
279
  char *e;
28
29
279
  REQUIRE(type == dns_rdatatype_tkey);
30
31
279
  UNUSED(type);
32
279
  UNUSED(rdclass);
33
279
  UNUSED(callbacks);
34
35
  /*
36
   * Algorithm.
37
   */
38
279
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
39
279
              false));
40
276
  buffer_fromregion(&buffer, &token.value.as_region);
41
276
  if (origin == NULL) {
42
276
    origin = dns_rootname;
43
276
  }
44
276
  RETTOK(dns_name_wirefromtext(&buffer, origin, options, target));
45
46
  /*
47
   * Inception.
48
   */
49
275
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
50
275
              false));
51
274
  RETERR(uint32_tobuffer(token.value.as_ulong, target));
52
53
  /*
54
   * Expiration.
55
   */
56
274
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
57
274
              false));
58
273
  RETERR(uint32_tobuffer(token.value.as_ulong, target));
59
60
  /*
61
   * Mode.
62
   */
63
273
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
64
273
              false));
65
272
  if (token.value.as_ulong > 0xffffU) {
66
11
    RETTOK(ISC_R_RANGE);
67
11
  }
68
261
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
69
70
  /*
71
   * Error.
72
   */
73
261
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
74
261
              false));
75
243
  if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) !=
76
243
      ISC_R_SUCCESS)
77
206
  {
78
206
    i = strtol(DNS_AS_STR(token), &e, 10);
79
206
    if (*e != 0) {
80
50
      RETTOK(DNS_R_UNKNOWN);
81
50
    }
82
156
    if (i < 0 || i > 0xffff) {
83
141
      RETTOK(ISC_R_RANGE);
84
141
    }
85
15
    rcode = (dns_rcode_t)i;
86
15
  }
87
52
  RETERR(uint16_tobuffer(rcode, target));
88
89
  /*
90
   * Key Size.
91
   */
92
52
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
93
52
              false));
94
26
  if (token.value.as_ulong > 0xffffU) {
95
1
    RETTOK(ISC_R_RANGE);
96
1
  }
97
25
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
98
99
  /*
100
   * Key Data.
101
   */
102
25
  RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
103
104
  /*
105
   * Other Size.
106
   */
107
23
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
108
23
              false));
109
22
  if (token.value.as_ulong > 0xffffU) {
110
13
    RETTOK(ISC_R_RANGE);
111
13
  }
112
9
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
113
114
  /*
115
   * Other Data.
116
   */
117
9
  return isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong);
118
9
}
119
120
static isc_result_t
121
1.78k
totext_tkey(ARGS_TOTEXT) {
122
1.78k
  isc_region_t sr, dr;
123
1.78k
  char buf[sizeof("4294967295 ")];
124
1.78k
  unsigned long n;
125
1.78k
  dns_name_t name;
126
1.78k
  dns_name_t prefix;
127
1.78k
  unsigned int opts;
128
129
1.78k
  REQUIRE(rdata->type == dns_rdatatype_tkey);
130
1.78k
  REQUIRE(rdata->length != 0);
131
132
1.78k
  dns_rdata_toregion(rdata, &sr);
133
134
  /*
135
   * Algorithm.
136
   */
137
1.78k
  dns_name_init(&name);
138
1.78k
  dns_name_init(&prefix);
139
1.78k
  dns_name_fromregion(&name, &sr);
140
1.78k
  opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT
141
1.78k
               : 0;
142
1.78k
  RETERR(dns_name_totext(&prefix, opts, target));
143
1.78k
  RETERR(str_totext(" ", target));
144
1.78k
  isc_region_consume(&sr, name_length(&name));
145
146
  /*
147
   * Inception.
148
   */
149
1.78k
  n = uint32_fromregion(&sr);
150
1.78k
  isc_region_consume(&sr, 4);
151
1.78k
  snprintf(buf, sizeof(buf), "%lu ", n);
152
1.78k
  RETERR(str_totext(buf, target));
153
154
  /*
155
   * Expiration.
156
   */
157
1.78k
  n = uint32_fromregion(&sr);
158
1.78k
  isc_region_consume(&sr, 4);
159
1.78k
  snprintf(buf, sizeof(buf), "%lu ", n);
160
1.78k
  RETERR(str_totext(buf, target));
161
162
  /*
163
   * Mode.
164
   */
165
1.78k
  n = uint16_fromregion(&sr);
166
1.78k
  isc_region_consume(&sr, 2);
167
1.78k
  snprintf(buf, sizeof(buf), "%lu ", n);
168
1.78k
  RETERR(str_totext(buf, target));
169
170
  /*
171
   * Error.
172
   */
173
1.78k
  n = uint16_fromregion(&sr);
174
1.78k
  isc_region_consume(&sr, 2);
175
1.78k
  if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) {
176
1.78k
    RETERR(str_totext(" ", target));
177
1.78k
  } 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
1.78k
  n = uint16_fromregion(&sr);
186
1.78k
  isc_region_consume(&sr, 2);
187
1.78k
  snprintf(buf, sizeof(buf), "%lu", n);
188
1.78k
  RETERR(str_totext(buf, target));
189
190
  /*
191
   * Key Data.
192
   */
193
1.78k
  REQUIRE(n <= sr.length);
194
1.78k
  dr = sr;
195
1.78k
  dr.length = n;
196
1.78k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
197
0
    RETERR(str_totext(" (", target));
198
0
  }
199
1.78k
  RETERR(str_totext(tctx->linebreak, target));
200
1.78k
  if (tctx->width == 0) { /* No splitting */
201
0
    RETERR(isc_base64_totext(&dr, 60, "", target));
202
1.78k
  } else {
203
1.78k
    RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak,
204
1.78k
           target));
205
1.78k
  }
206
1.78k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
207
0
    RETERR(str_totext(" ) ", target));
208
1.78k
  } else {
209
1.78k
    RETERR(str_totext(" ", target));
210
1.78k
  }
211
1.78k
  isc_region_consume(&sr, n);
212
213
  /*
214
   * Other Size.
215
   */
216
1.78k
  n = uint16_fromregion(&sr);
217
1.78k
  isc_region_consume(&sr, 2);
218
1.78k
  snprintf(buf, sizeof(buf), "%lu", n);
219
1.78k
  RETERR(str_totext(buf, target));
220
221
  /*
222
   * Other Data.
223
   */
224
1.78k
  REQUIRE(n <= sr.length);
225
1.78k
  if (n != 0U) {
226
1.25k
    dr = sr;
227
1.25k
    dr.length = n;
228
1.25k
    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
229
0
      RETERR(str_totext(" (", target));
230
0
    }
231
1.25k
    RETERR(str_totext(tctx->linebreak, target));
232
1.25k
    if (tctx->width == 0) { /* No splitting */
233
0
      RETERR(isc_base64_totext(&dr, 60, "", target));
234
1.25k
    } else {
235
1.25k
      RETERR(isc_base64_totext(&dr, tctx->width - 2,
236
1.25k
             tctx->linebreak, target));
237
1.25k
    }
238
1.25k
    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
239
0
      RETERR(str_totext(" )", target));
240
0
    }
241
1.25k
  }
242
1.78k
  return ISC_R_SUCCESS;
243
1.78k
}
244
245
static isc_result_t
246
3.21k
fromwire_tkey(ARGS_FROMWIRE) {
247
3.21k
  isc_region_t sr;
248
3.21k
  unsigned long n;
249
3.21k
  dns_name_t name;
250
251
3.21k
  REQUIRE(type == dns_rdatatype_tkey);
252
253
3.21k
  UNUSED(type);
254
3.21k
  UNUSED(rdclass);
255
256
3.21k
  dctx = dns_decompress_setpermitted(dctx, false);
257
258
  /*
259
   * Algorithm.
260
   */
261
3.21k
  dns_name_init(&name);
262
3.21k
  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.02k
  isc_buffer_activeregion(source, &sr);
271
3.02k
  if (sr.length < 12) {
272
4
    return ISC_R_UNEXPECTEDEND;
273
4
  }
274
3.01k
  RETERR(mem_tobuffer(target, sr.base, 12));
275
2.80k
  isc_region_consume(&sr, 12);
276
2.80k
  isc_buffer_forward(source, 12);
277
278
  /*
279
   * Key Length + Key Data.
280
   */
281
2.80k
  if (sr.length < 2) {
282
4
    return ISC_R_UNEXPECTEDEND;
283
4
  }
284
2.80k
  n = uint16_fromregion(&sr);
285
2.80k
  if (sr.length < n + 2) {
286
25
    return ISC_R_UNEXPECTEDEND;
287
25
  }
288
2.78k
  RETERR(mem_tobuffer(target, sr.base, n + 2));
289
2.58k
  isc_region_consume(&sr, n + 2);
290
2.58k
  isc_buffer_forward(source, n + 2);
291
292
  /*
293
   * Other Length + Other Data.
294
   */
295
2.58k
  if (sr.length < 2) {
296
8
    return ISC_R_UNEXPECTEDEND;
297
8
  }
298
2.57k
  n = uint16_fromregion(&sr);
299
2.57k
  if (sr.length < n + 2) {
300
14
    return ISC_R_UNEXPECTEDEND;
301
14
  }
302
2.55k
  isc_buffer_forward(source, n + 2);
303
2.55k
  return mem_tobuffer(target, sr.base, n + 2);
304
2.57k
}
305
306
static isc_result_t
307
897
towire_tkey(ARGS_TOWIRE) {
308
897
  isc_region_t sr;
309
897
  dns_name_t name;
310
311
897
  REQUIRE(rdata->type == dns_rdatatype_tkey);
312
897
  REQUIRE(rdata->length != 0);
313
314
897
  dns_compress_setpermitted(cctx, false);
315
  /*
316
   * Algorithm.
317
   */
318
897
  dns_rdata_toregion(rdata, &sr);
319
897
  dns_name_init(&name);
320
897
  dns_name_fromregion(&name, &sr);
321
897
  RETERR(dns_name_towire(&name, cctx, target));
322
896
  isc_region_consume(&sr, name_length(&name));
323
324
896
  return mem_tobuffer(target, sr.base, sr.length);
325
897
}
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 */