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