PageRenderTime 43ms CodeModel.GetById 11ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 0ms

/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c

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