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