Coverage Report

Created: 2026-06-15 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/rdata/generic/nsec3param_51.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
/*
15
 * Copyright (C) 2004  Nominet, Ltd.
16
 *
17
 * Permission to use, copy, modify, and distribute this software for any
18
 * purpose with or without fee is hereby granted, provided that the above
19
 * copyright notice and this permission notice appear in all copies.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH
22
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
23
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
24
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
26
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27
 * PERFORMANCE OF THIS SOFTWARE.
28
 */
29
30
/* RFC 5155 */
31
32
#ifndef RDATA_GENERIC_NSEC3PARAM_51_C
33
#define RDATA_GENERIC_NSEC3PARAM_51_C
34
35
#include <isc/base32.h>
36
#include <isc/iterated_hash.h>
37
38
11.4k
#define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
39
40
static isc_result_t
41
1.22k
fromtext_nsec3param(ARGS_FROMTEXT) {
42
1.22k
  isc_token_t token;
43
1.22k
  unsigned int flags = 0;
44
1.22k
  unsigned char hashalg;
45
46
1.22k
  REQUIRE(type == dns_rdatatype_nsec3param);
47
48
1.22k
  UNUSED(type);
49
1.22k
  UNUSED(rdclass);
50
1.22k
  UNUSED(callbacks);
51
1.22k
  UNUSED(origin);
52
1.22k
  UNUSED(options);
53
54
  /* Hash. */
55
1.22k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
56
1.22k
              false));
57
1.21k
  RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
58
1.16k
  RETERR(uint8_tobuffer(hashalg, target));
59
60
  /* Flags. */
61
1.16k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
62
1.16k
              false));
63
1.15k
  flags = token.value.as_ulong;
64
1.15k
  if (flags > 255U) {
65
70
    RETTOK(ISC_R_RANGE);
66
70
  }
67
1.08k
  RETERR(uint8_tobuffer(flags, target));
68
69
  /* Iterations. */
70
1.08k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
71
1.08k
              false));
72
1.06k
  if (token.value.as_ulong > 0xffffU) {
73
26
    RETTOK(ISC_R_RANGE);
74
26
  }
75
1.03k
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
76
77
  /* Salt. */
78
1.03k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
79
1.03k
              false));
80
997
  if (token.value.as_textregion.length > (255 * 2)) {
81
11
    RETTOK(DNS_R_TEXTTOOLONG);
82
11
  }
83
986
  if (strcmp(DNS_AS_STR(token), "-") == 0) {
84
484
    RETERR(uint8_tobuffer(0, target));
85
502
  } else {
86
502
    RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
87
502
    RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
88
490
  }
89
90
974
  return ISC_R_SUCCESS;
