Coverage Report

Created: 2025-07-18 07:03

/src/bind9/lib/dns/rdata/generic/keydata_65533.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
#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
9.47k
#define RRTYPE_KEYDATA_ATTRIBUTES (0)
23
24
static isc_result_t
25
121
fromtext_keydata(ARGS_FROMTEXT) {
26
121
  isc_token_t token;
27
121
  dns_secalg_t alg;
28
121
  dns_secproto_t proto;
29
121
  dns_keyflags_t flags;
30
121
  uint32_t refresh, addhd, removehd;
31
32
121
  REQUIRE(type == dns_rdatatype_keydata);
33
34
121
  UNUSED(type);
35
121
  UNUSED(rdclass);
36
121
  UNUSED(origin);
37
121
  UNUSED(options);
38
121
  UNUSED(callbacks);
39
40
  /* refresh timer */
41
121
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
42
121
              false));
43
119
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh));
44
93
  RETERR(uint32_tobuffer(refresh, target));
45
46
  /* add hold-down */
47
93
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
48
93
              false));
49
45
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd));
50
44
  RETERR(uint32_tobuffer(addhd, target));
51
52
  /* remove hold-down */
53
44
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
54
44
              false));
55
36
  RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd));
56
35
  RETERR(uint32_tobuffer(removehd, target));
57
58
  /* flags */
59
35
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
60
35
              false));
61
26
  RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
62
25
  RETERR(uint16_tobuffer(flags, target));
63
64
  /* protocol */
65
25
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
66
25
              false));
67
24
  RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
68
23
  RETERR(mem_tobuffer(target, &proto, 1));
69
70
  /* algorithm */
71
23
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
72
23
              false));
73
22
  RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
74
21
  RETERR(mem_tobuffer(target, &alg, 1));
75
76
  /* Do we have a placeholder KEYDATA record? */
77
21
  if (flags == 0 && proto == 0 && alg == 0) {
78
1
    return ISC_R_SUCCESS;
79
1
  }
80
81
  /* No Key? */
82
20
  if ((flags & 0xc000) == 0xc000) {
83
2
    return ISC_R_SUCCESS;
84
2
  }
85
86
18
  return isc_base64_tobuffer(lexer, target, -2);
87
20
}
88
89
static isc_result_t
90
1.87k
totext_keydata(ARGS_TOTEXT) {
91
1.87k
  isc_region_t sr;
92
1.87k
  char buf[sizeof("64000")];
93
1.87k
  unsigned int flags;
94
1.87k
  unsigned char proto, algorithm;
95
1.87k
  unsigned long refresh, add, deltime;
96
1.87k
  char algbuf[DNS_NAME_FORMATSIZE];
97
1.87k
  const char *keyinfo;
98
99
1.87k
  REQUIRE(rdata->type == dns_rdatatype_keydata);
100
101
1.87k
  if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16) {
102
1.87k
    return unknown_totext(rdata, tctx, target);
103
1.87k
  }
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
1.90k
fromwire_keydata(ARGS_FROMWIRE) {
252
1.90k
  isc_region_t sr;
253
254
1.90k
  REQUIRE(type == dns_rdatatype_keydata);
255
256
1.90k
  UNUSED(type);
257
1.90k
  UNUSED(rdclass);
258
1.90k
  UNUSED(dctx);
259
260
1.90k
  isc_buffer_activeregion(source, &sr);
261
1.90k
  isc_buffer_forward(source, sr.length);
262
1.90k
  return mem_tobuffer(target, sr.base, sr.length);
263
1.90k
}
264
265
static isc_result_t
266
939
towire_keydata(ARGS_TOWIRE) {
267
939
  isc_region_t sr;
268
269
939
  REQUIRE(rdata->type == dns_rdatatype_keydata);
270
271
939
  UNUSED(cctx);
272
273
939
  dns_rdata_toregion(rdata, &sr);
274
939
  return mem_tobuffer(target, sr.base, sr.length);
275
939
}
276
277
static int
278
0
compare_keydata(ARGS_COMPARE) {
279
0
  isc_region_t r1;
280
0
  isc_region_t r2;
281
282
0
  REQUIRE(rdata1->type == rdata2->type);
283
0
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
284
0
  REQUIRE(rdata1->type == dns_rdatatype_keydata);
285
286
0
  dns_rdata_toregion(rdata1, &r1);
287
0
  dns_rdata_toregion(rdata2, &r2);
288
0
  return isc_region_compare(&r1, &r2);
289
0
}
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
  keydata->common.rdclass = rdata->rdclass;
