xref: /openbsd/usr.bin/dig/lib/dns/rdata/generic/ds_43.c (revision 873f12b9)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* $Id: ds_43.c,v 1.13 2020/02/26 18:47:59 florian Exp $ */
18 
19 /* RFC3658 */
20 
21 #ifndef RDATA_GENERIC_DS_43_C
22 #define RDATA_GENERIC_DS_43_C
23 
24 #include <isc/sha1.h>
25 #include <isc/sha2.h>
26 
27 #include <dns/ds.h>
28 
29 static inline isc_result_t
generic_totext_ds(ARGS_TOTEXT)30 generic_totext_ds(ARGS_TOTEXT) {
31 	isc_region_t sr;
32 	char buf[sizeof("64000 ")];
33 	unsigned int n;
34 
35 	REQUIRE(rdata->length != 0);
36 
37 	UNUSED(tctx);
38 
39 	dns_rdata_toregion(rdata, &sr);
40 
41 	/*
42 	 * Key tag.
43 	 */
44 	n = uint16_fromregion(&sr);
45 	isc_region_consume(&sr, 2);
46 	snprintf(buf, sizeof(buf), "%u ", n);
47 	RETERR(isc_str_tobuffer(buf, target));
48 
49 	/*
50 	 * Algorithm.
51 	 */
52 	n = uint8_fromregion(&sr);
53 	isc_region_consume(&sr, 1);
54 	snprintf(buf, sizeof(buf), "%u ", n);
55 	RETERR(isc_str_tobuffer(buf, target));
56 
57 	/*
58 	 * Digest type.
59 	 */
60 	n = uint8_fromregion(&sr);
61 	isc_region_consume(&sr, 1);
62 	snprintf(buf, sizeof(buf), "%u", n);
63 	RETERR(isc_str_tobuffer(buf, target));
64 
65 	/*
66 	 * Digest.
67 	 */
68 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
69 		RETERR(isc_str_tobuffer(" (", target));
70 	RETERR(isc_str_tobuffer(tctx->linebreak, target));
71 	if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) {
72 		if (tctx->width == 0) /* No splitting */
73 			RETERR(isc_hex_totext(&sr, 0, "", target));
74 		else
75 			RETERR(isc_hex_totext(&sr, tctx->width - 2,
76 					      tctx->linebreak, target));
77 	} else
78 		RETERR(isc_str_tobuffer("[omitted]", target));
79 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
80 		RETERR(isc_str_tobuffer(" )", target));
81 	return (ISC_R_SUCCESS);
82 }
83 
84 static inline isc_result_t
totext_ds(ARGS_TOTEXT)85 totext_ds(ARGS_TOTEXT) {
86 
87 	REQUIRE(rdata->type == dns_rdatatype_ds);
88 
89 	return (generic_totext_ds(rdata, tctx, target));
90 }
91 
92 static inline isc_result_t
generic_fromwire_ds(ARGS_FROMWIRE)93 generic_fromwire_ds(ARGS_FROMWIRE) {
94 	isc_region_t sr;
95 
96 	UNUSED(type);
97 	UNUSED(rdclass);
98 	UNUSED(dctx);
99 	UNUSED(options);
100 
101 	isc_buffer_activeregion(source, &sr);
102 
103 	/*
104 	 * Check digest lengths if we know them.
105 	 */
106 	if (sr.length < 4 ||
107 	    (sr.base[3] == DNS_DSDIGEST_SHA1 &&
108 	     sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
109 	    (sr.base[3] == DNS_DSDIGEST_SHA256 &&
110 	     sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
111 	    (sr.base[3] == DNS_DSDIGEST_SHA384 &&
112 	     sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
113 		return (ISC_R_UNEXPECTEDEND);
114 
115 	/*
116 	 * Only copy digest lengths if we know them.
117 	 * If there is extra data dns_rdata_fromwire() will
118 	 * detect that.
119 	 */
120 	if (sr.base[3] == DNS_DSDIGEST_SHA1)
121 		sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
122 	else if (sr.base[3] == DNS_DSDIGEST_SHA256)
123 		sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
124 	else if (sr.base[3] == DNS_DSDIGEST_SHA384)
125 		sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
126 
127 	isc_buffer_forward(source, sr.length);
128 	return (isc_mem_tobuffer(target, sr.base, sr.length));
129 }
130 
131 static inline isc_result_t
fromwire_ds(ARGS_FROMWIRE)132 fromwire_ds(ARGS_FROMWIRE) {
133 
134 	REQUIRE(type == dns_rdatatype_ds);
135 
136 	return (generic_fromwire_ds(rdclass, type, source, dctx, options,
137 				    target));
138 }
139 
140 static inline isc_result_t
towire_ds(ARGS_TOWIRE)141 towire_ds(ARGS_TOWIRE) {
142 	isc_region_t sr;
143 
144 	REQUIRE(rdata->type == dns_rdatatype_ds);
145 	REQUIRE(rdata->length != 0);
146 
147 	UNUSED(cctx);
148 
149 	dns_rdata_toregion(rdata, &sr);
150 	return (isc_mem_tobuffer(target, sr.base, sr.length));
151 }
152 
153 #endif	/* RDATA_GENERIC_DS_43_C */
154