Coverage Report

Created: 2025-12-12 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/rdata/generic/keydata_65533.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
#ifndef GENERIC_KEYDATA_65533_C
15
#define GENERIC_KEYDATA_65533_C 1
16
17
#include <isc/stdtime.h>
18
#include <isc/time.h>
19
20
#include <dst/dst.h>
21
22
12.5k
#define RRTYPE_KEYDATA_ATTRIBUTES (0)
23
24
static isc_result_t
25
94
fromtext_keydata(ARGS_FROMTEXT) {
26
94
  isc_token_t token;
27
94
  dns_secalg_t alg;
28
94
  dns_secproto_t proto;
29
94
  dns_keyflags_t flags;
30
94
  uint32_t refresh, addhd, removehd;
31
32
94
  REQUIRE(type == dns_rdatatype_keydata);
33
34
94
  UNUSED(type);
35
94
  UNUSED(rdclass);
36
94
  UNUSED(origin);
37
94
  UNUSED(options);
38
94
  UNUSED(callbacks);
39
40
  /* refresh timer */
41
94
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
42
94
              false));
43
91
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh));
44
64
  RETERR(uint32_tobuffer(refresh, target));
45
46
  /* add hold-down */
47
64
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
48
64
              false));
49
29
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd));
50
28
  RETERR(uint32_tobuffer(addhd, target));
51
52
  /* remove hold-down */
53
28
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
54
28
              false));
55
21
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd));
56
20
  RETERR(uint32_tobuffer(removehd, target));
57
58
  /* flags */
59
20
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
60
20
              false));
61
14
  RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
62
13
  RETERR(uint16_tobuffer(flags, target));
63
64
  /* protocol */
65
13
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
66
13
              false));
67
12
  RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
68
11
  RETERR(mem_tobuffer(target, &proto, 1));
69
70
  /* algorithm */
71
11
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
72
11
              false));
73
10
  RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
74
9
  RETERR(mem_tobuffer(target, &alg, 1));
75
76
  /* Do we have a placeholder KEYDATA record? */
77
9
  if (flags == 0 && proto == 0 && alg == 0) {
78
1
    return ISC_R_SUCCESS;
79
1
  }
80
81
  /* No Key? */
82
8
  if ((flags & 0xc000) == 0xc000) {
83
1
    return ISC_R_SUCCESS;
84
1
  }
85
86
7
  return isc_base64_tobuffer(lexer, target, -2);
87
8
}
88
89
static isc_result_t
90
2.08k
totext_keydata(ARGS_TOTEXT) {
91
2.08k
  isc_region_t sr;
92
2.08k
  char buf[sizeof("64000")];
93
2.08k
  unsigned int flags;
94
2.08k
  unsigned char proto, algorithm;
95
2.08k
  unsigned long refresh, add, deltime;
96
2.08k
  char algbuf[DNS_NAME_FORMATSIZE];
97
2.08k
  const char *keyinfo;
98
99
2.08k
  REQUIRE(rdata->type == dns_rdatatype_keydata);
100
101
2.08k
  if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16) {
102
2.08k
    return unknown_totext(rdata, tctx, target);
103
2.08k
  }
104
105
0
  dns_rdata_toregion(rdata, &sr);
106
107
  /* refresh timer */
108
0
  refresh = uint32_fromregion(&sr);
109
0
  isc_region_consume(&sr, 4);
110
0
  RETERR(dns_time32_totext(refresh, target));
111
0
  RETERR(str_totext(" ", target));
112
113
  /* add hold-down */
114
0
  add = uint32_fromregion(&sr);
115
0
  isc_region_consume(&sr, 4);
116
0
  RETERR(dns_time32_totext(add, target));
117
0
  RETERR(str_totext(" ", target));
118
119
  /* remove hold-down */
120
0
  deltime = uint32_fromregion(&sr);
121
0
  isc_region_consume(&sr, 4);
122
0
  RETERR(dns_time32_totext(deltime, target));
123
0
  RETERR(str_totext(" ", target));
124
125
  /* flags */
126
0
  flags = uint16_fromregion(&sr);
127
0
  isc_region_consume(&sr, 2);
