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: hip_55.c,v 1.15 2020/09/14 08:40:43 florian Exp $ */
18
19 /* reviewed: TBC */
20
21 /* RFC 5205 */
22
23 #ifndef RDATA_GENERIC_HIP_5_C
24 #define RDATA_GENERIC_HIP_5_C
25
26 static inline isc_result_t
totext_hip(ARGS_TOTEXT)27 totext_hip(ARGS_TOTEXT) {
28 isc_region_t region;
29 dns_name_t name;
30 unsigned int length, key_len, hit_len;
31 unsigned char algorithm;
32 char buf[sizeof("225 ")];
33
34 REQUIRE(rdata->type == dns_rdatatype_hip);
35 REQUIRE(rdata->length != 0);
36
37 dns_rdata_toregion(rdata, ®ion);
38
39 hit_len = uint8_fromregion(®ion);
40 isc_region_consume(®ion, 1);
41
42 algorithm = uint8_fromregion(®ion);
43 isc_region_consume(®ion, 1);
44
45 key_len = uint16_fromregion(®ion);
46 isc_region_consume(®ion, 2);
47
48 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
49 RETERR(isc_str_tobuffer("( ", target));
50
51 /*
52 * Algorithm
53 */
54 snprintf(buf, sizeof(buf), "%u ", algorithm);
55 RETERR(isc_str_tobuffer(buf, target));
56
57 /*
58 * HIT.
59 */
60 INSIST(hit_len < region.length);
61 length = region.length;
62 region.length = hit_len;
63 RETERR(isc_hex_totext(®ion, 1, "", target));
64 region.length = length - hit_len;
65 RETERR(isc_str_tobuffer(tctx->linebreak, target));
66
67 /*
68 * Public KEY.
69 */
70 INSIST(key_len <= region.length);
71 length = region.length;
72 region.length = key_len;
73 RETERR(isc_base64_totext(®ion, 1, "", target));
74 region.length = length - key_len;
75 RETERR(isc_str_tobuffer(tctx->linebreak, target));
76
77 /*
78 * Rendezvous Servers.
79 */
80 dns_name_init(&name, NULL);
81 while (region.length > 0) {
82 dns_name_fromregion(&name, ®ion);
83
84 RETERR(dns_name_totext(&name, 0, target));
85 isc_region_consume(®ion, name.length);
86 if (region.length > 0)
87 RETERR(isc_str_tobuffer(tctx->linebreak, target));
88 }
89 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
90 RETERR(isc_str_tobuffer(" )", target));
91 return (ISC_R_SUCCESS);
92 }
93
94 static inline isc_result_t
fromwire_hip(ARGS_FROMWIRE)95 fromwire_hip(ARGS_FROMWIRE) {
96 isc_region_t region, rr;
97 dns_name_t name;
98 uint8_t hit_len;
99 uint16_t key_len;
100
101 REQUIRE(type == dns_rdatatype_hip);
102
103 UNUSED(type);
104 UNUSED(rdclass);
105
106 isc_buffer_activeregion(source, ®ion);
107 if (region.length < 4U)
108 return (DNS_R_FORMERR);
109
110 rr = region;
111 hit_len = uint8_fromregion(®ion);
112 if (hit_len == 0)
113 return (DNS_R_FORMERR);
114 isc_region_consume(®ion, 2); /* hit length + algorithm */
115 key_len = uint16_fromregion(®ion);
116 if (key_len == 0)
117 return (DNS_R_FORMERR);
118 isc_region_consume(®ion, 2);
119 if (region.length < (unsigned) (hit_len + key_len))
120 return (DNS_R_FORMERR);
121
122 RETERR(isc_mem_tobuffer(target, rr.base, 4 + hit_len + key_len));
123 isc_buffer_forward(source, 4 + hit_len + key_len);
124
125 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
126 while (isc_buffer_activelength(source) > 0) {
127 dns_name_init(&name, NULL);
128 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
129 }
130 return (ISC_R_SUCCESS);
131 }
132
133 static inline isc_result_t
towire_hip(ARGS_TOWIRE)134 towire_hip(ARGS_TOWIRE) {
135 isc_region_t region;
136
137 REQUIRE(rdata->type == dns_rdatatype_hip);
138 REQUIRE(rdata->length != 0);
139
140 UNUSED(cctx);
141
142 dns_rdata_toregion(rdata, ®ion);
143 return (isc_mem_tobuffer(target, region.base, region.length));
144 }
145 #endif /* RDATA_GENERIC_HIP_5_C */
146