2 * Copyright (C) 2008, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
20 * Copyright (C) 2004 Nominet, Ltd.
22 * Permission to use, copy, modify, and distribute this software for any
23 * purpose with or without fee is hereby granted, provided that the above
24 * copyright notice and this permission notice appear in all copies.
26 * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH
27 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
28 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
29 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
30 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
31 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
32 * PERFORMANCE OF THIS SOFTWARE.
37 #ifndef RDATA_GENERIC_NSEC3_50_C
38 #define RDATA_GENERIC_NSEC3_50_C
40 #include <isc/iterated_hash.h>
41 #include <isc/base32.h>
43 #define RRTYPE_NSEC3_ATTRIBUTES DNS_RDATATYPEATTR_DNSSEC
45 static inline isc_result_t
46 fromtext_nsec3(ARGS_FROMTEXT) {
49 unsigned char hashalg;
51 unsigned char buf[256];
53 REQUIRE(type == dns_rdatatype_nsec3);
62 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
64 RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion));
65 RETERR(uint8_tobuffer(hashalg, target));
68 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
70 flags = token.value.as_ulong;
73 RETERR(uint8_tobuffer(flags, target));
76 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
78 if (token.value.as_ulong > 0xffffU)
80 RETERR(uint16_tobuffer(token.value.as_ulong, target));
83 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
85 if (token.value.as_textregion.length > (255*2))
86 RETTOK(DNS_R_TEXTTOOLONG);
87 if (strcmp(DNS_AS_STR(token), "-") == 0) {
88 RETERR(uint8_tobuffer(0, target));
90 RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target));
91 RETERR(isc_hex_decodestring(DNS_AS_STR(token), target));
95 * Next hash a single base32hex word.
97 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
99 isc_buffer_init(&b, buf, sizeof(buf));
100 RETTOK(isc_base32hexnp_decodestring(DNS_AS_STR(token), &b));
101 if (isc_buffer_usedlength(&b) > 0xffU)
103 RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target));
104 RETERR(mem_tobuffer(target, &buf, isc_buffer_usedlength(&b)));
106 return (typemap_fromtext(lexer, target, ISC_TRUE));
109 static inline isc_result_t
110 totext_nsec3(ARGS_TOTEXT) {
115 char buf[sizeof("TYPE65535")];
116 isc_uint32_t iterations;
118 REQUIRE(rdata->type == dns_rdatatype_nsec3);
119 REQUIRE(rdata->length != 0);
121 dns_rdata_toregion(rdata, &sr);
124 hash = uint8_fromregion(&sr);
125 isc_region_consume(&sr, 1);
126 sprintf(buf, "%u ", hash);
127 RETERR(str_totext(buf, target));
130 flags = uint8_fromregion(&sr);
131 isc_region_consume(&sr, 1);
132 sprintf(buf, "%u ", flags);
133 RETERR(str_totext(buf, target));
136 iterations = uint16_fromregion(&sr);
137 isc_region_consume(&sr, 2);
138 sprintf(buf, "%u ", iterations);
139 RETERR(str_totext(buf, target));
142 j = uint8_fromregion(&sr);
143 isc_region_consume(&sr, 1);
144 INSIST(j <= sr.length);
149 RETERR(isc_hex_totext(&sr, 1, "", target));
152 RETERR(str_totext("-", target));
154 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
155 RETERR(str_totext(" (", target));
156 RETERR(str_totext(tctx->linebreak, target));
159 j = uint8_fromregion(&sr);
160 isc_region_consume(&sr, 1);
161 INSIST(j <= sr.length);
165 RETERR(isc_base32hexnp_totext(&sr, 1, "", target));
168 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0)
169 RETERR(str_totext(" ", target));
171 RETERR(typemap_totext(&sr, tctx, target));
173 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
174 RETERR(str_totext(" )", target));
176 return (ISC_R_SUCCESS);
179 static inline isc_result_t
180 fromwire_nsec3(ARGS_FROMWIRE) {
182 unsigned int saltlen, hashlen;
184 REQUIRE(type == dns_rdatatype_nsec3);
191 isc_buffer_activeregion(source, &sr);
194 /* hash(1), flags(1), iteration(2), saltlen(1) */
196 RETERR(DNS_R_FORMERR);
197 saltlen = sr.base[4];
198 isc_region_consume(&sr, 5);
200 if (sr.length < saltlen)
201 RETERR(DNS_R_FORMERR);
202 isc_region_consume(&sr, saltlen);
205 RETERR(DNS_R_FORMERR);
206 hashlen = sr.base[0];
207 isc_region_consume(&sr, 1);
209 if (sr.length < hashlen)
210 RETERR(DNS_R_FORMERR);
211 isc_region_consume(&sr, hashlen);
213 RETERR(typemap_test(&sr, ISC_TRUE));
215 RETERR(mem_tobuffer(target, rr.base, rr.length));
216 isc_buffer_forward(source, rr.length);
217 return (ISC_R_SUCCESS);
220 static inline isc_result_t
221 towire_nsec3(ARGS_TOWIRE) {
224 REQUIRE(rdata->type == dns_rdatatype_nsec3);
225 REQUIRE(rdata->length != 0);
229 dns_rdata_toregion(rdata, &sr);
230 return (mem_tobuffer(target, sr.base, sr.length));
234 compare_nsec3(ARGS_COMPARE) {
238 REQUIRE(rdata1->type == rdata2->type);
239 REQUIRE(rdata1->rdclass == rdata2->rdclass);
240 REQUIRE(rdata1->type == dns_rdatatype_nsec3);
241 REQUIRE(rdata1->length != 0);
242 REQUIRE(rdata2->length != 0);
244 dns_rdata_toregion(rdata1, &r1);
245 dns_rdata_toregion(rdata2, &r2);
246 return (isc_region_compare(&r1, &r2));
249 static inline isc_result_t
250 fromstruct_nsec3(ARGS_FROMSTRUCT) {
251 dns_rdata_nsec3_t *nsec3 = source;
254 REQUIRE(type == dns_rdatatype_nsec3);
255 REQUIRE(source != NULL);
256 REQUIRE(nsec3->common.rdtype == type);
257 REQUIRE(nsec3->common.rdclass == rdclass);
258 REQUIRE(nsec3->typebits != NULL || nsec3->len == 0);
259 REQUIRE(nsec3->hash == dns_hash_sha1);
264 RETERR(uint8_tobuffer(nsec3->hash, target));
265 RETERR(uint8_tobuffer(nsec3->flags, target));
266 RETERR(uint16_tobuffer(nsec3->iterations, target));
267 RETERR(uint8_tobuffer(nsec3->salt_length, target));
268 RETERR(mem_tobuffer(target, nsec3->salt, nsec3->salt_length));
269 RETERR(uint8_tobuffer(nsec3->next_length, target));
270 RETERR(mem_tobuffer(target, nsec3->next, nsec3->next_length));
272 region.base = nsec3->typebits;
273 region.length = nsec3->len;
274 RETERR(typemap_test(®ion, ISC_TRUE));
275 return (mem_tobuffer(target, nsec3->typebits, nsec3->len));
278 static inline isc_result_t
279 tostruct_nsec3(ARGS_TOSTRUCT) {
281 dns_rdata_nsec3_t *nsec3 = target;
283 REQUIRE(rdata->type == dns_rdatatype_nsec3);
284 REQUIRE(target != NULL);
285 REQUIRE(rdata->length != 0);
287 nsec3->common.rdclass = rdata->rdclass;
288 nsec3->common.rdtype = rdata->type;
289 ISC_LINK_INIT(&nsec3->common, link);
291 region.base = rdata->data;
292 region.length = rdata->length;
293 nsec3->hash = uint8_consume_fromregion(®ion);
294 nsec3->flags = uint8_consume_fromregion(®ion);
295 nsec3->iterations = uint16_consume_fromregion(®ion);
297 nsec3->salt_length = uint8_consume_fromregion(®ion);
298 nsec3->salt = mem_maybedup(mctx, region.base, nsec3->salt_length);
299 if (nsec3->salt == NULL)
300 return (ISC_R_NOMEMORY);
301 isc_region_consume(®ion, nsec3->salt_length);
303 nsec3->next_length = uint8_consume_fromregion(®ion);
304 nsec3->next = mem_maybedup(mctx, region.base, nsec3->next_length);
305 if (nsec3->next == NULL)
307 isc_region_consume(®ion, nsec3->next_length);
309 nsec3->len = region.length;
310 nsec3->typebits = mem_maybedup(mctx, region.base, region.length);
311 if (nsec3->typebits == NULL)
315 return (ISC_R_SUCCESS);
318 if (nsec3->next != NULL)
319 isc_mem_free(mctx, nsec3->next);
320 isc_mem_free(mctx, nsec3->salt);
321 return (ISC_R_NOMEMORY);
325 freestruct_nsec3(ARGS_FREESTRUCT) {
326 dns_rdata_nsec3_t *nsec3 = source;
328 REQUIRE(source != NULL);
329 REQUIRE(nsec3->common.rdtype == dns_rdatatype_nsec3);
331 if (nsec3->mctx == NULL)
334 if (nsec3->salt != NULL)
335 isc_mem_free(nsec3->mctx, nsec3->salt);
336 if (nsec3->next != NULL)
337 isc_mem_free(nsec3->mctx, nsec3->next);
338 if (nsec3->typebits != NULL)
339 isc_mem_free(nsec3->mctx, nsec3->typebits);
343 static inline isc_result_t
344 additionaldata_nsec3(ARGS_ADDLDATA) {
345 REQUIRE(rdata->type == dns_rdatatype_nsec3);
351 return (ISC_R_SUCCESS);
354 static inline isc_result_t
355 digest_nsec3(ARGS_DIGEST) {
358 REQUIRE(rdata->type == dns_rdatatype_nsec3);
360 dns_rdata_toregion(rdata, &r);
361 return ((digest)(arg, &r));
364 static inline isc_boolean_t
365 checkowner_nsec3(ARGS_CHECKOWNER) {
366 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
370 REQUIRE(type == dns_rdatatype_nsec3);
377 * First label is a base32hex string without padding.
379 dns_name_getlabel(name, 0, &label);
380 isc_region_consume(&label, 1);
381 isc_buffer_init(&buffer, owner, sizeof(owner));
382 if (isc_base32hexnp_decoderegion(&label, &buffer) == ISC_R_SUCCESS)
388 static inline isc_boolean_t
389 checknames_nsec3(ARGS_CHECKNAMES) {
391 REQUIRE(rdata->type == dns_rdatatype_nsec3);
401 casecompare_nsec3(ARGS_COMPARE) {
402 return (compare_nsec3(rdata1, rdata2));
405 #endif /* RDATA_GENERIC_NSEC3_50_C */