xref: /openbsd/usr.bin/dig/lib/dns/rdata/generic/hip_55.c (revision abb8b8a3)
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.11 2020/02/26 18:38:15 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
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, &region);
38 
39 	hit_len = uint8_fromregion(&region);
40 	isc_region_consume(&region, 1);
41 
42 	algorithm = uint8_fromregion(&region);
43 	isc_region_consume(&region, 1);
44 
45 	key_len = uint16_fromregion(&region);
46 	isc_region_consume(&region, 2);
47 
48 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
49 		RETERR(str_totext("( ", target));
50 
51 	/*
52 	 * Algorithm
53 	 */
54 	snprintf(buf, sizeof(buf), "%u ", algorithm);
55 	RETERR(str_totext(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(&region, 1, "", target));
64 	region.length = length - hit_len;
65 	RETERR(str_totext(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(&region, 1, "", target));
74 	region.length = length - key_len;
75 	RETERR(str_totext(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, &region);
83 
84 		RETERR(dns_name_totext(&name, ISC_FALSE, target));
85 		isc_region_consume(&region, name.length);
86 		if (region.length > 0)
87 			RETERR(str_totext(tctx->linebreak, target));
88 	}
89 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
90 		RETERR(str_totext(" )", target));
91 	return (ISC_R_SUCCESS);
92 }
93 
94 static inline isc_result_t
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, &region);
107 	if (region.length < 4U)
108 		RETERR(DNS_R_FORMERR);
109 
110 	rr = region;
111 	hit_len = uint8_fromregion(&region);
112 	if (hit_len == 0)
113 		RETERR(DNS_R_FORMERR);
114 	isc_region_consume(&region, 2);  	/* hit length + algorithm */
115 	key_len = uint16_fromregion(&region);
116 	if (key_len == 0)
117 		RETERR(DNS_R_FORMERR);
118 	isc_region_consume(&region, 2);
119 	if (region.length < (unsigned) (hit_len + key_len))
120 		RETERR(DNS_R_FORMERR);
121 
122 	RETERR(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
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, &region);
143 	return (mem_tobuffer(target, region.base, region.length));
144 }
145 #endif	/* RDATA_GENERIC_HIP_5_C */
146