1135446Strhodes/*
2224092Sdougb * Copyright (C) 2004-2007, 2009-2011  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1999-2002  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18234010Sdougb/* $Id: tsig.h,v 1.59 2011/01/11 23:47:13 tbox Exp $ */
19135446Strhodes
20135446Strhodes#ifndef DNS_TSIG_H
21135446Strhodes#define DNS_TSIG_H 1
22135446Strhodes
23193149Sdougb/*! \file dns/tsig.h */
24170222Sdougb
25135446Strhodes#include <isc/lang.h>
26135446Strhodes#include <isc/refcount.h>
27135446Strhodes#include <isc/rwlock.h>
28224092Sdougb#include <isc/stdio.h>
29135446Strhodes#include <isc/stdtime.h>
30135446Strhodes
31135446Strhodes#include <dns/types.h>
32135446Strhodes#include <dns/name.h>
33135446Strhodes
34135446Strhodes#include <dst/dst.h>
35135446Strhodes
36135446Strhodes/*
37135446Strhodes * Algorithms.
38135446Strhodes */
39135446StrhodesLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacmd5_name;
40135446Strhodes#define DNS_TSIG_HMACMD5_NAME		dns_tsig_hmacmd5_name
41135446StrhodesLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapi_name;
42135446Strhodes#define DNS_TSIG_GSSAPI_NAME		dns_tsig_gssapi_name
43135446StrhodesLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapims_name;
44135446Strhodes#define DNS_TSIG_GSSAPIMS_NAME		dns_tsig_gssapims_name
45170222SdougbLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha1_name;
46170222Sdougb#define DNS_TSIG_HMACSHA1_NAME		dns_tsig_hmacsha1_name
47170222SdougbLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha224_name;
48170222Sdougb#define DNS_TSIG_HMACSHA224_NAME	dns_tsig_hmacsha224_name
49170222SdougbLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha256_name;
50170222Sdougb#define DNS_TSIG_HMACSHA256_NAME	dns_tsig_hmacsha256_name
51170222SdougbLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha384_name;
52170222Sdougb#define DNS_TSIG_HMACSHA384_NAME	dns_tsig_hmacsha384_name
53170222SdougbLIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name;
54170222Sdougb#define DNS_TSIG_HMACSHA512_NAME	dns_tsig_hmacsha512_name
55135446Strhodes
56170222Sdougb/*%
57135446Strhodes * Default fudge value.
58135446Strhodes */
59135446Strhodes#define DNS_TSIG_FUDGE			300
60135446Strhodes
61135446Strhodesstruct dns_tsig_keyring {
62135446Strhodes	dns_rbt_t *keys;
63193149Sdougb	unsigned int writecount;
64135446Strhodes	isc_rwlock_t lock;
65135446Strhodes	isc_mem_t *mctx;
66218384Sdougb	/*
67218384Sdougb	 * LRU list of generated key along with a count of the keys on the
68218384Sdougb	 * list and a maximum size.
69218384Sdougb	 */
70218384Sdougb	unsigned int generated;
71218384Sdougb	unsigned int maxgenerated;
72218384Sdougb	ISC_LIST(dns_tsigkey_t) lru;
73224092Sdougb	unsigned int references;
74135446Strhodes};
75135446Strhodes
76135446Strhodesstruct dns_tsigkey {
77135446Strhodes	/* Unlocked */
78170222Sdougb	unsigned int		magic;		/*%< Magic number. */
79135446Strhodes	isc_mem_t		*mctx;
80170222Sdougb	dst_key_t		*key;		/*%< Key */
81170222Sdougb	dns_name_t		name;		/*%< Key name */
82170222Sdougb	dns_name_t		*algorithm;	/*%< Algorithm name */
83170222Sdougb	dns_name_t		*creator;	/*%< name that created secret */
84170222Sdougb	isc_boolean_t		generated;	/*%< was this generated? */
85170222Sdougb	isc_stdtime_t		inception;	/*%< start of validity period */
86170222Sdougb	isc_stdtime_t		expire;		/*%< end of validity period */
87170222Sdougb	dns_tsig_keyring_t	*ring;		/*%< the enclosing keyring */
88170222Sdougb	isc_refcount_t		refs;		/*%< reference counter */
89218384Sdougb	ISC_LINK(dns_tsigkey_t) link;
90135446Strhodes};
91135446Strhodes
92135446Strhodes#define dns_tsigkey_identity(tsigkey) \
93193149Sdougb	((tsigkey) == NULL ? NULL : \
94218384Sdougb	 (tsigkey)->generated ? ((tsigkey)->creator) : \
95218384Sdougb	 (&((tsigkey)->name)))
96135446Strhodes
97135446StrhodesISC_LANG_BEGINDECLS
98135446Strhodes
99135446Strhodesisc_result_t
100135446Strhodesdns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
101135446Strhodes		   unsigned char *secret, int length, isc_boolean_t generated,
102135446Strhodes		   dns_name_t *creator, isc_stdtime_t inception,
103135446Strhodes		   isc_stdtime_t expire, isc_mem_t *mctx,
104135446Strhodes		   dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
105135446Strhodes
106135446Strhodesisc_result_t
107135446Strhodesdns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
108135446Strhodes			  dst_key_t *dstkey, isc_boolean_t generated,
109135446Strhodes			  dns_name_t *creator, isc_stdtime_t inception,
110135446Strhodes			  isc_stdtime_t expire, isc_mem_t *mctx,
111135446Strhodes			  dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
112170222Sdougb/*%<
113135446Strhodes *	Creates a tsig key structure and saves it in the keyring.  If key is
114135446Strhodes *	not NULL, *key will contain a copy of the key.  The keys validity
115135446Strhodes *	period is specified by (inception, expire), and will not expire if
116135446Strhodes *	inception == expire.  If the key was generated, the creating identity,
117135446Strhodes *	if there is one, should be in the creator parameter.  Specifying an
118135446Strhodes *	unimplemented algorithm will cause failure only if dstkey != NULL; this
119135446Strhodes *	allows a transient key with an invalid algorithm to exist long enough
120135446Strhodes *	to generate a BADKEY response.
121135446Strhodes *
122218384Sdougb *	If dns_tsigkey_createfromkey is successful a new reference to 'dstkey'
123218384Sdougb *	will have been made.
124218384Sdougb *
125135446Strhodes *	Requires:
126170222Sdougb *\li		'name' is a valid dns_name_t
127170222Sdougb *\li		'algorithm' is a valid dns_name_t
128170222Sdougb *\li		'secret' is a valid pointer
129170222Sdougb *\li		'length' is an integer >= 0
130218384Sdougb *\li		'dstkey' is a valid dst key or NULL
131170222Sdougb *\li		'creator' points to a valid dns_name_t or is NULL
132170222Sdougb *\li		'mctx' is a valid memory context
133170222Sdougb *\li		'ring' is a valid TSIG keyring or NULL
134170222Sdougb *\li		'key' or '*key' must be NULL
135135446Strhodes *
136135446Strhodes *	Returns:
137170222Sdougb *\li		#ISC_R_SUCCESS
138170222Sdougb *\li		#ISC_R_EXISTS - a key with this name already exists
139170222Sdougb *\li		#ISC_R_NOTIMPLEMENTED - algorithm is not implemented
140170222Sdougb *\li		#ISC_R_NOMEMORY
141135446Strhodes */
142135446Strhodes
143135446Strhodesvoid
144135446Strhodesdns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp);
145170222Sdougb/*%<
146135446Strhodes *	Attach '*targetp' to 'source'.
147135446Strhodes *
148135446Strhodes *	Requires:
149170222Sdougb *\li		'key' is a valid TSIG key
150135446Strhodes *
151135446Strhodes *	Ensures:
152170222Sdougb *\li		*targetp is attached to source.
153135446Strhodes */
154135446Strhodes
155135446Strhodesvoid
156135446Strhodesdns_tsigkey_detach(dns_tsigkey_t **keyp);
157170222Sdougb/*%<
158135446Strhodes *	Detaches from the tsig key structure pointed to by '*key'.
159135446Strhodes *
160135446Strhodes *	Requires:
161170222Sdougb *\li		'keyp' is not NULL and '*keyp' is a valid TSIG key
162135446Strhodes *
163135446Strhodes *	Ensures:
164170222Sdougb *\li		'keyp' points to NULL
165135446Strhodes */
166135446Strhodes
167135446Strhodesvoid
168135446Strhodesdns_tsigkey_setdeleted(dns_tsigkey_t *key);
169170222Sdougb/*%<
170135446Strhodes *	Prevents this key from being used again.  It will be deleted when
171135446Strhodes *	no references exist.
172135446Strhodes *
173135446Strhodes *	Requires:
174170222Sdougb *\li		'key' is a valid TSIG key on a keyring
175135446Strhodes */
176135446Strhodes
177135446Strhodesisc_result_t
178135446Strhodesdns_tsig_sign(dns_message_t *msg);
179170222Sdougb/*%<
180135446Strhodes *	Generates a TSIG record for this message
181135446Strhodes *
182135446Strhodes *	Requires:
183170222Sdougb *\li		'msg' is a valid message
184170222Sdougb *\li		'msg->tsigkey' is a valid TSIG key
185170222Sdougb *\li		'msg->tsig' is NULL
186135446Strhodes *
187135446Strhodes *	Returns:
188170222Sdougb *\li		#ISC_R_SUCCESS
189170222Sdougb *\li		#ISC_R_NOMEMORY
190170222Sdougb *\li		#ISC_R_NOSPACE
191170222Sdougb *\li		#DNS_R_EXPECTEDTSIG
192135446Strhodes *			- this is a response & msg->querytsig is NULL
193135446Strhodes */
194135446Strhodes
195135446Strhodesisc_result_t
196135446Strhodesdns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
197135446Strhodes		dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2);
198170222Sdougb/*%<
199135446Strhodes *	Verifies the TSIG record in this message
200135446Strhodes *
201135446Strhodes *	Requires:
202170222Sdougb *\li		'source' is a valid buffer containing the unparsed message
203170222Sdougb *\li		'msg' is a valid message
204170222Sdougb *\li		'msg->tsigkey' is a valid TSIG key if this is a response
205170222Sdougb *\li		'msg->tsig' is NULL
206170222Sdougb *\li		'msg->querytsig' is not NULL if this is a response
207170222Sdougb *\li		'ring1' and 'ring2' are each either a valid keyring or NULL
208135446Strhodes *
209135446Strhodes *	Returns:
210170222Sdougb *\li		#ISC_R_SUCCESS
211170222Sdougb *\li		#ISC_R_NOMEMORY
212170222Sdougb *\li		#DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen
213170222Sdougb *\li		#DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected
214170222Sdougb *\li		#DNS_R_TSIGERRORSET - the TSIG verified but ->error was set
215135446Strhodes *				     and this is a query
216170222Sdougb *\li		#DNS_R_CLOCKSKEW - the TSIG failed to verify because of
217135446Strhodes *				  the time was out of the allowed range.
218170222Sdougb *\li		#DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify
219170222Sdougb *\li		#DNS_R_EXPECTEDRESPONSE - the message was set over TCP and
220135446Strhodes *					 should have been a response,
221135446Strhodes *					 but was not.
222135446Strhodes */
223135446Strhodes
224135446Strhodesisc_result_t
225135446Strhodesdns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
226135446Strhodes		 dns_name_t *algorithm, dns_tsig_keyring_t *ring);
227170222Sdougb/*%<
228135446Strhodes *	Returns the TSIG key corresponding to this name and (possibly)
229135446Strhodes *	algorithm.  Also increments the key's reference counter.
230135446Strhodes *
231135446Strhodes *	Requires:
232170222Sdougb *\li		'tsigkey' is not NULL
233170222Sdougb *\li		'*tsigkey' is NULL
234170222Sdougb *\li		'name' is a valid dns_name_t
235170222Sdougb *\li		'algorithm' is a valid dns_name_t or NULL
236170222Sdougb *\li		'ring' is a valid keyring
237135446Strhodes *
238135446Strhodes *	Returns:
239170222Sdougb *\li		#ISC_R_SUCCESS
240170222Sdougb *\li		#ISC_R_NOTFOUND
241135446Strhodes */
242135446Strhodes
243135446Strhodes
244135446Strhodesisc_result_t
245135446Strhodesdns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp);
246170222Sdougb/*%<
247135446Strhodes *	Create an empty TSIG key ring.
248135446Strhodes *
249135446Strhodes *	Requires:
250170222Sdougb *\li		'mctx' is not NULL
251170222Sdougb *\li		'ringp' is not NULL, and '*ringp' is NULL
252135446Strhodes *
253135446Strhodes *	Returns:
254170222Sdougb *\li		#ISC_R_SUCCESS
255170222Sdougb *\li		#ISC_R_NOMEMORY
256135446Strhodes */
257135446Strhodes
258224092Sdougbisc_result_t
259224092Sdougbdns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
260224092Sdougb		    dns_tsigkey_t *tkey);
261224092Sdougb/*%<
262224092Sdougb *      Place a TSIG key onto a key ring.
263224092Sdougb *
264224092Sdougb *	Requires:
265224092Sdougb *\li		'ring', 'name' and 'tkey' are not NULL
266224092Sdougb *
267224092Sdougb *	Returns:
268224092Sdougb *\li		#ISC_R_SUCCESS
269224092Sdougb *\li		Any other value indicates failure.
270224092Sdougb */
271135446Strhodes
272224092Sdougb
273135446Strhodesvoid
274224092Sdougbdns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target);
275224092Sdougb
276224092Sdougbvoid
277224092Sdougbdns_tsigkeyring_detach(dns_tsig_keyring_t **ringp);
278224092Sdougb
279224092Sdougbisc_result_t
280224092Sdougbdns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp);
281224092Sdougb
282170222Sdougb/*%<
283135446Strhodes *	Destroy a TSIG key ring.
284135446Strhodes *
285135446Strhodes *	Requires:
286170222Sdougb *\li		'ringp' is not NULL
287135446Strhodes */
288135446Strhodes
289224092Sdougbvoid
290224092Sdougbdns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp);
291224092Sdougb
292135446StrhodesISC_LANG_ENDDECLS
293135446Strhodes
294135446Strhodes#endif /* DNS_TSIG_H */
295