128
0
  snprintf(buf, sizeof(buf), "%u", flags);
129
0
  RETERR(str_totext(buf, target));
130
0
  RETERR(str_totext(" ", target));
131
0
  if ((flags & DNS_KEYFLAG_KSK) != 0) {
132
0
    if ((flags & DNS_KEYFLAG_REVOKE) != 0) {
133
0
      keyinfo = "revoked KSK";
134
0
    } else {
135
0
      keyinfo = "KSK";
136
0
    }
137
0
  } else {
138
0
    keyinfo = "ZSK";
139
0
  }
140
141
  /* protocol */
142
0
  proto = sr.base[0];
143
0
  snprintf(buf, sizeof(buf), "%u", proto);
144
0
  isc_region_consume(&sr, 1);
145
0
  RETERR(str_totext(buf, target));
146
0
  RETERR(str_totext(" ", target));
147
148
  /* algorithm */
149
0
  algorithm = sr.base[0];
150
0
  snprintf(buf, sizeof(buf), "%u", algorithm);
151
0
  isc_region_consume(&sr, 1);
152
0
  RETERR(str_totext(buf, target));
153
154
  /* Do we have a placeholder KEYDATA record? */
155
0
  if (flags == 0 && proto == 0 && algorithm == 0) {
156
0
    if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
157
0
      RETERR(str_totext(" ; placeholder", target));
158
0
    }
159
0
    return ISC_R_SUCCESS;
160
0
  }
161
162
  /* No Key? */
163
0
  if ((flags & 0xc000) == 0xc000) {
164
0
    return ISC_R_SUCCESS;
165
0
  }
166
167
  /* key */
168
0
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
169
0
    RETERR(str_totext(" (", target));
170
0
  }
171
0
  RETERR(str_totext(tctx->linebreak, target));
172
0
  if (tctx->width == 0) { /* No splitting */
173
0
    RETERR(isc_base64_totext(&sr, 60, "", target));
174
0
  } else {
175
0
    RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak,
176
0
           target));
177
0
  }
178
179
0
  if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
180
0
    RETERR(str_totext(tctx->linebreak, target));
181
0
  } else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
182
0
    RETERR(str_totext(" ", target));
183
0
  }
184
185
0
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
186
0
    RETERR(str_totext(")", target));
187
0
  }
188
189
0
  if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
190
0
    isc_region_t tmpr;
191
0
    char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
192
0
    char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
193
0
    char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
194
0
    isc_time_t t;
195
196
0
    RETERR(str_totext(" ; ", target));
197
0
    RETERR(str_totext(keyinfo, target));
198
0
    dns_secalg_format((dns_secalg_t)algorithm, algbuf,
199
0
          sizeof(algbuf));
200
0
    RETERR(str_totext("; alg = ", target));
201
0
    RETERR(str_totext(algbuf, target));
202
0
    RETERR(str_totext("; key id = ", target));
203
0
    dns_rdata_toregion(rdata, &tmpr);
204
    /* Skip over refresh, addhd, and removehd */
205
0
    isc_region_consume(&tmpr, 12);
206
0
    snprintf(buf, sizeof(buf), "%u", dst_region_computeid(&tmpr));
207
0
    RETERR(str_totext(buf, target));
208
209
0
    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
210
0
      isc_stdtime_t now = isc_stdtime_now();
211
212
0
      RETERR(str_totext(tctx->linebreak, target));
213
0
      RETERR(str_totext("; next refresh: ", target));
214
0
      isc_time_set(&t, refresh, 0);
215
0
      isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf));
216
0
      RETERR(str_totext(rbuf, target));
217
218
0
      if (add == 0U) {
219
0
        RETERR(str_totext(tctx->linebreak, target));
220
0
        RETERR(str_totext("; no trust", target));
221
0
      } else {
222
0
        RETERR(str_totext(tctx->linebreak, target));
223
0
        if (add < now) {
224
0
          RETERR(str_totext("; trusted since: ",
225
0
                target));
226
0
        } else {
227
0
          RETERR(str_totext("; trust pending: ",
228
0
                target));
229
0
        }
230
0
        isc_time_set(&t, add, 0);
231
0
        isc_time_formathttptimestamp(&t, abuf,
232
0
                   sizeof(abuf));
233
0
        RETERR(str_totext(abuf, target));
234
0
      }
