xref: /netbsd/external/bsd/nsd/dist/tsig.h (revision 688d4060)
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