Coverage Report

Created: 2023-06-07 06:23

/src/bind9/lib/dns/rdata/generic/zonemd_63.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
/* RFC 8976 */
15
16
#ifndef RDATA_GENERIC_ZONEMD_63_C
17
#define RDATA_GENERIC_ZONEMD_63_C
18
19
12.7k
#define RRTYPE_ZONEMD_ATTRIBUTES 0
20
21
static isc_result_t
22
562
fromtext_zonemd(ARGS_FROMTEXT) {
23
562
  isc_token_t token;
24
562
  int digest_type, length;
25
562
  isc_buffer_t save;
26
562
  isc_result_t result;
27
28
562
  UNUSED(type);
29
562
  UNUSED(rdclass);
30
562
  UNUSED(origin);
31
562
  UNUSED(options);
32
562
  UNUSED(callbacks);
33
34
  /*
35
   * Zone Serial.
36
   */
37
562
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
38
562
              false));
39
558
  RETERR(uint32_tobuffer(token.value.as_ulong, target));
40
41
  /*
42
   * Digest Scheme.
43
   */
44
558
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
45
558
              false));
46
555
  RETERR(uint8_tobuffer(token.value.as_ulong, target));
47
48
  /*
49
   * Digest Type.
50
   */
51
522
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
52
522
              false));
53
520
  digest_type = token.value.as_ulong;
54
520
  RETERR(uint8_tobuffer(digest_type, target));
55
56
  /*
57
   * Digest.
58
   */
59
516
  switch (digest_type) {
60
271
  case DNS_ZONEMD_DIGEST_SHA384:
61
271
    length = ISC_SHA384_DIGESTLENGTH;
62
271
    break;
63
182
  case DNS_ZONEMD_DIGEST_SHA512:
64
182
    length = ISC_SHA512_DIGESTLENGTH;
65
182
    break;
66
63
  default:
67
63
    length = -2;
68
63
    break;
69
516
  }
70
71
516
  save = *target;
72
516
  result = isc_hex_tobuffer(lexer, target, length);
73
  /* Minimum length of digest is 12 octets. */
74
516
  if (isc_buffer_usedlength(target) - isc_buffer_usedlength(&save) < 12) {
75
12
    return (ISC_R_UNEXPECTEDEND);
76
12
  }
77
504
  return (result);
78
516
}
79
80
static isc_result_t
81
1.26k
totext_zonemd(ARGS_TOTEXT) {
82
1.26k
  isc_region_t sr;
83
1.26k
  char buf[sizeof("0123456789")];
84
1.26k
  unsigned long num;
85
86
1.26k
  REQUIRE(rdata->length > 6);
87
88
1.26k
  UNUSED(tctx);
89
90
1.26k
  dns_rdata_toregion(rdata, &sr);
91
92
  /*
93
   * Zone Serial.
94
   */
95
1.26k
  num = uint32_fromregion(&sr);
96
1.26k
  isc_region_consume(&sr, 4);
97
1.26k
  snprintf(buf, sizeof(buf), "%lu", num);
98
1.26k
  RETERR(str_totext(buf, target));
99
100
1.26k
  RETERR(str_totext(" ", target));
101
102
  /*
103
   * Digest scheme.
104
   */
105
1.26k
  num = uint8_fromregion(&sr);
106
1.26k
  isc_region_consume(&sr, 1);
107
1.26k
  snprintf(buf, sizeof(buf), "%lu", num);
108
1.26k
  RETERR(str_totext(buf, target));
109
110
1.26k
  RETERR(str_totext(" ", target));
111
112
  /*
113
   * Digest type.
114
   */
115
1.26k
  num = uint8_fromregion(&sr);
116
1.26k
  isc_region_consume(&sr, 1);
117
1.26k
  snprintf(buf, sizeof(buf), "%lu", num);
118
1.26k
  RETERR(str_totext(buf, target));
119
120
  /*
121
   * Digest.
122
   */
123
1.26k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
124
19
    RETERR(str_totext(" (", target));
125
19
  }
126
1.26k
  RETERR(str_totext(tctx->linebreak, target));
