Home | History | Annotate | Line # | Download | only in dist
      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