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: tsig_250.c,v 1.10 2020/09/14 08:40:43 florian Exp $ */
18
19 /* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */
20
21 #ifndef RDATA_ANY_255_TSIG_250_C
22 #define RDATA_ANY_255_TSIG_250_C
23
24 static inline isc_result_t
totext_any_tsig(ARGS_TOTEXT)25 totext_any_tsig(ARGS_TOTEXT) {
26 isc_region_t sr;
27 isc_region_t sigr;
28 char buf[sizeof(" 281474976710655 ")];
29 char *bufp;
30 dns_name_t name;
31 dns_name_t prefix;
32 int sub;
33 uint64_t sigtime;
34 unsigned short n;
35
36 REQUIRE(rdata->type == dns_rdatatype_tsig);
37 REQUIRE(rdata->rdclass == dns_rdataclass_any);
38 REQUIRE(rdata->length != 0);
39
40 dns_rdata_toregion(rdata, &sr);
41 /*
42 * Algorithm Name.
43 */
44 dns_name_init(&name, NULL);
45 dns_name_init(&prefix, NULL);
46 dns_name_fromregion(&name, &sr);
47 sub = name_prefix(&name, tctx->origin, &prefix);
48 RETERR(dns_name_totext(&prefix, sub, target));
49 RETERR(isc_str_tobuffer(" ", target));
50 isc_region_consume(&sr, name_length(&name));
51
52 /*
53 * Time Signed.
54 */
55 sigtime = ((uint64_t)sr.base[0] << 40) |
56 ((uint64_t)sr.base[1] << 32) |
57 ((uint64_t)sr.base[2] << 24) |
58 ((uint64_t)sr.base[3] << 16) |
59 ((uint64_t)sr.base[4] << 8) |
60 (uint64_t)sr.base[5];
61 isc_region_consume(&sr, 6);
62 bufp = &buf[sizeof(buf) - 1];
63 *bufp-- = 0;
64 *bufp-- = ' ';
65 do {
66 *bufp-- = decdigits[sigtime % 10];
67 sigtime /= 10;
68 } while (sigtime != 0);
69 bufp++;
70 RETERR(isc_str_tobuffer(bufp, target));
71
72 /*
73 * Fudge.
74 */
75 n = uint16_fromregion(&sr);
76 isc_region_consume(&sr, 2);
77 snprintf(buf, sizeof(buf), "%u ", n);
78 RETERR(isc_str_tobuffer(buf, target));
79
80 /*
81 * Signature Size.
82 */
83 n = uint16_fromregion(&sr);
84 isc_region_consume(&sr, 2);
85 snprintf(buf, sizeof(buf), "%u", n);
86 RETERR(isc_str_tobuffer(buf, target));
87
88 /*
89 * Signature.
90 */
91 REQUIRE(n <= sr.length);
92 sigr = sr;
93 sigr.length = n;
94 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
95 RETERR(isc_str_tobuffer(" (", target));
96 RETERR(isc_str_tobuffer(tctx->linebreak, target));
97 if (tctx->width == 0) /* No splitting */
98 RETERR(isc_base64_totext(&sigr, 60, "", target));
99 else
100 RETERR(isc_base64_totext(&sigr, tctx->width - 2,
101 tctx->linebreak, target));
102 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
103 RETERR(isc_str_tobuffer(" ) ", target));
104 else
105 RETERR(isc_str_tobuffer(" ", target));
106 isc_region_consume(&sr, n);
107
108 /*
109 * Original ID.
110 */
111 n = uint16_fromregion(&sr);
112 isc_region_consume(&sr, 2);
113 snprintf(buf, sizeof(buf), "%u ", n);
114 RETERR(isc_str_tobuffer(buf, target));
115
116 /*
117 * Error.
118 */
119 n = uint16_fromregion(&sr);
120 isc_region_consume(&sr, 2);
121 RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target));
122
123 /*
124 * Other Size.
125 */
126 n = uint16_fromregion(&sr);
127 isc_region_consume(&sr, 2);
128 snprintf(buf, sizeof(buf), " %u ", n);
129 RETERR(isc_str_tobuffer(buf, target));
130
131 /*
132 * Other.
133 */
134 if (tctx->width == 0) /* No splitting */
135 return (isc_base64_totext(&sr, 60, "", target));
136 else
137 return (isc_base64_totext(&sr, 60, " ", target));
138 }
139
140 static inline isc_result_t
fromwire_any_tsig(ARGS_FROMWIRE)141 fromwire_any_tsig(ARGS_FROMWIRE) {
142 isc_region_t sr;
143 dns_name_t name;
144 unsigned long n;
145
146 REQUIRE(type == dns_rdatatype_tsig);
147 REQUIRE(rdclass == dns_rdataclass_any);
148
149 UNUSED(type);
150 UNUSED(rdclass);
151
152 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
153
154 /*
155 * Algorithm Name.
156 */
157 dns_name_init(&name, NULL);
158 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
159
160 isc_buffer_activeregion(source, &sr);
161 /*
162 * Time Signed + Fudge.
163 */
164 if (sr.length < 8)
165 return (ISC_R_UNEXPECTEDEND);
166 RETERR(isc_mem_tobuffer(target, sr.base, 8));
167 isc_region_consume(&sr, 8);
168 isc_buffer_forward(source, 8);
169
170 /*
171 * Signature Length + Signature.
172 */
173 if (sr.length < 2)
174 return (ISC_R_UNEXPECTEDEND);
175 n = uint16_fromregion(&sr);
176 if (sr.length < n + 2)
177 return (ISC_R_UNEXPECTEDEND);
178 RETERR(isc_mem_tobuffer(target, sr.base, n + 2));
179 isc_region_consume(&sr, n + 2);
180 isc_buffer_forward(source, n + 2);
181
182 /*
183 * Original ID + Error.
184 */
185 if (sr.length < 4)
186 return (ISC_R_UNEXPECTEDEND);
187 RETERR(isc_mem_tobuffer(target, sr.base, 4));
188 isc_region_consume(&sr, 4);
189 isc_buffer_forward(source, 4);
190
191 /*
192 * Other Length + Other.
193 */
194 if (sr.length < 2)
195 return (ISC_R_UNEXPECTEDEND);
196 n = uint16_fromregion(&sr);
197 if (sr.length < n + 2)
198 return (ISC_R_UNEXPECTEDEND);
199 isc_buffer_forward(source, n + 2);
200 return (isc_mem_tobuffer(target, sr.base, n + 2));
201 }
202
203 static inline isc_result_t
towire_any_tsig(ARGS_TOWIRE)204 towire_any_tsig(ARGS_TOWIRE) {
205 isc_region_t sr;
206 dns_name_t name;
207 dns_offsets_t offsets;
208
209 REQUIRE(rdata->type == dns_rdatatype_tsig);
210 REQUIRE(rdata->rdclass == dns_rdataclass_any);
211 REQUIRE(rdata->length != 0);
212
213 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
214 dns_rdata_toregion(rdata, &sr);
215 dns_name_init(&name, offsets);
216 dns_name_fromregion(&name, &sr);
217 RETERR(dns_name_towire(&name, cctx, target));
218 isc_region_consume(&sr, name_length(&name));
219 return (isc_mem_tobuffer(target, sr.base, sr.length));
220 }
221
222 static inline isc_result_t
fromstruct_any_tsig(ARGS_FROMSTRUCT)223 fromstruct_any_tsig(ARGS_FROMSTRUCT) {
224 dns_rdata_any_tsig_t *tsig = source;
225 isc_region_t tr;
226
227 REQUIRE(type == dns_rdatatype_tsig);
228 REQUIRE(rdclass == dns_rdataclass_any);
229 REQUIRE(source != NULL);
230 REQUIRE(tsig->common.rdclass == rdclass);
231 REQUIRE(tsig->common.rdtype == type);
232
233 UNUSED(type);
234 UNUSED(rdclass);
235
236 /*
237 * Algorithm Name.
238 */
239 RETERR(name_tobuffer(&tsig->algorithm, target));
240
241 isc_buffer_availableregion(target, &tr);
242 if (tr.length < 6 + 2 + 2)
243 return (ISC_R_NOSPACE);
244
245 /*
246 * Time Signed: 48 bits.
247 */
248 RETERR(uint16_tobuffer((uint16_t)(tsig->timesigned >> 32),
249 target));
250 RETERR(uint32_tobuffer((uint32_t)(tsig->timesigned & 0xffffffffU),
251 target));
252
253 /*
254 * Fudge.
255 */
256 RETERR(uint16_tobuffer(tsig->fudge, target));
257
258 /*
259 * Signature Size.
260 */
261 RETERR(uint16_tobuffer(tsig->siglen, target));
262
263 /*
264 * Signature.
265 */
266 RETERR(isc_mem_tobuffer(target, tsig->signature, tsig->siglen));
267
268 isc_buffer_availableregion(target, &tr);
269 if (tr.length < 2 + 2 + 2)
270 return (ISC_R_NOSPACE);
271
272 /*
273 * Original ID.
274 */
275 RETERR(uint16_tobuffer(tsig->originalid, target));
276
277 /*
278 * Error.
279 */
280 RETERR(uint16_tobuffer(tsig->error, target));
281
282 /*
283 * Other Len.
284 */
285 RETERR(uint16_tobuffer(tsig->otherlen, target));
286
287 /*
288 * Other Data.
289 */
290 return (isc_mem_tobuffer(target, tsig->other, tsig->otherlen));
291 }
292
293 static inline isc_result_t
tostruct_any_tsig(ARGS_TOSTRUCT)294 tostruct_any_tsig(ARGS_TOSTRUCT) {
295 dns_rdata_any_tsig_t *tsig;
296 dns_name_t alg;
297 isc_region_t sr;
298
299 REQUIRE(rdata->type == dns_rdatatype_tsig);
300 REQUIRE(rdata->rdclass == dns_rdataclass_any);
301 REQUIRE(rdata->length != 0);
302
303 tsig = (dns_rdata_any_tsig_t *) target;
304 tsig->common.rdclass = rdata->rdclass;
305 tsig->common.rdtype = rdata->type;
306 ISC_LINK_INIT(&tsig->common, link);
307
308 dns_rdata_toregion(rdata, &sr);
309
310 /*
311 * Algorithm Name.
312 */
313 dns_name_init(&alg, NULL);
314 dns_name_fromregion(&alg, &sr);
315 dns_name_init(&tsig->algorithm, NULL);
316 RETERR(name_duporclone(&alg, &tsig->algorithm));
317
318 isc_region_consume(&sr, name_length(&tsig->algorithm));
319
320 /*
321 * Time Signed.
322 */
323 INSIST(sr.length >= 6);
324 tsig->timesigned = ((uint64_t)sr.base[0] << 40) |
325 ((uint64_t)sr.base[1] << 32) |
326 ((uint64_t)sr.base[2] << 24) |
327 ((uint64_t)sr.base[3] << 16) |
328 ((uint64_t)sr.base[4] << 8) |
329 (uint64_t)sr.base[5];
330 isc_region_consume(&sr, 6);
331
332 /*
333 * Fudge.
334 */
335 tsig->fudge = uint16_fromregion(&sr);
336 isc_region_consume(&sr, 2);
337
338 /*
339 * Signature Size.
340 */
341 tsig->siglen = uint16_fromregion(&sr);
342 isc_region_consume(&sr, 2);
343
344 /*
345 * Signature.
346 */
347 INSIST(sr.length >= tsig->siglen);
348 tsig->signature = mem_maybedup(sr.base, tsig->siglen);
349 if (tsig->signature == NULL)
350 goto cleanup;
351 isc_region_consume(&sr, tsig->siglen);
352
353 /*
354 * Original ID.
355 */
356 tsig->originalid = uint16_fromregion(&sr);
357 isc_region_consume(&sr, 2);
358
359 /*
360 * Error.
361 */
362 tsig->error = uint16_fromregion(&sr);
363 isc_region_consume(&sr, 2);
364
365 /*
366 * Other Size.
367 */
368 tsig->otherlen = uint16_fromregion(&sr);
369 isc_region_consume(&sr, 2);
370
371 /*
372 * Other.
373 */
374 INSIST(sr.length == tsig->otherlen);
375 tsig->other = mem_maybedup(sr.base, tsig->otherlen);
376 if (tsig->other == NULL)
377 goto cleanup;
378
379 return (ISC_R_SUCCESS);
380
381 cleanup:
382 dns_name_free(&tsig->algorithm);
383 free(tsig->signature);
384 return (ISC_R_NOMEMORY);
385 }
386
387 static inline void
freestruct_any_tsig(ARGS_FREESTRUCT)388 freestruct_any_tsig(ARGS_FREESTRUCT) {
389 dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *) source;
390
391 REQUIRE(source != NULL);
392 REQUIRE(tsig->common.rdtype == dns_rdatatype_tsig);
393 REQUIRE(tsig->common.rdclass == dns_rdataclass_any);
394
395 dns_name_free(&tsig->algorithm);
396 free(tsig->signature);
397 free(tsig->other);
398 }
399
400 #endif /* RDATA_ANY_255_TSIG_250_C */
401