127
1.26k
  if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) {
128
1.26k
    if (tctx->width == 0) { /* No splitting */
129
0
      RETERR(isc_hex_totext(&sr, 0, "", target));
130
1.26k
    } else {
131
1.26k
      RETERR(isc_hex_totext(&sr, tctx->width - 2,
132
1.26k
                tctx->linebreak, target));
133
1.26k
    }
134
1.26k
  } else {
135
0
    RETERR(str_totext("[omitted]", target));
136
0
  }
137
1.26k
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
138
19
    RETERR(str_totext(" )", target));
139
19
  }
140
1.26k
  return (ISC_R_SUCCESS);
141
1.26k
}
142
143
static isc_result_t
144
1.43k
fromwire_zonemd(ARGS_FROMWIRE) {
145
1.43k
  isc_region_t sr;
146
1.43k
  size_t digestlen = 0;
147
148
1.43k
  UNUSED(type);
149
1.43k
  UNUSED(rdclass);
150
1.43k
  UNUSED(dctx);
151
152
1.43k
  isc_buffer_activeregion(source, &sr);
153
154
  /*
155
   * If we do not recognize the digest type, ensure that the digest
156
   * meets minimum length (12).
157
   *
158
   * If we do recognize the digest type, ensure that the digest is of the
159
   * correct length.
160
   */
161
1.43k
  if (sr.length < 18) {
162
28
    return (ISC_R_UNEXPECTEDEND);
163
28
  }
164
165
1.40k
  switch (sr.base[5]) {
166
93
  case DNS_ZONEMD_DIGEST_SHA384:
167
93
    digestlen = ISC_SHA384_DIGESTLENGTH;
168
93
    break;
169
28
  case DNS_ZONEMD_DIGEST_SHA512:
170
28
    digestlen = ISC_SHA512_DIGESTLENGTH;
171
28
    break;
172
1.28k
  default:
173
1.28k
    break;
174
1.40k
  }
175
176
1.40k
  if (digestlen != 0 && sr.length < 6 + digestlen) {
177
10
    return (ISC_R_UNEXPECTEDEND);
178
10
  }
179
180
  /*
181
   * Only specify the number of octets to consume if we recognize the
182
   * digest type.
183
   *
184
   * If there is extra data, dns_rdata_fromwire() will detect that.
185
   */
186
1.39k
  if (digestlen != 0) {
187
111
    sr.length = 6 + digestlen;
188
111
  }
189
190
1.39k
  isc_buffer_forward(source, sr.length);
191
1.39k
  return (mem_tobuffer(target, sr.base, sr.length));
192
1.40k
}
193
194
static isc_result_t
195
650
towire_zonemd(ARGS_TOWIRE) {
196
650
  isc_region_t sr;
197
198
650
  REQUIRE(rdata->type == dns_rdatatype_zonemd);
199
650
  REQUIRE(rdata->length != 0);
200
201
650
  UNUSED(cctx);
202
203
650
  dns_rdata_toregion(rdata, &sr);
204
650
  return (mem_tobuffer(target, sr.base, sr.length));
205
650
}
206
207
static int
208
1.37k
compare_zonemd(ARGS_COMPARE) {
209
1.37k
  isc_region_t r1;
210
1.37k
  isc_region_t r2;
211
212
1.37k
  REQUIRE(rdata1->type == rdata2->type);
213
1.37k
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
214
1.37k
  REQUIRE(rdata1->type == dns_rdatatype_zonemd);
215
1.37k
  REQUIRE(rdata1->length != 0);
216
1.37k
  REQUIRE(rdata2->length != 0);
217
218
1.37k
  dns_rdata_toregion(rdata1, &r1);
219
1.37k
  dns_rdata_toregion(rdata2, &r2);
220
1.37k
  return (isc_region_compare(&r1, &r2));
221
1.37k
}
222
223
static isc_result_t
224
0
fromstruct_zonemd(ARGS_FROMSTRUCT) {
225
0
  dns_rdata_zonemd_t *zonemd = source;
226
227
0
  REQUIRE(zonemd != NULL);
228
0
  REQUIRE(zonemd->common.rdtype == type);
229
0
  REQUIRE(zonemd->common.rdclass == rdclass);
230
231
0
  UNUSED(type);
232
0
  UNUSED(rdclass);
233
234
0
  switch (zonemd->digest_type) {
235
0
  case DNS_ZONEMD_DIGEST_SHA384:
236
0
    REQUIRE(zonemd->length == ISC_SHA384_DIGESTLENGTH);
237
0
    break;
238
0
  case DNS_ZONEMD_DIGEST_SHA512:
239
0
    REQUIRE(zonemd->length == ISC_SHA512_DIGESTLENGTH);
240
0
    break;
241
0
  }
242
243
0
  RETERR(uint32_tobuffer(zonemd->serial, target));
244
0
  RETERR(uint8_tobuffer(zonemd->scheme, target));
245
0
  RETERR(uint8_tobuffer(zonemd->digest_type, target));
246
247
0
  return (mem_tobuffer(target, zonemd->digest, zonemd->length));
248
0
}
249
250
static isc_result_t
251
0
tostruct_zonemd(ARGS_TOSTRUCT) {
252
0
  dns_rdata_zonemd_t *zonemd = target;
253
0
  isc_region_t region;
254
255
0
  REQUIRE(rdata->type == dns_rdatatype_zonemd);
256
0
  REQUIRE(zonemd != NULL);
257
0
  REQUIRE(rdata->length != 0);
258
259
0
  zonemd->common.rdclass = rdata->rdclass;
260
0
  zonemd->common.rdtype = rdata->type;
261
0
  ISC_LINK_INIT(&zonemd->common, link);
262
263
0
  dns_rdata_toregion(rdata, &region);
264
265
0
  zonemd->serial = uint32_fromregion(&region);
266
0
  isc_region_consume(&region, 4);
267
0
  zonemd->scheme = uint8_fromregion(&region);
268
0
  isc_region_consume(&region, 1);
269
0
  zonemd->digest_type = uint8_fromregion(&region);
270
0
  isc_region_consume(&region, 1);
271
0
  zonemd->length = region.length;
272
273
0
  zonemd->digest = mem_maybedup(mctx, region.base, region.length);
274
0
  zonemd->mctx = mctx;
275
0
  return (ISC_R_SUCCESS);
276
0
}
277
278
static void
279
0
freestruct_zonemd(ARGS_FREESTRUCT) {
280
0
  dns_rdata_zonemd_t *zonemd = source;
281
282
0
  REQUIRE(zonemd != NULL);
283
0
  REQUIRE(zonemd->common.rdtype == dns_rdatatype_zonemd);
284
285
0
  if (zonemd->mctx == NULL) {
286
0
    return;
287
0
  }
288
289
0
  if (zonemd->digest != NULL) {
290
0
    isc_mem_free(zonemd->mctx, zonemd->digest);
291
0
  }
292
0
  zonemd->mctx = NULL;
293
0
}
294
295
static isc_result_t
296
0
additionaldata_zonemd(ARGS_ADDLDATA) {
297
0
  REQUIRE(rdata->type == dns_rdatatype_zonemd);
298
299
0
  UNUSED(rdata);
300
0
  UNUSED(owner);
301
0
  UNUSED(add);
302
0
  UNUSED(arg);
303
304
0
  return (ISC_R_SUCCESS);
305
0
}
306
307
static isc_result_t
308
0
digest_zonemd(ARGS_DIGEST) {
309
0
  isc_region_t r;
310
311
0
  REQUIRE(rdata->type == dns_rdatatype_zonemd);
312
313
0
  dns_rdata_toregion(rdata, &r);
314
315
0
  return ((digest)(arg, &r));
316
0
}
317
318
static bool
319
0
checkowner_zonemd(ARGS_CHECKOWNER) {
320
0
  REQUIRE(type == dns_rdatatype_zonemd);
321
322
0
  UNUSED(name);
323
0
  UNUSED(type);
324
0
  UNUSED(rdclass);
325
0
  UNUSED(wildcard);
326
327
0
  return (true);
328
0
}
329
330
static bool
331
0
checknames_zonemd(ARGS_CHECKNAMES) {
332
0
  REQUIRE(rdata->type == dns_rdatatype_zonemd);
333
334
0
  UNUSED(rdata);
335
0
  UNUSED(owner);
336
0
  UNUSED(bad);
337
338
0
  return (true);
339
0
}
340
341
static int
342
0
casecompare_zonemd(ARGS_COMPARE) {
343
0
  return (compare_zonemd(rdata1, rdata2));
344
0
}
345
346
#endif /* RDATA_GENERIC_ZONEMD_63_C */