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