xref: /openbsd/usr.bin/dig/lib/dns/rdata/generic/key_25.c (revision 73471bf0)
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: key_25.c,v 1.13 2020/02/26 18:47:59 florian Exp $ */
18 
19 /*
20  * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
21  */
22 
23 /* RFC2535 */
24 
25 #ifndef RDATA_GENERIC_KEY_25_C
26 #define RDATA_GENERIC_KEY_25_C
27 
28 #include <dst/dst.h>
29 
30 static inline isc_result_t
31 generic_totext_key(ARGS_TOTEXT) {
32 	isc_region_t sr;
33 	char buf[sizeof("[key id = 64000]")];
34 	unsigned int flags;
35 	unsigned char algorithm;
36 	char algbuf[DNS_NAME_FORMATSIZE];
37 	const char *keyinfo;
38 	isc_region_t tmpr;
39 
40 	REQUIRE(rdata->length != 0);
41 
42 	dns_rdata_toregion(rdata, &sr);
43 
44 	/* flags */
45 	flags = uint16_fromregion(&sr);
46 	isc_region_consume(&sr, 2);
47 	snprintf(buf, sizeof(buf), "%u", flags);
48 	RETERR(isc_str_tobuffer(buf, target));
49 	RETERR(isc_str_tobuffer(" ", target));
50 	if ((flags & DNS_KEYFLAG_KSK) != 0) {
51 		if (flags & DNS_KEYFLAG_REVOKE)
52 			keyinfo = "revoked KSK";
53 		else
54 			keyinfo = "KSK";
55 	} else
56 		keyinfo = "ZSK";
57 
58 	/* protocol */
59 	snprintf(buf, sizeof(buf), "%u", sr.base[0]);
60 	isc_region_consume(&sr, 1);
61 	RETERR(isc_str_tobuffer(buf, target));
62 	RETERR(isc_str_tobuffer(" ", target));
63 
64 	/* algorithm */
65 	algorithm = sr.base[0];
66 	snprintf(buf, sizeof(buf), "%u", algorithm);
67 	isc_region_consume(&sr, 1);
68 	RETERR(isc_str_tobuffer(buf, target));
69 
70 	/* No Key? */
71 	if ((flags & 0xc000) == 0xc000)
72 		return (ISC_R_SUCCESS);
73 
74 	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
75 	     algorithm == DNS_KEYALG_PRIVATEDNS) {
76 		dns_name_t name;
77 		dns_name_init(&name, NULL);
78 		dns_name_fromregion(&name, &sr);
79 		dns_name_format(&name, algbuf, sizeof(algbuf));
80 	} else {
81 		dns_secalg_format((dns_secalg_t) algorithm, algbuf,
82 				  sizeof(algbuf));
83 	}
84 
85 	/* key */
86 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
87 		RETERR(isc_str_tobuffer(" (", target));
88 	RETERR(isc_str_tobuffer(tctx->linebreak, target));
89 
90 	if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) {
91 		if (tctx->width == 0)   /* No splitting */
92 			RETERR(isc_base64_totext(&sr, 60, "", target));
93 		else
94 			RETERR(isc_base64_totext(&sr, tctx->width - 2,
95 						 tctx->linebreak, target));
96 	} else {
97 		dns_rdata_toregion(rdata, &tmpr);
98 		snprintf(buf, sizeof(buf), "[key id = %u]",
99 			 dst_region_computeid(&tmpr, algorithm));
100 		RETERR(isc_str_tobuffer(buf, target));
101 	}
102 
103 	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0)
104 		RETERR(isc_str_tobuffer(tctx->linebreak, target));
105 	else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
106 		RETERR(isc_str_tobuffer(" ", target));
107 
108 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
109 		RETERR(isc_str_tobuffer(")", target));
110 
111 	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
112 
113 		if (rdata->type == dns_rdatatype_dnskey ||
114 		    rdata->type == dns_rdatatype_cdnskey) {
115 			RETERR(isc_str_tobuffer(" ; ", target));
116 			RETERR(isc_str_tobuffer(keyinfo, target));
117 		}
118 		RETERR(isc_str_tobuffer("; alg = ", target));
119 		RETERR(isc_str_tobuffer(algbuf, target));
120 		RETERR(isc_str_tobuffer(" ; key id = ", target));
121 		dns_rdata_toregion(rdata, &tmpr);
122 		snprintf(buf, sizeof(buf), "%u",
123 			 dst_region_computeid(&tmpr, algorithm));
124 		RETERR(isc_str_tobuffer(buf, target));
125 	}
126 	return (ISC_R_SUCCESS);
127 }
128 
129 static inline isc_result_t
130 generic_fromwire_key(ARGS_FROMWIRE) {
131 	unsigned char algorithm;
132 	isc_region_t sr;
133 
134 	UNUSED(type);
135 	UNUSED(rdclass);
136 	UNUSED(dctx);
137 	UNUSED(options);
138 
139 	isc_buffer_activeregion(source, &sr);
140 	if (sr.length < 4)
141 		return (ISC_R_UNEXPECTEDEND);
142 
143 	algorithm = sr.base[3];
144 	RETERR(isc_mem_tobuffer(target, sr.base, 4));
145 	isc_region_consume(&sr, 4);
146 	isc_buffer_forward(source, 4);
147 
148 	if (algorithm == DNS_KEYALG_PRIVATEDNS) {
149 		dns_name_t name;
150 		dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
151 		dns_name_init(&name, NULL);
152 		RETERR(dns_name_fromwire(&name, source, dctx, options, target));
153 	}
154 
155 	/*
156 	 * RSAMD5 computes key ID differently from other
157 	 * algorithms: we need to ensure there's enough data
158 	 * present for the computation
159 	 */
160 	if (algorithm == DST_ALG_RSAMD5 && sr.length < 3)
161 		return (ISC_R_UNEXPECTEDEND);
162 
163 	isc_buffer_activeregion(source, &sr);
164 	isc_buffer_forward(source, sr.length);
165 	return (isc_mem_tobuffer(target, sr.base, sr.length));
166 }
167 
168 static inline isc_result_t
169 totext_key(ARGS_TOTEXT) {
170 
171 	REQUIRE(rdata != NULL);
172 	REQUIRE(rdata->type == dns_rdatatype_key);
173 
174 	return (generic_totext_key(rdata, tctx, target));
175 }
176 
177 static inline isc_result_t
178 fromwire_key(ARGS_FROMWIRE) {
179 
180 	REQUIRE(type == dns_rdatatype_key);
181 
182 	return (generic_fromwire_key(rdclass, type, source, dctx,
183 				     options, target));
184 }
185 
186 static inline isc_result_t
187 towire_key(ARGS_TOWIRE) {
188 	isc_region_t sr;
189 
190 	REQUIRE(rdata != NULL);
191 	REQUIRE(rdata->type == dns_rdatatype_key);
192 	REQUIRE(rdata->length != 0);
193 
194 	UNUSED(cctx);
195 
196 	dns_rdata_toregion(rdata, &sr);
197 	return (isc_mem_tobuffer(target, sr.base, sr.length));
198 }
199 
200 #endif	/* RDATA_GENERIC_KEY_25_C */
201