1 /*------------------------------------------------------------------------------
2  *
3  * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4  * The YADIFA TM software product is provided under the BSD 3-clause license:
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *        * Redistributions in binary form must reproduce the above copyright
13  *          notice, this list of conditions and the following disclaimer in the
14  *          documentation and/or other materials provided with the distribution.
15  *        * Neither the name of EURid nor the names of its contributors may be
16  *          used to endorse or promote products derived from this software
17  *          without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  *------------------------------------------------------------------------------
32  *
33  */
34 
35 /** @defgroup ### #######
36  *  @ingroup dnscore
37  *  @brief
38  *
39  * @{
40  */
41 
42 #ifndef TSIG_H_
43 #define TSIG_H_
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 
48 #include <dnscore/dnskey.h>
49 #include <dnscore/hmac.h>
50 
51 #if DNSCORE_HAS_TSIG_SUPPORT
52 
53 #ifdef	__cplusplus
54 extern "C"
55 {
56 #endif
57 
58 #define HMAC_UNKNOWN	  0
59 #define HMAC_MD5        157
60 #define HMAC_SHA1       161
61 #define HMAC_SHA224     162
62 #define HMAC_SHA256     163
63 #define HMAC_SHA384     164
64 #define HMAC_SHA512     165
65 
66 struct packet_unpack_reader_data;
67 
68 /*
69  * A digest is stored prefixed with its length ([1;255])
70  */
71 
72 /*
73  * A structure to hold both children with direct access
74  */
75 
76 typedef struct tsig_node tsig_node;
77 
78 struct tsig_children
79 {
80     struct tsig_node* left;
81     struct tsig_node* right;
82 };
83 
84 /*
85  * An union to have access to the children with direct or indexed access
86  */
87 
88 typedef union tsig_children_union tsig_children_union;
89 
90 union tsig_children_union
91 {
92     struct tsig_children lr;
93     struct tsig_node * child[2];
94 };
95 
96 typedef struct tsig_item tsig_item;
97 
98 struct tsig_item
99 {
100     const u8 *name;
101     const u8 *mac;
102     const u8 *mac_algorithm_name;
103     u16 name_len;
104     u16 mac_algorithm_name_len;
105     u16 mac_size;
106     u8 mac_algorithm;
107 
108     u8 load_serial;
109 };
110 
111 /*
112  * The node structure CANNOT have a varying size on a given collection
113  * This means that the digest size is a constant in the whole tree
114  */
115 
116 struct tsig_node
117 {
118     union tsig_children_union children;
119     tsig_item item;
120     s8 balance;
121 };
122 
123 /**
124  * Call this before a config reload
125  */
126 
127 void tsig_serial_next();
128 
129 /*
130  * I recommend setting a define to identify the C part of the template
131  * So it can be used to undefine what is not required anymore for every
132  * C file but that one.
133  *
134  */
135 
136 ya_result tsig_register(const u8 *name, const u8 *mac, u16 mac_size, u8 mac_algorithm);
137 
138 void tsig_finalize();
139 
140 tsig_item *tsig_get(const u8 *name);
141 
142 u32 tsig_get_count();
143 
144 tsig_item *tsig_get_at_index(s32 index);
145 
146 struct message_data;
147 
148 typedef enum
149 {
150     TSIG_NOWHERE = -1,
151     TSIG_START   =  0,
152     TSIG_MIDDLE  =  1,
153     TSIG_END     =  2,
154     TSIG_WHOLE   =  3
155 } tsig_tcp_message_position;
156 
157 /**
158  * Sign the first message_data of a tcp answer
159  */
160 
161 ya_result tsig_sign_tcp_first_message(struct message_data *mesg);
162 
163 /**
164  * Sign one of the "middle" message_data of a tcp answer
165  */
166 
167 ya_result tsig_sign_tcp_next_message(struct message_data *mesg);
168 
169 /**
170  * Sign the 100*Nth last message_data of a tcp answer
171  */
172 
173 ya_result tsig_sign_tcp_last_message(struct message_data *mesg);
174 
175 /**
176  * Calls the relevant sign tcp function
177  */
178 
179 ya_result tsig_sign_tcp_message(struct message_data *mesg, tsig_tcp_message_position pos);
180 
181 /**
182  * Sign the first message_data of a tcp answer
183  */
184 
185 ya_result tsig_sign_tcp_first_message(struct message_data *mesg);
186 
187 /**
188  * Sign one of the "middle" message_data of a tcp answer
189  */
190 
191 ya_result tsig_sign_tcp_next_message(struct message_data *mesg);
192 
193 /**
194  * Sign the 100*Nth last message_data of a tcp answer
195  */
196 
197 ya_result tsig_sign_tcp_last_message(struct message_data *mesg);
198 
199 /**
200  * Calls the relevant verify tcp function
201  */
202 
203 ya_result tsig_verify_tcp_first_message(struct message_data *mesg, const u8 *mac, u16 mac_size);
204 ya_result tsig_verify_tcp_next_message(struct message_data *mesg);
205 void tsig_verify_tcp_last_message(struct message_data *mesg);
206 
207 
208 void tsig_register_algorithms();
209 
210 ya_result tsig_get_hmac_algorithm_from_friendly_name(const char *hmacname);
211 
212 u8 tsig_get_algorithm(const u8 *name);
213 const u8* tsig_get_algorithm_name(u8 algorithm);
214 
215 /*
216  * Called by tsig_extract_and_process
217  * Processes the TSIG of the message, remove the TSIG from the message
218  * *mesg the message
219  * *purd the packet reader pointing to be start of the RDATA of the TSIG
220  * tsigname the dname of the TSIG
221  * tctr the TYPE-CLASS-TTL-RDATALEN of the TSIG
222  */
223 
224 // no verification whatsoever, use with care
225 ya_result tsig_process(struct message_data *mesg, struct packet_unpack_reader_data *purd, u32 tsig_offset, const tsig_item *tsig, struct type_class_ttl_rdlen *tctr);
226 
227 ya_result tsig_process_query(struct message_data *mesg, struct packet_unpack_reader_data *purd, u32 tsig_offset, u8 tsigname[MAX_DOMAIN_LENGTH], struct type_class_ttl_rdlen *tctr);
228 
229 ya_result tsig_process_answer(struct message_data *mesg, struct packet_unpack_reader_data *purd, u32 tsig_offset, struct type_class_ttl_rdlen *tctr);
230 
231 /*
232  * Search for the last
233  *
234  */
235 
236 ya_result tsig_extract_and_process(struct message_data *mesg);
237 
238 /**
239  * signs the message
240  * the tsig.tsig should be set
241  * the tsig fields must be set
242  *
243  */
244 
245 ya_result tsig_sign_answer(struct message_data *mesg);
246 
247 /**
248  * signs the message
249  * the tsig.tsig should be set
250  * the tsig fields should be clear
251  *
252  */
253 
254 ya_result tsig_sign_query(struct message_data *mesg);
255 
256 ya_result tsig_verify_answer(struct message_data *mesg, const u8 *mac, u16 mac_size);
257 
258 ya_result tsig_append_unsigned_error(struct message_data *mesg);
259 ya_result tsig_append_error(struct message_data *mesg);
260 
261 /**
262  * Removes the TSIG if any, setups the tsig fields of the message.
263  *
264  * Returns 1 if a TSIG has been processed.
265  * Returns 0 if none were found.
266  */
267 
268 ya_result tsig_message_extract(struct message_data *mesg);
269 
270 #ifdef	__cplusplus
271 }
272 #endif
273 
274 #endif /* TSIG support */
275 
276 #endif /* TSIG_H_ */
277 
278 /** @} */
279