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
generic_totext_key(ARGS_TOTEXT)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
generic_fromwire_key(ARGS_FROMWIRE)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
totext_key(ARGS_TOTEXT)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
fromwire_key(ARGS_FROMWIRE)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
towire_key(ARGS_TOWIRE)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