235
236
0
      if (deltime != 0U) {
237
0
        RETERR(str_totext(tctx->linebreak, target));
238
0
        RETERR(str_totext("; removal pending: ",
239
0
              target));
240
0
        isc_time_set(&t, deltime, 0);
241
0
        isc_time_formathttptimestamp(&t, dbuf,
242
0
                   sizeof(dbuf));
243
0
        RETERR(str_totext(dbuf, target));
244
0
      }
245
0
    }
246
0
  }
247
0
  return ISC_R_SUCCESS;
248
0
}
249
250
static isc_result_t
251
3.03k
fromwire_keydata(ARGS_FROMWIRE) {
252
3.03k
  isc_region_t sr;
253
254
3.03k
  REQUIRE(type == dns_rdatatype_keydata);
255
256
3.03k
  UNUSED(type);
257
3.03k
  UNUSED(rdclass);
258
3.03k
  UNUSED(dctx);
259
260
3.03k
  isc_buffer_activeregion(source, &sr);
261
3.03k
  isc_buffer_forward(source, sr.length);
262
3.03k
  return mem_tobuffer(target, sr.base, sr.length);
263
3.03k
}
264
265
static isc_result_t
266
1.05k
towire_keydata(ARGS_TOWIRE) {
267
1.05k
  isc_region_t sr;
268
269
1.05k
  REQUIRE(rdata->type == dns_rdatatype_keydata);
270
271
1.05k
  UNUSED(cctx);
272
273
1.05k
  dns_rdata_toregion(rdata, &sr);
274
1.05k
  return mem_tobuffer(target, sr.base, sr.length);
275
1.05k
}
276
277
static int
278
752
compare_keydata(ARGS_COMPARE) {
279
752
  isc_region_t r1;
280
752
  isc_region_t r2;
281
282
752
  REQUIRE(rdata1->type == rdata2->type);
283
752
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
284
752
  REQUIRE(rdata1->type == dns_rdatatype_keydata);
285
286
752
  dns_rdata_toregion(rdata1, &r1);
287
752
  dns_rdata_toregion(rdata2, &r2);
288
752
  return isc_region_compare(&r1, &r2);
289
752
}
290
291
static isc_result_t
292
0
fromstruct_keydata(ARGS_FROMSTRUCT) {
293
0
  dns_rdata_keydata_t *keydata = source;
294
295
0
  REQUIRE(type == dns_rdatatype_keydata);
296
0
  REQUIRE(keydata != NULL);
297
0
  REQUIRE(keydata->common.rdtype == type);
298
0
  REQUIRE(keydata->common.rdclass == rdclass);
299
300
0
  UNUSED(type);
301
0
  UNUSED(rdclass);
302
303
  /* Refresh timer */
304
0
  RETERR(uint32_tobuffer(keydata->refresh, target));
305
306
  /* Add hold-down */
307
0
  RETERR(uint32_tobuffer(keydata->addhd, target));
308
309
  /* Remove hold-down */
310
0
  RETERR(uint32_tobuffer(keydata->removehd, target));
311
312
  /* Flags */
313
0
  RETERR(uint16_tobuffer(keydata->flags, target));
314
315
  /* Protocol */
316
0
  RETERR(uint8_tobuffer(keydata->protocol, target));
317
318
  /* Algorithm */
319
0
  RETERR(uint8_tobuffer(keydata->algorithm, target));
320
321
  /* Data */
322
0
  return mem_tobuffer(target, keydata->data, keydata->datalen);
323
0
}
324
325
static isc_result_t
326
0
tostruct_keydata(ARGS_TOSTRUCT) {
327
0
  dns_rdata_keydata_t *keydata = target;
328
0
  isc_region_t sr;
329
330
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
331
0
  REQUIRE(keydata != NULL);
332
333
0
  DNS_RDATACOMMON_INIT(keydata, rdata->type, rdata->rdclass);
334
335
0
  dns_rdata_toregion(rdata, &sr);
336
337
  /* Refresh timer */
338
0
  if (sr.length < 4) {
339
    /* Not KEYDATA */
340
0
    return ISC_R_NOTIMPLEMENTED;
341
0
  }
342
0
  keydata->refresh = uint32_fromregion(&sr);
343
0
  isc_region_consume(&sr, 4);
344
345
  /* Add hold-down */
346
0
  if (sr.length < 4) {
347
    /* Not KEYDATA */
348
0
    return ISC_R_NOTIMPLEMENTED;
349
0
  }
350
0
  keydata->addhd = uint32_fromregion(&sr);
351
0
  isc_region_consume(&sr, 4);
352
353
  /* Remove hold-down */
354
0
  if (sr.length < 4) {
355
    /* Not KEYDATA */
356
0
    return ISC_R_NOTIMPLEMENTED;
357
0
  }
358
0
  keydata->removehd = uint32_fromregion(&sr);
359
0
  isc_region_consume(&sr, 4);
360
361
  /* Flags */
362
0
  if (sr.length < 2) {
363
    /* Not KEYDATA */
364
0
    return ISC_R_NOTIMPLEMENTED;
365
0
  }
366
0
  keydata->flags = uint16_fromregion(&sr);
367
0
  isc_region_consume(&sr, 2);
368
369
  /* Protocol */
370
0
  if (sr.length < 1) {
371
    /* Not KEYDATA */
372
0
    return ISC_R_NOTIMPLEMENTED;
373
0
  }
374
0
  keydata->protocol = uint8_fromregion(&sr);
375
0
  isc_region_consume(&sr, 1);
376
377
  /* Algorithm */
378
0
  if (sr.length < 1) {
379
    /* Not KEYDATA */
380
0
    return ISC_R_NOTIMPLEMENTED;
381
0
  }
382
0
  keydata->algorithm = uint8_fromregion(&sr);
383
0
  isc_region_consume(&sr, 1);
384
385
  /* Data */
386
0
  keydata->datalen = sr.length;
387
0
  keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen);
