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