91
986
}
92
93
static isc_result_t
94
1.00k
totext_nsec3param(ARGS_TOTEXT) {
95
1.00k
  isc_region_t sr;
96
1.00k
  unsigned int i, j;
97
1.00k
  unsigned char hash;
98
1.00k
  unsigned char flags;
99
1.00k
  char buf[sizeof("65535 ")];
100
1.00k
  uint32_t iterations;
101
102
1.00k
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
103
1.00k
  REQUIRE(rdata->length != 0);
104
105
1.00k
  UNUSED(tctx);
106
107
1.00k
  dns_rdata_toregion(rdata, &sr);
108
109
1.00k
  hash = uint8_fromregion(&sr);
110
1.00k
  isc_region_consume(&sr, 1);
111
112
1.00k
  flags = uint8_fromregion(&sr);
113
1.00k
  isc_region_consume(&sr, 1);
114
115
1.00k
  iterations = uint16_fromregion(&sr);
116
1.00k
  isc_region_consume(&sr, 2);
117
118
1.00k
  snprintf(buf, sizeof(buf), "%u ", hash);
119
1.00k
  RETERR(str_totext(buf, target));
120
121
1.00k
  snprintf(buf, sizeof(buf), "%u ", flags);
122
1.00k
  RETERR(str_totext(buf, target));
123
124
1.00k
  snprintf(buf, sizeof(buf), "%u ", iterations);
125
1.00k
  RETERR(str_totext(buf, target));
126
127
1.00k
  j = uint8_fromregion(&sr);
128
1.00k
  isc_region_consume(&sr, 1);
129
1.00k
  INSIST(j <= sr.length);
130
131
1.00k
  if (j != 0) {
132
556
    i = sr.length;
133
556
    sr.length = j;
134
556
    RETERR(isc_hex_totext(&sr, 1, "", target));
135
556
    sr.length = i - j;
136
556
  } else {
137
452
    RETERR(str_totext("-", target));
138
452
  }
139
140
1.00k
  return ISC_R_SUCCESS;
141
1.00k
}
142
143
static isc_result_t
144
1.40k
fromwire_nsec3param(ARGS_FROMWIRE) {
145
1.40k
  isc_region_t sr, rr;
146
1.40k
  unsigned int saltlen;
147
148
1.40k
  REQUIRE(type == dns_rdatatype_nsec3param);
149
150
1.40k
  UNUSED(type);
151
1.40k
  UNUSED(rdclass);
152
1.40k
  UNUSED(dctx);
153
154
1.40k
  isc_buffer_activeregion(source, &sr);
155
1.40k
  rr = sr;
156
157
  /* hash(1), flags(1), iterations(2), saltlen(1) */
158
1.40k
  if (sr.length < 5U) {
159
14
    RETERR(DNS_R_FORMERR);
160
0
  }
161
1.38k
  saltlen = sr.base[4];
162
1.38k
  isc_region_consume(&sr, 5);
163
164
1.38k
  if (sr.length != saltlen) {
165
58
    RETERR(DNS_R_FORMERR);
166
0
  }
167
1.33k
  isc_region_consume(&sr, saltlen);
168
1.33k
  RETERR(mem_tobuffer(target, rr.base, rr.length));
169
1.25k
  isc_buffer_forward(source, rr.length);
170
1.25k
  return ISC_R_SUCCESS;
171
1.33k
}
172
173
static isc_result_t
174
514
towire_nsec3param(ARGS_TOWIRE) {
175
514
  isc_region_t sr;
176
177
514
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
178
514
  REQUIRE(rdata->length != 0);
179
180
514
  UNUSED(cctx);
181
182
514
  dns_rdata_toregion(rdata, &sr);
183
514
  return mem_tobuffer(target, sr.base, sr.length);
184
514
}
185
186
static int
187
2.96k
compare_nsec3param(ARGS_COMPARE) {
188
2.96k
  isc_region_t r1;
189
2.96k
  isc_region_t r2;
190
191
2.96k
  REQUIRE(rdata1->type == rdata2->type);
192
2.96k
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
193
2.96k
  REQUIRE(rdata1->type == dns_rdatatype_nsec3param);
194
2.96k
  REQUIRE(rdata1->length != 0);
195
2.96k
  REQUIRE(rdata2->length != 0);
196
197
2.96k
  dns_rdata_toregion(rdata1, &r1);
198
2.96k
  dns_rdata_toregion(rdata2, &r2);
199
2.96k
  return isc_region_compare(&r1, &r2);
200
2.96k
}
201
202
static isc_result_t
203
0
fromstruct_nsec3param(ARGS_FROMSTRUCT) {
204
0
  dns_rdata_nsec3param_t *nsec3param = source;
205
206
0
  REQUIRE(type == dns_rdatatype_nsec3param);
207
0
  REQUIRE(nsec3param != NULL);
208
0
  REQUIRE(nsec3param->common.rdtype == type);
209
0
  REQUIRE(nsec3param->common.rdclass == rdclass);
210
211
0
  UNUSED(type);
212
0
  UNUSED(rdclass);
213
214
0
  RETERR(uint8_tobuffer(nsec3param->hash, target));
215
0
  RETERR(uint8_tobuffer(nsec3param->flags, target));
216
0
  RETERR(uint16_tobuffer(nsec3param->iterations, target));
217
0
  RETERR(uint8_tobuffer(nsec3param->salt.length, target));
218
0
  RETERR(mem_tobuffer(target, nsec3param->salt.base,
219
0
          nsec3param->salt.length));
220
0
  return ISC_R_SUCCESS;
221
0
}
222
223
static isc_result_t
224
18
tostruct_nsec3param(ARGS_TOSTRUCT) {
225
18
  isc_region_t region;
226
18
  dns_rdata_nsec3param_t *nsec3param = target;
227
228
18
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
229
18
  REQUIRE(nsec3param != NULL);
230
18
  REQUIRE(rdata->length != 0);
231
232
18
  DNS_RDATACOMMON_INIT(nsec3param, rdata->type, rdata->rdclass);
233
234
18
  region.base = rdata->data;
235
18
  region.length = rdata->length;
236
18
  nsec3param->hash = uint8_consume_fromregion(&region);
237
18
  nsec3param->flags = uint8_consume_fromregion(&region);
238
18
  nsec3param->iterations = uint16_consume_fromregion(&region);
239
240
18
  nsec3param->salt.length = uint8_consume_fromregion(&region);
241
18
  INSIST(nsec3param->salt.length == region.length);
242
18
  nsec3param->salt.base = mem_maybedup(mctx, region.base,
243
18
               nsec3param->salt.length);
244
18
  isc_region_consume(&region, nsec3param->salt.length);
245
246
18
  nsec3param->mctx = mctx;
247
18
  return ISC_R_SUCCESS;
248
18
}
249
250
static void
251
0
freestruct_nsec3param(ARGS_FREESTRUCT) {
252
0
  dns_rdata_nsec3param_t *nsec3param = source;
253
254
0
  REQUIRE(nsec3param != NULL);
255
0
  REQUIRE(nsec3param->common.rdtype == dns_rdatatype_nsec3param);
256
257
0
  if (nsec3param->mctx == NULL) {
258
0
    return;
259
0
  }
260
261
0
  if (nsec3param->salt.base != NULL) {
262
0
    isc_mem_free(nsec3param->mctx, nsec3param->salt.base);
263
0
    nsec3param->salt.length = 0;
264
0
  }
265
0
  nsec3param->mctx = NULL;
266
0
}
267
268
static isc_result_t
269
0
additionaldata_nsec3param(ARGS_ADDLDATA) {
270
0
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
271
272
0
  UNUSED(rdata);
273
0
  UNUSED(owner);
274
0
  UNUSED(add);
275
0
  UNUSED(arg);
276
277
0
  return ISC_R_SUCCESS;
278
0
}
279
280
static isc_result_t
281
0
digest_nsec3param(ARGS_DIGEST) {
282
0
  isc_region_t r;
283
284
0
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
285
286
0
  dns_rdata_toregion(rdata, &r);
287
0
  return (digest)(arg, &r);
288
0
}
289
290
static bool
291
0
checkowner_nsec3param(ARGS_CHECKOWNER) {
292
0
  REQUIRE(type == dns_rdatatype_nsec3param);
293
294
0
  UNUSED(name);
295
0
  UNUSED(type);
296
0
  UNUSED(rdclass);
297
0
  UNUSED(wildcard);
298
299
0
  return true;
300
0
}
301
302
static bool
303
0
checknames_nsec3param(ARGS_CHECKNAMES) {
304
0
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
305
306
0
  UNUSED(rdata);
307
0
  UNUSED(owner);
308
0
  UNUSED(bad);
309
310
0
  return true;
311
0
}
312
313
static int
314
0
casecompare_nsec3param(ARGS_COMPARE) {
315
0
  return compare_nsec3param(rdata1, rdata2);
316
0
}
317
318
#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */