1 /*	$NetBSD: tlsa_52.c,v 1.1.1.4 2014/12/10 03:34:42 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /* Id */
20 
21 /* rfc6698.txt */
22 
23 #ifndef RDATA_GENERIC_TLSA_52_C
24 #define RDATA_GENERIC_TLSA_52_C
25 
26 #define RRTYPE_TLSA_ATTRIBUTES 0
27 
28 static inline isc_result_t
29 fromtext_tlsa(ARGS_FROMTEXT) {
30 	isc_token_t token;
31 
32 	REQUIRE(type == 52);
33 
34 	UNUSED(type);
35 	UNUSED(rdclass);
36 	UNUSED(origin);
37 	UNUSED(options);
38 	UNUSED(callbacks);
39 
40 	/*
41 	 * Certificate Usage.
42 	 */
43 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
44 				      ISC_FALSE));
45 	if (token.value.as_ulong > 0xffU)
46 		RETTOK(ISC_R_RANGE);
47 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
48 
49 	/*
50 	 * Selector.
51 	 */
52 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
53 				      ISC_FALSE));
54 	if (token.value.as_ulong > 0xffU)
55 		RETTOK(ISC_R_RANGE);
56 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
57 
58 	/*
59 	 * Matching type.
60 	 */
61 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
62 				      ISC_FALSE));
63 	if (token.value.as_ulong > 0xffU)
64 		RETTOK(ISC_R_RANGE);
65 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
66 
67 	/*
68 	 * Certificate Association Data.
69 	 */
70 	return (isc_hex_tobuffer(lexer, target, -1));
71 }
72 
73 static inline isc_result_t
74 totext_tlsa(ARGS_TOTEXT) {
75 	isc_region_t sr;
76 	char buf[sizeof("64000 ")];
77 	unsigned int n;
78 
79 	REQUIRE(rdata->type == 52);
80 	REQUIRE(rdata->length != 0);
81 
82 	UNUSED(tctx);
83 
84 	dns_rdata_toregion(rdata, &sr);
85 
86 	/*
87 	 * Certificate Usage.
88 	 */
89 	n = uint8_fromregion(&sr);
90 	isc_region_consume(&sr, 1);
91 	sprintf(buf, "%u ", n);
92 	RETERR(str_totext(buf, target));
93 
94 	/*
95 	 * Selector.
96 	 */
97 	n = uint8_fromregion(&sr);
98 	isc_region_consume(&sr, 1);
99 	sprintf(buf, "%u ", n);
100 	RETERR(str_totext(buf, target));
101 
102 	/*
103 	 * Matching type.
104 	 */
105 	n = uint8_fromregion(&sr);
106 	isc_region_consume(&sr, 1);
107 	sprintf(buf, "%u", n);
108 	RETERR(str_totext(buf, target));
109 
110 	/*
111 	 * Certificate Association Data.
112 	 */
113 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
114 		RETERR(str_totext(" (", target));
115 	RETERR(str_totext(tctx->linebreak, target));
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 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
122 		RETERR(str_totext(" )", target));
123 	return (ISC_R_SUCCESS);
124 }
125 
126 static inline isc_result_t
127 fromwire_tlsa(ARGS_FROMWIRE) {
128 	isc_region_t sr;
129 
130 	REQUIRE(type == 52);
131 
132 	UNUSED(type);
133 	UNUSED(rdclass);
134 	UNUSED(dctx);
135 	UNUSED(options);
136 
137 	isc_buffer_activeregion(source, &sr);
138 
139 	if (sr.length < 3)
140 		return (ISC_R_UNEXPECTEDEND);
141 
142 	isc_buffer_forward(source, sr.length);
143 	return (mem_tobuffer(target, sr.base, sr.length));
144 }
145 
146 static inline isc_result_t
147 towire_tlsa(ARGS_TOWIRE) {
148 	isc_region_t sr;
149 
150 	REQUIRE(rdata->type == 52);
151 	REQUIRE(rdata->length != 0);
152 
153 	UNUSED(cctx);
154 
155 	dns_rdata_toregion(rdata, &sr);
156 	return (mem_tobuffer(target, sr.base, sr.length));
157 }
158 
159 static inline int
160 compare_tlsa(ARGS_COMPARE) {
161 	isc_region_t r1;
162 	isc_region_t r2;
163 
164 	REQUIRE(rdata1->type == rdata2->type);
165 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
166 	REQUIRE(rdata1->type == 52);
167 	REQUIRE(rdata1->length != 0);
168 	REQUIRE(rdata2->length != 0);
169 
170 	dns_rdata_toregion(rdata1, &r1);
171 	dns_rdata_toregion(rdata2, &r2);
172 	return (isc_region_compare(&r1, &r2));
173 }
174 
175 static inline isc_result_t
176 fromstruct_tlsa(ARGS_FROMSTRUCT) {
177 	dns_rdata_tlsa_t *tlsa = source;
178 
179 	REQUIRE(type == 52);
180 	REQUIRE(source != NULL);
181 	REQUIRE(tlsa->common.rdtype == type);
182 	REQUIRE(tlsa->common.rdclass == rdclass);
183 
184 	UNUSED(type);
185 	UNUSED(rdclass);
186 
187 	RETERR(uint8_tobuffer(tlsa->usage, target));
188 	RETERR(uint8_tobuffer(tlsa->selector, target));
189 	RETERR(uint8_tobuffer(tlsa->match, target));
190 
191 	return (mem_tobuffer(target, tlsa->data, tlsa->length));
192 }
193 
194 static inline isc_result_t
195 tostruct_tlsa(ARGS_TOSTRUCT) {
196 	dns_rdata_tlsa_t *tlsa = target;
197 	isc_region_t region;
198 
199 	REQUIRE(rdata->type == 52);
200 	REQUIRE(target != NULL);
201 	REQUIRE(rdata->length != 0);
202 
203 	tlsa->common.rdclass = rdata->rdclass;
204 	tlsa->common.rdtype = rdata->type;
205 	ISC_LINK_INIT(&tlsa->common, link);
206 
207 	dns_rdata_toregion(rdata, &region);
208 
209 	tlsa->usage = uint8_fromregion(&region);
210 	isc_region_consume(&region, 1);
211 	tlsa->selector = uint8_fromregion(&region);
212 	isc_region_consume(&region, 1);
213 	tlsa->match = uint8_fromregion(&region);
214 	isc_region_consume(&region, 1);
215 	tlsa->length = region.length;
216 
217 	tlsa->data = mem_maybedup(mctx, region.base, region.length);
218 	if (tlsa->data == NULL)
219 		return (ISC_R_NOMEMORY);
220 
221 	tlsa->mctx = mctx;
222 	return (ISC_R_SUCCESS);
223 }
224 
225 static inline void
226 freestruct_tlsa(ARGS_FREESTRUCT) {
227 	dns_rdata_tlsa_t *tlsa = source;
228 
229 	REQUIRE(tlsa != NULL);
230 	REQUIRE(tlsa->common.rdtype == 52);
231 
232 	if (tlsa->mctx == NULL)
233 		return;
234 
235 	if (tlsa->data != NULL)
236 		isc_mem_free(tlsa->mctx, tlsa->data);
237 	tlsa->mctx = NULL;
238 }
239 
240 static inline isc_result_t
241 additionaldata_tlsa(ARGS_ADDLDATA) {
242 	REQUIRE(rdata->type == 52);
243 
244 	UNUSED(rdata);
245 	UNUSED(add);
246 	UNUSED(arg);
247 
248 	return (ISC_R_SUCCESS);
249 }
250 
251 static inline isc_result_t
252 digest_tlsa(ARGS_DIGEST) {
253 	isc_region_t r;
254 
255 	REQUIRE(rdata->type == 52);
256 
257 	dns_rdata_toregion(rdata, &r);
258 
259 	return ((digest)(arg, &r));
260 }
261 
262 static inline isc_boolean_t
263 checkowner_tlsa(ARGS_CHECKOWNER) {
264 
265 	REQUIRE(type == 52);
266 
267 	UNUSED(name);
268 	UNUSED(type);
269 	UNUSED(rdclass);
270 	UNUSED(wildcard);
271 
272 	return (ISC_TRUE);
273 }
274 
275 static inline isc_boolean_t
276 checknames_tlsa(ARGS_CHECKNAMES) {
277 
278 	REQUIRE(rdata->type == 52);
279 
280 	UNUSED(rdata);
281 	UNUSED(owner);
282 	UNUSED(bad);
283 
284 	return (ISC_TRUE);
285 }
286 
287 static inline int
288 casecompare_tlsa(ARGS_COMPARE) {
289 	return (compare_tlsa(rdata1, rdata2));
290 }
291 
292 #endif	/* RDATA_GENERIC_TLSA_52_C */
293