1/*	$NetBSD$	*/
2
3/*
4 * Copyright (C) 2004-2007, 2009-2011  Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2002  Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20/* Id: tsig.h,v 1.59 2011/01/11 23:47:13 tbox Exp  */
21
22#ifndef DNS_TSIG_H
23#define DNS_TSIG_H 1
24
25/*! \file dns/tsig.h */
26
27#include <isc/lang.h>
28#include <isc/refcount.h>
29#include <isc/rwlock.h>
30#include <isc/stdio.h>
31#include <isc/stdtime.h>
32
33#include <dns/types.h>
34#include <dns/name.h>
35
36#include <dst/dst.h>
37
38/*
39 * Algorithms.
40 */
41LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacmd5_name;
42#define DNS_TSIG_HMACMD5_NAME		dns_tsig_hmacmd5_name
43LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapi_name;
44#define DNS_TSIG_GSSAPI_NAME		dns_tsig_gssapi_name
45LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapims_name;
46#define DNS_TSIG_GSSAPIMS_NAME		dns_tsig_gssapims_name
47LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha1_name;
48#define DNS_TSIG_HMACSHA1_NAME		dns_tsig_hmacsha1_name
49LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha224_name;
50#define DNS_TSIG_HMACSHA224_NAME	dns_tsig_hmacsha224_name
51LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha256_name;
52#define DNS_TSIG_HMACSHA256_NAME	dns_tsig_hmacsha256_name
53LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha384_name;
54#define DNS_TSIG_HMACSHA384_NAME	dns_tsig_hmacsha384_name
55LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name;
56#define DNS_TSIG_HMACSHA512_NAME	dns_tsig_hmacsha512_name
57
58/*%
59 * Default fudge value.
60 */
61#define DNS_TSIG_FUDGE			300
62
63struct dns_tsig_keyring {
64	dns_rbt_t *keys;
65	unsigned int writecount;
66	isc_rwlock_t lock;
67	isc_mem_t *mctx;
68	/*
69	 * LRU list of generated key along with a count of the keys on the
70	 * list and a maximum size.
71	 */
72	unsigned int generated;
73	unsigned int maxgenerated;
74	ISC_LIST(dns_tsigkey_t) lru;
75	unsigned int references;
76};
77
78struct dns_tsigkey {
79	/* Unlocked */
80	unsigned int		magic;		/*%< Magic number. */
81	isc_mem_t		*mctx;
82	dst_key_t		*key;		/*%< Key */
83	dns_name_t		name;		/*%< Key name */
84	dns_name_t		*algorithm;	/*%< Algorithm name */
85	dns_name_t		*creator;	/*%< name that created secret */
86	isc_boolean_t		generated;	/*%< was this generated? */
87	isc_stdtime_t		inception;	/*%< start of validity period */
88	isc_stdtime_t		expire;		/*%< end of validity period */
89	dns_tsig_keyring_t	*ring;		/*%< the enclosing keyring */
90	isc_refcount_t		refs;		/*%< reference counter */
91	ISC_LINK(dns_tsigkey_t) link;
92};
93
94#define dns_tsigkey_identity(tsigkey) \
95	((tsigkey) == NULL ? NULL : \
96	 (tsigkey)->generated ? ((tsigkey)->creator) : \
97	 (&((tsigkey)->name)))
98
99ISC_LANG_BEGINDECLS
100
101isc_result_t
102dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
103		   unsigned char *secret, int length, isc_boolean_t generated,
104		   dns_name_t *creator, isc_stdtime_t inception,
105		   isc_stdtime_t expire, isc_mem_t *mctx,
106		   dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
107
108isc_result_t
109dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
110			  dst_key_t *dstkey, isc_boolean_t generated,
111			  dns_name_t *creator, isc_stdtime_t inception,
112			  isc_stdtime_t expire, isc_mem_t *mctx,
113			  dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
114/*%<
115 *	Creates a tsig key structure and saves it in the keyring.  If key is
116 *	not NULL, *key will contain a copy of the key.  The keys validity
117 *	period is specified by (inception, expire), and will not expire if
118 *	inception == expire.  If the key was generated, the creating identity,
119 *	if there is one, should be in the creator parameter.  Specifying an
120 *	unimplemented algorithm will cause failure only if dstkey != NULL; this
121 *	allows a transient key with an invalid algorithm to exist long enough
122 *	to generate a BADKEY response.
123 *
124 *	If dns_tsigkey_createfromkey is successful a new reference to 'dstkey'
125 *	will have been made.
126 *
127 *	Requires:
128 *\li		'name' is a valid dns_name_t
129 *\li		'algorithm' is a valid dns_name_t
130 *\li		'secret' is a valid pointer
131 *\li		'length' is an integer >= 0
132 *\li		'dstkey' is a valid dst key or NULL
133 *\li		'creator' points to a valid dns_name_t or is NULL
134 *\li		'mctx' is a valid memory context
135 *\li		'ring' is a valid TSIG keyring or NULL
136 *\li		'key' or '*key' must be NULL
137 *
138 *	Returns:
139 *\li		#ISC_R_SUCCESS
140 *\li		#ISC_R_EXISTS - a key with this name already exists
141 *\li		#ISC_R_NOTIMPLEMENTED - algorithm is not implemented
142 *\li		#ISC_R_NOMEMORY
143 */
144
145void
146dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp);
147/*%<
148 *	Attach '*targetp' to 'source'.
149 *
150 *	Requires:
151 *\li		'key' is a valid TSIG key
152 *
153 *	Ensures:
154 *\li		*targetp is attached to source.
155 */
156
157void
158dns_tsigkey_detach(dns_tsigkey_t **keyp);
159/*%<
160 *	Detaches from the tsig key structure pointed to by '*key'.
161 *
162 *	Requires:
163 *\li		'keyp' is not NULL and '*keyp' is a valid TSIG key
164 *
165 *	Ensures:
166 *\li		'keyp' points to NULL
167 */
168
169void
170dns_tsigkey_setdeleted(dns_tsigkey_t *key);
171/*%<
172 *	Prevents this key from being used again.  It will be deleted when
173 *	no references exist.
174 *
175 *	Requires:
176 *\li		'key' is a valid TSIG key on a keyring
177 */
178
179isc_result_t
180dns_tsig_sign(dns_message_t *msg);
181/*%<
182 *	Generates a TSIG record for this message
183 *
184 *	Requires:
185 *\li		'msg' is a valid message
186 *\li		'msg->tsigkey' is a valid TSIG key
187 *\li		'msg->tsig' is NULL
188 *
189 *	Returns:
190 *\li		#ISC_R_SUCCESS
191 *\li		#ISC_R_NOMEMORY
192 *\li		#ISC_R_NOSPACE
193 *\li		#DNS_R_EXPECTEDTSIG
194 *			- this is a response & msg->querytsig is NULL
195 */
196
197isc_result_t
198dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
199		dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2);
200/*%<
201 *	Verifies the TSIG record in this message
202 *
203 *	Requires:
204 *\li		'source' is a valid buffer containing the unparsed message
205 *\li		'msg' is a valid message
206 *\li		'msg->tsigkey' is a valid TSIG key if this is a response
207 *\li		'msg->tsig' is NULL
208 *\li		'msg->querytsig' is not NULL if this is a response
209 *\li		'ring1' and 'ring2' are each either a valid keyring or NULL
210 *
211 *	Returns:
212 *\li		#ISC_R_SUCCESS
213 *\li		#ISC_R_NOMEMORY
214 *\li		#DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen
215 *\li		#DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected
216 *\li		#DNS_R_TSIGERRORSET - the TSIG verified but ->error was set
217 *				     and this is a query
218 *\li		#DNS_R_CLOCKSKEW - the TSIG failed to verify because of
219 *				  the time was out of the allowed range.
220 *\li		#DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify
221 *\li		#DNS_R_EXPECTEDRESPONSE - the message was set over TCP and
222 *					 should have been a response,
223 *					 but was not.
224 */
225
226isc_result_t
227dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
228		 dns_name_t *algorithm, dns_tsig_keyring_t *ring);
229/*%<
230 *	Returns the TSIG key corresponding to this name and (possibly)
231 *	algorithm.  Also increments the key's reference counter.
232 *
233 *	Requires:
234 *\li		'tsigkey' is not NULL
235 *\li		'*tsigkey' is NULL
236 *\li		'name' is a valid dns_name_t
237 *\li		'algorithm' is a valid dns_name_t or NULL
238 *\li		'ring' is a valid keyring
239 *
240 *	Returns:
241 *\li		#ISC_R_SUCCESS
242 *\li		#ISC_R_NOTFOUND
243 */
244
245
246isc_result_t
247dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp);
248/*%<
249 *	Create an empty TSIG key ring.
250 *
251 *	Requires:
252 *\li		'mctx' is not NULL
253 *\li		'ringp' is not NULL, and '*ringp' is NULL
254 *
255 *	Returns:
256 *\li		#ISC_R_SUCCESS
257 *\li		#ISC_R_NOMEMORY
258 */
259
260isc_result_t
261dns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
262		    dns_tsigkey_t *tkey);
263/*%<
264 *      Place a TSIG key onto a key ring.
265 *
266 *	Requires:
267 *\li		'ring', 'name' and 'tkey' are not NULL
268 *
269 *	Returns:
270 *\li		#ISC_R_SUCCESS
271 *\li		Any other value indicates failure.
272 */
273
274
275void
276dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target);
277
278void
279dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp);
280
281isc_result_t
282dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp);
283
284/*%<
285 *	Destroy a TSIG key ring.
286 *
287 *	Requires:
288 *\li		'ringp' is not NULL
289 */
290
291void
292dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp);
293
294ISC_LANG_ENDDECLS
295
296#endif /* DNS_TSIG_H */
297