1 /*	$NetBSD: sig_24.c,v 1.6 2015/07/08 17:28:59 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2015  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: Fri Mar 17 09:05:02 PST 2000 by gson */
23 
24 /* RFC2535 */
25 
26 #ifndef RDATA_GENERIC_SIG_24_C
27 #define RDATA_GENERIC_SIG_24_C
28 
29 #define RRTYPE_SIG_ATTRIBUTES (0)
30 
31 static inline isc_result_t
fromtext_sig(ARGS_FROMTEXT)32 fromtext_sig(ARGS_FROMTEXT) {
33 	isc_token_t token;
34 	unsigned char c;
35 	long i;
36 	dns_rdatatype_t covered;
37 	char *e;
38 	isc_result_t result;
39 	dns_name_t name;
40 	isc_buffer_t buffer;
41 	isc_uint32_t time_signed, time_expire;
42 
43 	REQUIRE(type == 24);
44 
45 	UNUSED(type);
46 	UNUSED(rdclass);
47 	UNUSED(callbacks);
48 
49 	/*
50 	 * Type covered.
51 	 */
52 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
53 				      ISC_FALSE));
54 	result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
55 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
56 		i = strtol(DNS_AS_STR(token), &e, 10);
57 		if (i < 0 || i > 65535)
58 			RETTOK(ISC_R_RANGE);
59 		if (*e != 0)
60 			RETTOK(result);
61 		covered = (dns_rdatatype_t)i;
62 	}
63 	RETERR(uint16_tobuffer(covered, target));
64 
65 	/*
66 	 * Algorithm.
67 	 */
68 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
69 				      ISC_FALSE));
70 	RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
71 	RETERR(mem_tobuffer(target, &c, 1));
72 
73 	/*
74 	 * Labels.
75 	 */
76 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
77 				      ISC_FALSE));
78 	if (token.value.as_ulong > 0xffU)
79 		RETTOK(ISC_R_RANGE);
80 	c = (unsigned char)token.value.as_ulong;
81 	RETERR(mem_tobuffer(target, &c, 1));
82 
83 	/*
84 	 * Original ttl.
85 	 */
86 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
87 				      ISC_FALSE));
88 	RETERR(uint32_tobuffer(token.value.as_ulong, target));
89 
90 	/*
91 	 * Signature expiration.
92 	 */
93 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
94 				      ISC_FALSE));
95 	RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
96 	RETERR(uint32_tobuffer(time_expire, target));
97 
98 	/*
99 	 * Time signed.
100 	 */
101 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
102 				      ISC_FALSE));
103 	RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
104 	RETERR(uint32_tobuffer(time_signed, target));
105 
106 	/*
107 	 * Key footprint.
108 	 */
109 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
110 				      ISC_FALSE));
111 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
112 
113 	/*
114 	 * Signer.
115 	 */
116 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
117 				      ISC_FALSE));
118 	dns_name_init(&name, NULL);
119 	buffer_fromregion(&buffer, &token.value.as_region);
120 	origin = (origin != NULL) ? origin : dns_rootname;
121 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
122 
123 	/*
124 	 * Sig.
125 	 */
126 	return (isc_base64_tobuffer(lexer, target, -1));
127 }
128 
129 static inline isc_result_t
totext_sig(ARGS_TOTEXT)130 totext_sig(ARGS_TOTEXT) {
131 	isc_region_t sr;
132 	char buf[sizeof("4294967295")];
133 	dns_rdatatype_t covered;
134 	unsigned long ttl;
135 	unsigned long when;
136 	unsigned long exp;
137 	unsigned long foot;
138 	dns_name_t name;
139 	dns_name_t prefix;
140 	isc_boolean_t sub;
141 
142 	REQUIRE(rdata->type == 24);
143 	REQUIRE(rdata->length != 0);
144 
145 	dns_rdata_toregion(rdata, &sr);
146 
147 	/*
148 	 * Type covered.
149 	 */
150 	covered = uint16_fromregion(&sr);
151 	isc_region_consume(&sr, 2);
152 	/*
153 	 * XXXAG We should have something like dns_rdatatype_isknown()
154 	 * that does the right thing with type 0.
155 	 */
156 	if (dns_rdatatype_isknown(covered) && covered != 0) {
157 		RETERR(dns_rdatatype_totext(covered, target));
158 	} else {
159 		sprintf(buf, "%u", covered);
160 		RETERR(str_totext(buf, target));
161 	}
162 	RETERR(str_totext(" ", target));
163 
164 	/*
165 	 * Algorithm.
166 	 */
167 	sprintf(buf, "%u", sr.base[0]);
168 	isc_region_consume(&sr, 1);
169 	RETERR(str_totext(buf, target));
170 	RETERR(str_totext(" ", target));
171 
172 	/*
173 	 * Labels.
174 	 */
175 	sprintf(buf, "%u", sr.base[0]);
176 	isc_region_consume(&sr, 1);
177 	RETERR(str_totext(buf, target));
178 	RETERR(str_totext(" ", target));
179 
180 	/*
181 	 * Ttl.
182 	 */
183 	ttl = uint32_fromregion(&sr);
184 	isc_region_consume(&sr, 4);
185 	sprintf(buf, "%lu", ttl);
186 	RETERR(str_totext(buf, target));
187 	RETERR(str_totext(" ", target));
188 
189 	/*
190 	 * Sig exp.
191 	 */
192 	exp = uint32_fromregion(&sr);
193 	isc_region_consume(&sr, 4);
194 	RETERR(dns_time32_totext(exp, target));
195 
196 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
197 		RETERR(str_totext(" (", target));
198 	RETERR(str_totext(tctx->linebreak, target));
199 
200 	/*
201 	 * Time signed.
202 	 */
203 	when = uint32_fromregion(&sr);
204 	isc_region_consume(&sr, 4);
205 	RETERR(dns_time32_totext(when, target));
206 	RETERR(str_totext(" ", target));
207 
208 	/*
209 	 * Footprint.
210 	 */
211 	foot = uint16_fromregion(&sr);
212 	isc_region_consume(&sr, 2);
213 	sprintf(buf, "%lu", foot);
214 	RETERR(str_totext(buf, target));
215 	RETERR(str_totext(" ", target));
216 
217 	/*
218 	 * Signer.
219 	 */
220 	dns_name_init(&name, NULL);
221 	dns_name_init(&prefix, NULL);
222 	dns_name_fromregion(&name, &sr);
223 	isc_region_consume(&sr, name_length(&name));
224 	sub = name_prefix(&name, tctx->origin, &prefix);
225 	RETERR(dns_name_totext(&prefix, sub, target));
226 
227 	/*
228 	 * Sig.
229 	 */
230 	RETERR(str_totext(tctx->linebreak, target));
231 	if (tctx->width == 0)   /* No splitting */
232 		RETERR(isc_base64_totext(&sr, 60, "", target));
233 	else
234 		RETERR(isc_base64_totext(&sr, tctx->width - 2,
235 					 tctx->linebreak, target));
236 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
237 		RETERR(str_totext(" )", target));
238 
239 	return (ISC_R_SUCCESS);
240 }
241 
242 static inline isc_result_t
fromwire_sig(ARGS_FROMWIRE)243 fromwire_sig(ARGS_FROMWIRE) {
244 	isc_region_t sr;
245 	dns_name_t name;
246 
247 	REQUIRE(type == 24);
248 
249 	UNUSED(type);
250 	UNUSED(rdclass);
251 
252 	dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
253 
254 	isc_buffer_activeregion(source, &sr);
255 	/*
256 	 * type covered: 2
257 	 * algorithm: 1
258 	 * labels: 1
259 	 * original ttl: 4
260 	 * signature expiration: 4
261 	 * time signed: 4
262 	 * key footprint: 2
263 	 */
264 	if (sr.length < 18)
265 		return (ISC_R_UNEXPECTEDEND);
266 
267 	isc_buffer_forward(source, 18);
268 	RETERR(mem_tobuffer(target, sr.base, 18));
269 
270 	/*
271 	 * Signer.
272 	 */
273 	dns_name_init(&name, NULL);
274 	RETERR(dns_name_fromwire(&name, source, dctx, options, target));
275 
276 	/*
277 	 * Sig.
278 	 */
279 	isc_buffer_activeregion(source, &sr);
280 	isc_buffer_forward(source, sr.length);
281 	return (mem_tobuffer(target, sr.base, sr.length));
282 }
283 
284 static inline isc_result_t
towire_sig(ARGS_TOWIRE)285 towire_sig(ARGS_TOWIRE) {
286 	isc_region_t sr;
287 	dns_name_t name;
288 	dns_offsets_t offsets;
289 
290 	REQUIRE(rdata->type == 24);
291 	REQUIRE(rdata->length != 0);
292 
293 	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
294 	dns_rdata_toregion(rdata, &sr);
295 	/*
296 	 * type covered: 2
297 	 * algorithm: 1
298 	 * labels: 1
299 	 * original ttl: 4
300 	 * signature expiration: 4
301 	 * time signed: 4
302 	 * key footprint: 2
303 	 */
304 	RETERR(mem_tobuffer(target, sr.base, 18));
305 	isc_region_consume(&sr, 18);
306 
307 	/*
308 	 * Signer.
309 	 */
310 	dns_name_init(&name, offsets);
311 	dns_name_fromregion(&name, &sr);
312 	isc_region_consume(&sr, name_length(&name));
313 	RETERR(dns_name_towire(&name, cctx, target));
314 
315 	/*
316 	 * Signature.
317 	 */
318 	return (mem_tobuffer(target, sr.base, sr.length));
319 }
320 
321 static inline int
compare_sig(ARGS_COMPARE)322 compare_sig(ARGS_COMPARE) {
323 	isc_region_t r1;
324 	isc_region_t r2;
325 	dns_name_t name1;
326 	dns_name_t name2;
327 	int order;
328 
329 	REQUIRE(rdata1->type == rdata2->type);
330 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
331 	REQUIRE(rdata1->type == 24);
332 	REQUIRE(rdata1->length != 0);
333 	REQUIRE(rdata2->length != 0);
334 
335 	dns_rdata_toregion(rdata1, &r1);
336 	dns_rdata_toregion(rdata2, &r2);
337 
338 	INSIST(r1.length > 18);
339 	INSIST(r2.length > 18);
340 	r1.length = 18;
341 	r2.length = 18;
342 	order = isc_region_compare(&r1, &r2);
343 	if (order != 0)
344 		return (order);
345 
346 	dns_name_init(&name1, NULL);
347 	dns_name_init(&name2, NULL);
348 	dns_rdata_toregion(rdata1, &r1);
349 	dns_rdata_toregion(rdata2, &r2);
350 	isc_region_consume(&r1, 18);
351 	isc_region_consume(&r2, 18);
352 	dns_name_fromregion(&name1, &r1);
353 	dns_name_fromregion(&name2, &r2);
354 	order = dns_name_rdatacompare(&name1, &name2);
355 	if (order != 0)
356 		return (order);
357 
358 	isc_region_consume(&r1, name_length(&name1));
359 	isc_region_consume(&r2, name_length(&name2));
360 
361 	return (isc_region_compare(&r1, &r2));
362 }
363 
364 static inline isc_result_t
fromstruct_sig(ARGS_FROMSTRUCT)365 fromstruct_sig(ARGS_FROMSTRUCT) {
366 	dns_rdata_sig_t *sig = source;
367 
368 	REQUIRE(type == 24);
369 	REQUIRE(source != NULL);
370 	REQUIRE(sig->common.rdtype == type);
371 	REQUIRE(sig->common.rdclass == rdclass);
372 	REQUIRE(sig->signature != NULL || sig->siglen == 0);
373 
374 	UNUSED(type);
375 	UNUSED(rdclass);
376 
377 	/*
378 	 * Type covered.
379 	 */
380 	RETERR(uint16_tobuffer(sig->covered, target));
381 
382 	/*
383 	 * Algorithm.
384 	 */
385 	RETERR(uint8_tobuffer(sig->algorithm, target));
386 
387 	/*
388 	 * Labels.
389 	 */
390 	RETERR(uint8_tobuffer(sig->labels, target));
391 
392 	/*
393 	 * Original TTL.
394 	 */
395 	RETERR(uint32_tobuffer(sig->originalttl, target));
396 
397 	/*
398 	 * Expire time.
399 	 */
400 	RETERR(uint32_tobuffer(sig->timeexpire, target));
401 
402 	/*
403 	 * Time signed.
404 	 */
405 	RETERR(uint32_tobuffer(sig->timesigned, target));
406 
407 	/*
408 	 * Key ID.
409 	 */
410 	RETERR(uint16_tobuffer(sig->keyid, target));
411 
412 	/*
413 	 * Signer name.
414 	 */
415 	RETERR(name_tobuffer(&sig->signer, target));
416 
417 	/*
418 	 * Signature.
419 	 */
420 	return (mem_tobuffer(target, sig->signature, sig->siglen));
421 }
422 
423 static inline isc_result_t
tostruct_sig(ARGS_TOSTRUCT)424 tostruct_sig(ARGS_TOSTRUCT) {
425 	isc_region_t sr;
426 	dns_rdata_sig_t *sig = target;
427 	dns_name_t signer;
428 
429 	REQUIRE(rdata->type == 24);
430 	REQUIRE(target != NULL);
431 	REQUIRE(rdata->length != 0);
432 
433 	sig->common.rdclass = rdata->rdclass;
434 	sig->common.rdtype = rdata->type;
435 	ISC_LINK_INIT(&sig->common, link);
436 
437 	dns_rdata_toregion(rdata, &sr);
438 
439 	/*
440 	 * Type covered.
441 	 */
442 	sig->covered = uint16_fromregion(&sr);
443 	isc_region_consume(&sr, 2);
444 
445 	/*
446 	 * Algorithm.
447 	 */
448 	sig->algorithm = uint8_fromregion(&sr);
449 	isc_region_consume(&sr, 1);
450 
451 	/*
452 	 * Labels.
453 	 */
454 	sig->labels = uint8_fromregion(&sr);
455 	isc_region_consume(&sr, 1);
456 
457 	/*
458 	 * Original TTL.
459 	 */
460 	sig->originalttl = uint32_fromregion(&sr);
461 	isc_region_consume(&sr, 4);
462 
463 	/*
464 	 * Expire time.
465 	 */
466 	sig->timeexpire = uint32_fromregion(&sr);
467 	isc_region_consume(&sr, 4);
468 
469 	/*
470 	 * Time signed.
471 	 */
472 	sig->timesigned = uint32_fromregion(&sr);
473 	isc_region_consume(&sr, 4);
474 
475 	/*
476 	 * Key ID.
477 	 */
478 	sig->keyid = uint16_fromregion(&sr);
479 	isc_region_consume(&sr, 2);
480 
481 	dns_name_init(&signer, NULL);
482 	dns_name_fromregion(&signer, &sr);
483 	dns_name_init(&sig->signer, NULL);
484 	RETERR(name_duporclone(&signer, mctx, &sig->signer));
485 	isc_region_consume(&sr, name_length(&sig->signer));
486 
487 	/*
488 	 * Signature.
489 	 */
490 	sig->siglen = sr.length;
491 	sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
492 	if (sig->signature == NULL)
493 		goto cleanup;
494 
495 
496 	sig->mctx = mctx;
497 	return (ISC_R_SUCCESS);
498 
499  cleanup:
500 	if (mctx != NULL)
501 		dns_name_free(&sig->signer, mctx);
502 	return (ISC_R_NOMEMORY);
503 }
504 
505 static inline void
freestruct_sig(ARGS_FREESTRUCT)506 freestruct_sig(ARGS_FREESTRUCT) {
507 	dns_rdata_sig_t *sig = (dns_rdata_sig_t *) source;
508 
509 	REQUIRE(source != NULL);
510 	REQUIRE(sig->common.rdtype == 24);
511 
512 	if (sig->mctx == NULL)
513 		return;
514 
515 	dns_name_free(&sig->signer, sig->mctx);
516 	if (sig->signature != NULL)
517 		isc_mem_free(sig->mctx, sig->signature);
518 	sig->mctx = NULL;
519 }
520 
521 static inline isc_result_t
additionaldata_sig(ARGS_ADDLDATA)522 additionaldata_sig(ARGS_ADDLDATA) {
523 	REQUIRE(rdata->type == 24);
524 
525 	UNUSED(rdata);
526 	UNUSED(add);
527 	UNUSED(arg);
528 
529 	return (ISC_R_SUCCESS);
530 }
531 
532 static inline isc_result_t
digest_sig(ARGS_DIGEST)533 digest_sig(ARGS_DIGEST) {
534 
535 	REQUIRE(rdata->type == 24);
536 
537 	UNUSED(rdata);
538 	UNUSED(digest);
539 	UNUSED(arg);
540 
541 	return (ISC_R_NOTIMPLEMENTED);
542 }
543 
544 static inline dns_rdatatype_t
covers_sig(dns_rdata_t * rdata)545 covers_sig(dns_rdata_t *rdata) {
546 	dns_rdatatype_t type;
547 	isc_region_t r;
548 
549 	REQUIRE(rdata->type == 24);
550 
551 	dns_rdata_toregion(rdata, &r);
552 	type = uint16_fromregion(&r);
553 
554 	return (type);
555 }
556 
557 static inline isc_boolean_t
checkowner_sig(ARGS_CHECKOWNER)558 checkowner_sig(ARGS_CHECKOWNER) {
559 
560 	REQUIRE(type == 24);
561 
562 	UNUSED(name);
563 	UNUSED(type);
564 	UNUSED(rdclass);
565 	UNUSED(wildcard);
566 
567 	return (ISC_TRUE);
568 }
569 
570 static inline isc_boolean_t
checknames_sig(ARGS_CHECKNAMES)571 checknames_sig(ARGS_CHECKNAMES) {
572 
573 	REQUIRE(rdata->type == 24);
574 
575 	UNUSED(rdata);
576 	UNUSED(owner);
577 	UNUSED(bad);
578 
579 	return (ISC_TRUE);
580 }
581 
582 static inline int
casecompare_sig(ARGS_COMPARE)583 casecompare_sig(ARGS_COMPARE) {
584 	return (compare_sig(rdata1, rdata2));
585 }
586 #endif	/* RDATA_GENERIC_SIG_24_C */
587