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