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