Coverage Report

Created: 2026-02-26 06:45

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
12.4k
#define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
39
40
static isc_result_t
41
1.12k
fromtext_nsec3param(ARGS_FROMTEXT) {
42
1.12k
  isc_token_t token;
43
1.12k
  unsigned int flags = 0;
44
1.12k
  unsigned char hashalg;
45
46
1.12k
  REQUIRE(type == dns_rdatatype_nsec3param);
47
48
1.12k
  UNUSED(type);
49
1.12k
  UNUSED(rdclass);
50
1.12k
  UNUSED(callbacks);
51
1.12k
  UNUSED(origin);
52
1.12k
  UNUSED(options);
53
54
  /* Hash. */
55
1.12k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
56
1.12k
              false));
57
1.11k
  RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
58
1.06k
  RETERR(uint8_tobuffer(hashalg, target));
59
60
  /* Flags. */
61
1.06k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
62
1.06k
              false));
63
1.05k
  flags = token.value.as_ulong;
64
1.05k
  if (flags > 255U) {
65
41
    RETTOK(ISC_R_RANGE);
66
41
  }
67
1.01k
  RETERR(uint8_tobuffer(flags, target));
68
69
  /* Iterations. */
70
1.01k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
71
1.01k
              false));
72
998
  if (token.value.as_ulong > 0xffffU) {
73
12
    RETTOK(ISC_R_RANGE);
74
12
  }
75
986
  RETERR(uint16_tobuffer(token.value.as_ulong, target));
76
77
  /* Salt. */
78
986
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
79
986
              false));
80
947
  if (token.value.as_textregion.length > (255 * 2)) {
81
8
    RETTOK(DNS_R_TEXTTOOLONG);
82
8
  }
83
939
  if (strcmp(DNS_AS_STR(token), "-") == 0) {
84
496
    RETERR(uint8_tobuffer(0, target));
85
496
  } else {
86
443
    RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
87
443
    RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
88
425
  }
89
90
921
  return ISC_R_SUCCESS;
91
939
}
92
93
static isc_result_t
94
1.37k
totext_nsec3param(ARGS_TOTEXT) {
95
1.37k
  isc_region_t sr;
96
1.37k
  unsigned int i, j;
97
1.37k
  unsigned char hash;
98
1.37k
  unsigned char flags;
99
1.37k
  char buf[sizeof("65535 ")];
100
1.37k
  uint32_t iterations;
101
102
1.37k
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
103
1.37k
  REQUIRE(rdata->length != 0);
104
105
1.37k
  UNUSED(tctx);
106
107
1.37k
  dns_rdata_toregion(rdata, &sr);
108
109
1.37k
  hash = uint8_fromregion(&sr);
110
1.37k
  isc_region_consume(&sr, 1);
111
112
1.37k
  flags = uint8_fromregion(&sr);
113
1.37k
  isc_region_consume(&sr, 1);
114
115
1.37k
  iterations = uint16_fromregion(&sr);
116
1.37k
  isc_region_consume(&sr, 2);
117
118
1.37k
  snprintf(buf, sizeof(buf), "%u ", hash);
119
1.37k
  RETERR(str_totext(buf, target));
120
121
1.37k
  snprintf(buf, sizeof(buf), "%u ", flags);
122
1.37k
  RETERR(str_totext(buf, target));
123
124
1.37k
  snprintf(buf, sizeof(buf), "%u ", iterations);
125
1.37k
  RETERR(str_totext(buf, target));
126
127
1.37k
  j = uint8_fromregion(&sr);
128
1.37k
  isc_region_consume(&sr, 1);
129
1.37k
  INSIST(j <= sr.length);
130
131
1.37k
  if (j != 0) {
132
580
    i = sr.length;
133
580
    sr.length = j;
134
580
    RETERR(isc_hex_totext(&sr, 1, "", target));
135
580
    sr.length = i - j;
136
791
  } else {
137
791
    RETERR(str_totext("-", target));
138
791
  }
139
140
1.37k
  return ISC_R_SUCCESS;
141
1.37k
}
142
143
static isc_result_t
144
1.80k
fromwire_nsec3param(ARGS_FROMWIRE) {
145
1.80k
  isc_region_t sr, rr;
146
1.80k
  unsigned int saltlen;
147
148
1.80k
  REQUIRE(type == dns_rdatatype_nsec3param);
149
150
1.80k
  UNUSED(type);
151
1.80k
  UNUSED(rdclass);
152
1.80k
  UNUSED(dctx);
153
154
1.80k
  isc_buffer_activeregion(source, &sr);
155
1.80k
  rr = sr;
156
157
  /* hash(1), flags(1), iterations(2), saltlen(1) */
158
1.80k
  if (sr.length < 5U) {
159
15
    RETERR(DNS_R_FORMERR);
160
0
  }
161
1.78k
  saltlen = sr.base[4];
162
1.78k
  isc_region_consume(&sr, 5);
163
164
1.78k
  if (sr.length != saltlen) {
165
49
    RETERR(DNS_R_FORMERR);
166
0
  }
167
1.73k
  isc_region_consume(&sr, saltlen);
168
1.73k
  RETERR(mem_tobuffer(target, rr.base, rr.length));
169
1.65k
  isc_buffer_forward(source, rr.length);
170
1.65k
  return ISC_R_SUCCESS;
171
1.73k
}
172
173
static isc_result_t
174
696
towire_nsec3param(ARGS_TOWIRE) {
175
696
  isc_region_t sr;
176
177
696
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
178
696
  REQUIRE(rdata->length != 0);
179
180
696
  UNUSED(cctx);
181
182
696
  dns_rdata_toregion(rdata, &sr);
183
696
  return mem_tobuffer(target, sr.base, sr.length);
184
696
}
185
186
static int
187
2.49k
compare_nsec3param(ARGS_COMPARE) {
188
2.49k
  isc_region_t r1;
189
2.49k
  isc_region_t r2;
190
191
2.49k
  REQUIRE(rdata1->type == rdata2->type);
192
2.49k
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
193
2.49k
  REQUIRE(rdata1->type == dns_rdatatype_nsec3param);
194
2.49k
  REQUIRE(rdata1->length != 0);
195
2.49k
  REQUIRE(rdata2->length != 0);
196
197
2.49k
  dns_rdata_toregion(rdata1, &r1);
198
2.49k
  dns_rdata_toregion(rdata2, &r2);
199
2.49k
  return isc_region_compare(&r1, &r2);
200
2.49k
}
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, nsec3param->salt_length));
219
0
  return ISC_R_SUCCESS;