388
0
  keydata->mctx = mctx;
389
0
  return ISC_R_SUCCESS;
390
0
}
391
392
static void
393
0
freestruct_keydata(ARGS_FREESTRUCT) {
394
0
  dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *)source;
395
396
0
  REQUIRE(keydata != NULL);
397
0
  REQUIRE(keydata->common.rdtype == dns_rdatatype_keydata);
398
399
0
  if (keydata->mctx == NULL) {
400
0
    return;
401
0
  }
402
403
0
  if (keydata->data != NULL) {
404
0
    isc_mem_free(keydata->mctx, keydata->data);
405
0
  }
406
0
  keydata->mctx = NULL;
407
0
}
408
409
static isc_result_t
410
0
additionaldata_keydata(ARGS_ADDLDATA) {
411
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
412
413
0
  UNUSED(rdata);
414
0
  UNUSED(owner);
415
0
  UNUSED(add);
416
0
  UNUSED(arg);
417
418
0
  return ISC_R_SUCCESS;
419
0
}
420
421
static isc_result_t
422
0
digest_keydata(ARGS_DIGEST) {
423
0
  isc_region_t r;
424
425
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
426
427
0
  dns_rdata_toregion(rdata, &r);
428
429
0
  return (digest)(arg, &r);
430
0
}
431
432
static bool
433
0
checkowner_keydata(ARGS_CHECKOWNER) {
434
0
  REQUIRE(type == dns_rdatatype_keydata);
435
436
0
  UNUSED(name);
437
0
  UNUSED(type);
438
0
  UNUSED(rdclass);
439
0
  UNUSED(wildcard);
440
441
0
  return true;
442
0
}
443
444
static bool
445
0
checknames_keydata(ARGS_CHECKNAMES) {
446
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
447
448
0
  UNUSED(rdata);
449
0
  UNUSED(owner);
450
0
  UNUSED(bad);
451
452
0
  return true;
453
0
}
454
455
static int
456
0
casecompare_keydata(ARGS_COMPARE) {
457
0
  return compare_keydata(rdata1, rdata2);
458
0
}
459
460
#endif /* GENERIC_KEYDATA_65533_C */