334
0
  keydata->common.rdtype = rdata->type;
335
336
0
  dns_rdata_toregion(rdata, &sr);
337
338
  /* Refresh timer */
339
0
  if (sr.length < 4) {
340
    /* Not KEYDATA */
341
0
    return ISC_R_NOTIMPLEMENTED;
342
0
  }
343
0
  keydata->refresh = uint32_fromregion(&sr);
344
0
  isc_region_consume(&sr, 4);
345
346
  /* Add hold-down */
347
0
  if (sr.length < 4) {
348
    /* Not KEYDATA */
349
0
    return ISC_R_NOTIMPLEMENTED;
350
0
  }
351
0
  keydata->addhd = uint32_fromregion(&sr);
352
0
  isc_region_consume(&sr, 4);
353
354
  /* Remove hold-down */
355
0
  if (sr.length < 4) {
356
    /* Not KEYDATA */
357
0
    return ISC_R_NOTIMPLEMENTED;
358
0
  }
359
0
  keydata->removehd = uint32_fromregion(&sr);
360
0
  isc_region_consume(&sr, 4);
361
362
  /* Flags */
363
0
  if (sr.length < 2) {
364
    /* Not KEYDATA */
365
0
    return ISC_R_NOTIMPLEMENTED;
366
0
  }
367
0
  keydata->flags = uint16_fromregion(&sr);
368
0
  isc_region_consume(&sr, 2);
369
370
  /* Protocol */
371
0
  if (sr.length < 1) {
372
    /* Not KEYDATA */
373
0
    return ISC_R_NOTIMPLEMENTED;
374
0
  }
375
0
  keydata->protocol = uint8_fromregion(&sr);
376
0
  isc_region_consume(&sr, 1);
377
378
  /* Algorithm */
379
0
  if (sr.length < 1) {
380
    /* Not KEYDATA */
381
0
    return ISC_R_NOTIMPLEMENTED;
382
0
  }
383
0
  keydata->algorithm = uint8_fromregion(&sr);
384
0
  isc_region_consume(&sr, 1);
385
386
  /* Data */
387
0
  keydata->datalen = sr.length;
388
0
  keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen);
389
0
  keydata->mctx = mctx;
390
0
  return ISC_R_SUCCESS;
391
0
}
392
393
static void
394
0
freestruct_keydata(ARGS_FREESTRUCT) {
395
0
  dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *)source;
396
397
0
  REQUIRE(keydata != NULL);
398
0
  REQUIRE(keydata->common.rdtype == dns_rdatatype_keydata);
399
400
0
  if (keydata->mctx == NULL) {
401
0
    return;
402
0
  }
403
404
0
  if (keydata->data != NULL) {
405
0
    isc_mem_free(keydata->mctx, keydata->data);
406
0
  }
407
0
  keydata->mctx = NULL;
408
0
}
409
410
static isc_result_t
411
0
additionaldata_keydata(ARGS_ADDLDATA) {
412
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
413
414
0
  UNUSED(rdata);
415
0
  UNUSED(owner);
416
0
  UNUSED(add);
417
0
  UNUSED(arg);
418
419
0
  return ISC_R_SUCCESS;
420
0
}
421
422
static isc_result_t
423
0
digest_keydata(ARGS_DIGEST) {
424
0
  isc_region_t r;
425
426
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
427
428
0
  dns_rdata_toregion(rdata, &r);
429
430
0
  return (digest)(arg, &r);
431
0
}
432
433
static bool
434
0
checkowner_keydata(ARGS_CHECKOWNER) {
435
0
  REQUIRE(type == dns_rdatatype_keydata);
436
437
0
  UNUSED(name);
438
0
  UNUSED(type);
439
0
  UNUSED(rdclass);
440
0
  UNUSED(wildcard);
441
442
0
  return true;
443
0
}
444
445
static bool
446
0
checknames_keydata(ARGS_CHECKNAMES) {
447
0
  REQUIRE(rdata->type == dns_rdatatype_keydata);
448
449
0
  UNUSED(rdata);
450
0
  UNUSED(owner);
451
0
  UNUSED(bad);
452
453
0
  return true;
454
0
}
455
456
static int
457
0
casecompare_keydata(ARGS_COMPARE) {
458
0
  return compare_keydata(rdata1, rdata2);
459
0
}
460
461
#endif /* GENERIC_KEYDATA_65533_C */