1 /* 2 * tsig.h -- TSIG definitions (RFC 2845). 3 * 4 * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #ifndef _TSIG_H_ 11 #define _TSIG_H_ 12 13 #include <sys/types.h> 14 #include <sys/socket.h> 15 #include <netdb.h> 16 17 #include "buffer.h" 18 #include "dname.h" 19 20 #define TSIG_ERROR_NOERROR 0 21 #define TSIG_ERROR_BADSIG 16 22 #define TSIG_ERROR_BADKEY 17 23 #define TSIG_ERROR_BADTIME 18 24 25 #define TSIG_HMAC_MD5 157 26 #define TSIG_HMAC_SHA1 158 27 #define TSIG_HMAC_SHA256 159 28 29 typedef struct tsig_algorithm tsig_algorithm_type; 30 typedef struct tsig_key tsig_key_type; 31 typedef struct tsig_record tsig_record_type; 32 33 enum tsig_status 34 { 35 TSIG_NOT_PRESENT, 36 TSIG_OK, 37 TSIG_ERROR 38 }; 39 typedef enum tsig_status tsig_status_type; 40 41 struct tsig_lookup_struct_table 42 { 43 uint8_t id; 44 const char* short_name; 45 }; 46 typedef struct tsig_lookup_struct_table tsig_lookup_algorithm_table; 47 48 /* 49 * A TSIG HMAC algorithm, such as hmac-md5. 50 */ 51 struct tsig_algorithm 52 { 53 /* 54 * Short name of the algorithm, such as "hmac-md5". 55 */ 56 const char *short_name; 57 58 /* 59 * Full wireformat name of the algorithm, such as 60 * "hmac-md5.sig-alg.reg.int." 61 */ 62 const dname_type *wireformat_name; 63 64 /* 65 * The maximum size of a digest generated by this algorithm. 66 */ 67 size_t maximum_digest_size; 68 69 /* 70 * Algorithm implementation specific data. 71 */ 72 const void *data; 73 74 /* 75 * Create a new HMAC context. 76 */ 77 void *(*hmac_create_context)(region_type *region); 78 79 /* 80 * Initialize an HMAC context with the specified algorithm and 81 * key. 82 */ 83 void (*hmac_init_context)(void *context, 84 tsig_algorithm_type *algorithm, 85 tsig_key_type *key); 86 87 /* 88 * Update the HMAC context with the specified data. 89 */ 90 void (*hmac_update)(void *context, const void *data, size_t size); 91 92 /* 93 * Generate the final digest. DIGEST points to a buffer of at 94 * least maximum_digest_size bytes. 95 */ 96 void (*hmac_final)(void *context, uint8_t *digest, size_t *size); 97 }; 98 99 /* 100 * A TSIG key used to sign and verify packets. 101 */ 102 struct tsig_key 103 { 104 const dname_type *name; 105 size_t size; 106 const uint8_t *data; 107 }; 108 109 struct tsig_record 110 { 111 tsig_status_type status; 112 size_t position; 113 size_t response_count; 114 size_t updates_since_last_prepare; 115 void *context; 116 tsig_algorithm_type *algorithm; 117 tsig_key_type *key; 118 size_t prior_mac_size; 119 uint8_t *prior_mac_data; 120 121 /* TSIG RR data is allocated in the rr_region. */ 122 region_type *rr_region; 123 region_type *context_region; 124 const dname_type *key_name; 125 const dname_type *algorithm_name; 126 uint16_t signed_time_high; 127 uint32_t signed_time_low; 128 uint16_t signed_time_fudge; 129 uint16_t mac_size; 130 uint8_t *mac_data; 131 uint16_t original_query_id; 132 uint16_t error_code; 133 uint16_t other_size; 134 uint8_t *other_data; 135 }; 136 137 /* 138 * Initialize the TSIG module (including TSIG implementation modules 139 * such as tsig-openssl). 140 */ 141 int tsig_init(region_type *region); 142 143 /* 144 * Add the specified key to the TSIG key table. 145 */ 146 void tsig_add_key(tsig_key_type *key); 147 148 /* 149 * Add the specified algorithm to the TSIG algorithm table. 150 */ 151 void tsig_add_algorithm(tsig_algorithm_type *algorithm); 152 153 /* 154 * Find an HMAC algorithm based on its short name. 155 */ 156 tsig_algorithm_type *tsig_get_algorithm_by_name(const char *name); 157 158 /* 159 * Find an HMAC algorithm based on its identifier. 160 */ 161 tsig_algorithm_type *tsig_get_algorithm_by_id(uint8_t alg); 162 163 /* 164 * Return a descriptive error message based on the TSIG error code. 165 */ 166 const char *tsig_error(int error_code); 167 168 /* 169 * Create the tsig record internal structure. Allocs it. 170 * Call init_record afterwards before doing more with it. 171 * 172 * The region is used to attach a cleanup function that destroys the tsig. 173 */ 174 void tsig_create_record(tsig_record_type* tsig, 175 region_type* region); 176 177 /* 178 * Like tsig_create_record, with custom region settings. 179 * The size params are used to customise the rr_region and context_region. 180 */ 181 void tsig_create_record_custom(tsig_record_type* tsig, 182 region_type* region, 183 size_t chunk_size, 184 size_t large_object_size, 185 size_t initial_cleanup_size); 186 187 /* 188 * Call this before starting to analyze or signing a sequence of 189 * packets. 190 * 191 * ALGORITHM and KEY are optional and are only needed if you want to 192 * sign the initial query. Otherwise the key and algorithm are looked 193 * up in the algorithm and key table when a received TSIG RR is 194 * processed. 195 */ 196 void tsig_init_record(tsig_record_type *data, 197 tsig_algorithm_type *algorithm, 198 tsig_key_type *key); 199 200 /* 201 * Validate the TSIG RR key and algorithm from the TSIG RR. Otherwise 202 * update the TSIG error code. The MAC itself is not validated. 203 * 204 * Returns non-zero if the key and algorithm could be validated. 205 */ 206 int tsig_from_query(tsig_record_type *tsig); 207 208 /* 209 * Prepare TSIG for signing of a query. This initializes TSIG with 210 * the algorithm and key stored in the TSIG record. 211 */ 212 void tsig_init_query(tsig_record_type *tsig, uint16_t original_query_id); 213 214 /* 215 * Prepare TSIG for performing an HMAC calculation. If the TSIG 216 * contains a prior HMAC it is inserted first into the hash 217 * calculation. 218 */ 219 void tsig_prepare(tsig_record_type *tsig); 220 221 /* 222 * Add the first LENGTH octets of PACKET to the TSIG hash, replacing 223 * the PACKET's id with the original query id from TSIG. If the query 224 * is a response the TSIG response count is incremented. 225 */ 226 void tsig_update(tsig_record_type *tsig, buffer_type *packet, size_t length); 227 228 /* 229 * Finalize the TSIG record by hashing the TSIG data. If the TSIG 230 * response count is greater than 1 only the timers are hashed. 231 * Signed time is set to the current time. The TSIG record can be 232 * added to a packet using tsig_append_rr(). 233 * 234 * The calculated MAC is also stored as the prior MAC, so it can be 235 * used as a running MAC. 236 */ 237 void tsig_sign(tsig_record_type *tsig); 238 239 /* 240 * Verify the calculated MAC against the MAC in the TSIG RR. 241 * 242 * The calculated MAC is also stored as the prior MAC, so it can be 243 * used as a running MAC. 244 */ 245 int tsig_verify(tsig_record_type *tsig); 246 247 /* 248 * Find the TSIG RR in QUERY and parse it if present. Store the 249 * parsed results in TSIG. 250 * 251 * Returns non-zero if no parsing error occurred, use the tsig->status 252 * field to find out if the TSIG record was present. 253 */ 254 int tsig_find_rr(tsig_record_type *tsig, buffer_type *packet); 255 256 /* 257 * Call this to analyze the TSIG RR starting at the current location 258 * of PACKET. On success true is returned and the results are stored 259 * in TSIG. 260 * 261 * Returns non-zero if no parsing error occurred, use the tsig->status 262 * field to find out if the TSIG record was present. 263 */ 264 int tsig_parse_rr(tsig_record_type *tsig, buffer_type *packet); 265 266 /* 267 * Append the TSIG record to the response PACKET. 268 */ 269 void tsig_append_rr(tsig_record_type *tsig, buffer_type *packet); 270 271 /* 272 * The amount of space to reserve in the response for the TSIG data 273 * (if required). 274 */ 275 size_t tsig_reserved_space(tsig_record_type *tsig); 276 277 /* 278 * status or error_code must already be in error. 279 * prepares content for error packet. 280 */ 281 void tsig_error_reply(tsig_record_type *tsig); 282 283 /* 284 * compare tsig algorithm names case insensitive. 285 */ 286 int tsig_strlowercmp(const char* str1, const char* str2); 287 288 /* 289 * cleanup tsig openssl stuff. 290 */ 291 void tsig_finalize(void); 292 293 #endif /* _TSIG_H_ */ 294