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