220
0
}
221
222
static isc_result_t
223
19
tostruct_nsec3param(ARGS_TOSTRUCT) {
224
19
  isc_region_t region;
225
19
  dns_rdata_nsec3param_t *nsec3param = target;
226
227
19
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
228
19
  REQUIRE(nsec3param != NULL);
229
19
  REQUIRE(rdata->length != 0);
230
231
19
  DNS_RDATACOMMON_INIT(nsec3param, rdata->type, rdata->rdclass);
232
233
19
  region.base = rdata->data;
234
19
  region.length = rdata->length;
235
19
  nsec3param->hash = uint8_consume_fromregion(&region);
236
19
  nsec3param->flags = uint8_consume_fromregion(&region);
237
19
  nsec3param->iterations = uint16_consume_fromregion(&region);
238
239
19
  nsec3param->salt_length = uint8_consume_fromregion(&region);
240
19
  INSIST(nsec3param->salt_length == region.length);
241
19
  nsec3param->salt = mem_maybedup(mctx, region.base,
242
19
          nsec3param->salt_length);
243
19
  isc_region_consume(&region, nsec3param->salt_length);
244
245
19
  nsec3param->mctx = mctx;
246
19
  return ISC_R_SUCCESS;
247
19
}
248
249
static void
250
0
freestruct_nsec3param(ARGS_FREESTRUCT) {
251
0
  dns_rdata_nsec3param_t *nsec3param = source;
252
253
0
  REQUIRE(nsec3param != NULL);
254
0
  REQUIRE(nsec3param->common.rdtype == dns_rdatatype_nsec3param);
255
256
0
  if (nsec3param->mctx == NULL) {
257
0
    return;
258
0
  }
259
260
0
  if (nsec3param->salt != NULL) {
261
0
    isc_mem_free(nsec3param->mctx, nsec3param->salt);
262
0
  }
263
0
  nsec3param->mctx = NULL;
264
0
}
265
266
static isc_result_t
267
0
additionaldata_nsec3param(ARGS_ADDLDATA) {
268
0
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
269
270
0
  UNUSED(rdata);
271
0
  UNUSED(owner);
272
0
  UNUSED(add);
273
0
  UNUSED(arg);
274
275
0
  return ISC_R_SUCCESS;
276
0
}
277
278
static isc_result_t
279
0
digest_nsec3param(ARGS_DIGEST) {
280
0
  isc_region_t r;
281
282
0
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
283
284
0
  dns_rdata_toregion(rdata, &r);
285
0
  return (digest)(arg, &r);
286
0
}
287
288
static bool
289
0
checkowner_nsec3param(ARGS_CHECKOWNER) {
290
0
  REQUIRE(type == dns_rdatatype_nsec3param);
291
292
0
  UNUSED(name);
293
0
  UNUSED(type);
294
0
  UNUSED(rdclass);
295
0
  UNUSED(wildcard);
296
297
0
  return true;
298
0
}
299
300
static bool
301
0
checknames_nsec3param(ARGS_CHECKNAMES) {
302
0
  REQUIRE(rdata->type == dns_rdatatype_nsec3param);
303
304
0
  UNUSED(rdata);
305
0
  UNUSED(owner);
306
0
  UNUSED(bad);
307
308
0
  return true;
309
0
}
310
311
static int
312
0
casecompare_nsec3param(ARGS_COMPARE) {
313
0
  return compare_nsec3param(rdata1, rdata2);
314
0
}
315
316
#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */