1 /*
2  * Copyright (C) 2004-2007, 2009-2014  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2002  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /* $Id$ */
19 
20 #ifndef DNS_DNSSEC_H
21 #define DNS_DNSSEC_H 1
22 
23 /*! \file dns/dnssec.h */
24 
25 #include <isc/lang.h>
26 #include <isc/stdtime.h>
27 #include <isc/stats.h>
28 
29 #include <dns/diff.h>
30 #include <dns/types.h>
31 
32 #include <dst/dst.h>
33 
34 ISC_LANG_BEGINDECLS
35 
36 LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats;
37 
38 /*%< Maximum number of keys supported in a zone. */
39 #define DNS_MAXZONEKEYS 32
40 
41 /*
42  * Indicates how the signer found this key: in the key repository, at the
43  * zone apex, or specified by the user.
44  */
45 typedef enum {
46 	dns_keysource_unknown,
47 	dns_keysource_repository,
48 	dns_keysource_zoneapex,
49 	dns_keysource_user
50 } dns_keysource_t;
51 
52 /*
53  * A DNSSEC key and hints about its intended use gleaned from metadata
54  */
55 struct dns_dnsseckey {
56 	dst_key_t *key;
57 	isc_boolean_t hint_publish;  /*% metadata says to publish */
58 	isc_boolean_t force_publish; /*% publish regardless of metadata */
59 	isc_boolean_t hint_sign;     /*% metadata says to sign with this key */
60 	isc_boolean_t force_sign;    /*% sign with key regardless of metadata */
61 	isc_boolean_t hint_remove;   /*% metadata says *don't* publish */
62 	isc_boolean_t is_active;     /*% key is already active */
63 	isc_boolean_t first_sign;    /*% key is newly becoming active */
64 	unsigned int prepublish;     /*% how long until active? */
65 	dns_keysource_t source;      /*% how the key was found */
66 	isc_boolean_t ksk;           /*% this is a key-signing key */
67 	isc_boolean_t legacy;        /*% this is old-style key with no
68 					 metadata (possibly generated by
69 					 an older version of BIND9) and
70 					 should be ignored when searching
71 					 for keys to import into the zone */
72 	unsigned int index;          /*% position in list */
73 	ISC_LINK(dns_dnsseckey_t) link;
74 };
75 
76 isc_result_t
77 dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx,
78 			dst_key_t **key);
79 /*%<
80  *	Creates a DST key from a DNS record.  Basically a wrapper around
81  *	dst_key_fromdns().
82  *
83  *	Requires:
84  *\li		'name' is not NULL
85  *\li		'rdata' is not NULL
86  *\li		'mctx' is not NULL
87  *\li		'key' is not NULL
88  *\li		'*key' is NULL
89  *
90  *	Returns:
91  *\li		#ISC_R_SUCCESS
92  *\li		#ISC_R_NOMEMORY
93  *\li		DST_R_INVALIDPUBLICKEY
94  *\li		various errors from dns_name_totext
95  */
96 
97 isc_result_t
98 dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
99 		isc_stdtime_t *inception, isc_stdtime_t *expire,
100 		isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata);
101 /*%<
102  *	Generates a RRSIG record covering this rdataset.  This has no effect
103  *	on existing RRSIG records.
104  *
105  *	Requires:
106  *\li		'name' (the owner name of the record) is a valid name
107  *\li		'set' is a valid rdataset
108  *\li		'key' is a valid key
109  *\li		'inception' is not NULL
110  *\li		'expire' is not NULL
111  *\li		'mctx' is not NULL
112  *\li		'buffer' is not NULL
113  *\li		'sigrdata' is not NULL
114  *
115  *	Returns:
116  *\li		#ISC_R_SUCCESS
117  *\li		#ISC_R_NOMEMORY
118  *\li		#ISC_R_NOSPACE
119  *\li		#DNS_R_INVALIDTIME - the expiration is before the inception
120  *\li		#DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either
121  *			it is not a zone key or its flags prevent
122  *			authentication)
123  *\li		DST_R_*
124  */
125 
126 isc_result_t
127 dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
128 		  isc_boolean_t ignoretime, isc_mem_t *mctx,
129 		  dns_rdata_t *sigrdata);
130 
131 isc_result_t
132 dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
133 		   isc_boolean_t ignoretime, isc_mem_t *mctx,
134 		   dns_rdata_t *sigrdata, dns_name_t *wild);
135 
136 isc_result_t
137 dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
138 		   isc_boolean_t ignoretime, unsigned int maxbits,
139 		   isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild);
140 /*%<
141  *	Verifies the RRSIG record covering this rdataset signed by a specific
142  *	key.  This does not determine if the key's owner is authorized to sign
143  *	this record, as this requires a resolver or database.
144  *	If 'ignoretime' is ISC_TRUE, temporal validity will not be checked.
145  *
146  *	'maxbits' specifies the maximum number of rsa exponent bits accepted.
147  *
148  *	Requires:
149  *\li		'name' (the owner name of the record) is a valid name
150  *\li		'set' is a valid rdataset
151  *\li		'key' is a valid key
152  *\li		'mctx' is not NULL
153  *\li		'sigrdata' is a valid rdata containing a SIG record
154  *\li		'wild' if non-NULL then is a valid and has a buffer.
155  *
156  *	Returns:
157  *\li		#ISC_R_SUCCESS
158  *\li		#ISC_R_NOMEMORY
159  *\li		#DNS_R_FROMWILDCARD - the signature is valid and is from
160  *			a wildcard expansion.  dns_dnssec_verify2() only.
161  *			'wild' contains the name of the wildcard if non-NULL.
162  *\li		#DNS_R_SIGINVALID - the signature fails to verify
163  *\li		#DNS_R_SIGEXPIRED - the signature has expired
164  *\li		#DNS_R_SIGFUTURE - the signature's validity period has not begun
165  *\li		#DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either
166  *			it is not a zone key or its flags prevent
167  *			authentication)
168  *\li		DST_R_*
169  */
170 
171 /*@{*/
172 isc_result_t
173 dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
174 			dns_name_t *name, isc_mem_t *mctx,
175 			unsigned int maxkeys, dst_key_t **keys,
176 			unsigned int *nkeys);
177 
178 isc_result_t
179 dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
180 			 dns_dbnode_t *node, dns_name_t *name,
181 			 const char *directory, isc_mem_t *mctx,
182 			 unsigned int maxkeys, dst_key_t **keys,
183 			 unsigned int *nkeys);
184 /*%<
185  * 	Finds a set of zone keys.
186  * 	XXX temporary - this should be handled in dns_zone_t.
187  */
188 /*@}*/
189 
190 isc_boolean_t
191 dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now);
192 /*%<
193  *
194  * 	Returns ISC_TRUE if 'key' is active as of the time specified
195  * 	in 'now' (i.e., if the activation date has passed, inactivation or
196  * 	deletion date has not yet been reached, and the key is not revoked
197  * 	-- or if it is a legacy key without metadata). Otherwise returns
198  * 	ISC_FALSE.
199  *
200  *	Requires:
201  *\li		'key' is a valid key
202  */
203 
204 isc_result_t
205 dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key);
206 /*%<
207  *	Signs a message with a SIG(0) record.  This is implicitly called by
208  *	dns_message_renderend() if msg->sig0key is not NULL.
209  *
210  *	Requires:
211  *\li		'msg' is a valid message
212  *\li		'key' is a valid key that can be used for signing
213  *
214  *	Returns:
215  *\li		#ISC_R_SUCCESS
216  *\li		#ISC_R_NOMEMORY
217  *\li		DST_R_*
218  */
219 
220 isc_result_t
221 dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
222 			 dst_key_t *key);
223 /*%<
224  *	Verifies a message signed by a SIG(0) record.  This is not
225  *	called implicitly by dns_message_parse().  If dns_message_signer()
226  *	is called before dns_dnssec_verifymessage(), it will return
227  *	#DNS_R_NOTVERIFIEDYET.  dns_dnssec_verifymessage() will set
228  *	the verified_sig0 flag in msg if the verify succeeds, and
229  *	the sig0status field otherwise.
230  *
231  *	Requires:
232  *\li		'source' is a valid buffer containing the unparsed message
233  *\li		'msg' is a valid message
234  *\li		'key' is a valid key
235  *
236  *	Returns:
237  *\li		#ISC_R_SUCCESS
238  *\li		#ISC_R_NOMEMORY
239  *\li		#ISC_R_NOTFOUND - no SIG(0) was found
240  *\li		#DNS_R_SIGINVALID - the SIG record is not well-formed or
241  *				   was not generated by the key.
242  *\li		DST_R_*
243  */
244 
245 isc_boolean_t
246 dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
247 		     dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
248 		     isc_boolean_t ignoretime, isc_mem_t *mctx);
249 
250 
251 isc_boolean_t
252 dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name,
253 		 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
254 		 isc_boolean_t ignoretime, isc_mem_t *mctx);
255 /*%<
256  * Verify that 'rdataset' is validly signed in 'sigrdataset' by
257  * the key in 'rdata'.
258  *
259  * dns_dnssec_selfsigns() requires that rdataset be a DNSKEY or KEY
260  * rrset.  dns_dnssec_signs() works on any rrset.
261  */
262 
263 
264 isc_result_t
265 dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
266 		     dns_dnsseckey_t **dkp);
267 /*%<
268  * Create and initialize a dns_dnsseckey_t structure.
269  *
270  *	Requires:
271  *\li		'dkp' is not NULL and '*dkp' is NULL.
272  *
273  *	Returns:
274  *\li		#ISC_R_SUCCESS
275  *\li		#ISC_R_NOMEMORY
276  */
277 
278 void
279 dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp);
280 /*%<
281  * Reclaim a dns_dnsseckey_t structure.
282  *
283  *	Requires:
284  *\li		'dkp' is not NULL and '*dkp' is not NULL.
285  *
286  *	Ensures:
287  *\li		'*dkp' is NULL.
288  */
289 
290 isc_result_t
291 dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
292 			    isc_mem_t *mctx, dns_dnsseckeylist_t *keylist);
293 /*%<
294  * Search 'directory' for K* key files matching the name in 'origin'.
295  * Append all such keys, along with use hints gleaned from their
296  * metadata, onto 'keylist'.
297  *
298  *	Requires:
299  *\li		'keylist' is not NULL
300  *
301  *	Returns:
302  *\li		#ISC_R_SUCCESS
303  *\li		#ISC_R_NOTFOUND
304  *\li		#ISC_R_NOMEMORY
305  *\li		any error returned by dns_name_totext(), isc_dir_open(), or
306  *              dst_key_fromnamedfile()
307  *
308  *	Ensures:
309  *\li		On error, keylist is unchanged
310  */
311 
312 isc_result_t
313 dns_dnssec_keylistfromrdataset(dns_name_t *origin,
314 			       const char *directory, isc_mem_t *mctx,
315 			       dns_rdataset_t *keyset, dns_rdataset_t *keysigs,
316 			       dns_rdataset_t *soasigs, isc_boolean_t savekeys,
317 			       isc_boolean_t publickey,
318 			       dns_dnsseckeylist_t *keylist);
319 /*%<
320  * Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
321  * Omit duplicates.  If 'publickey' is ISC_FALSE, search 'directory' for
322  * matching key files, and load the private keys that go with
323  * the public ones.  If 'savekeys' is ISC_TRUE, mark the keys so
324  * they will not be deleted or inactivated regardless of metadata.
325  *
326  * 'keysigs' and 'soasigs', if not NULL and associated, contain the
327  * RRSIGS for the DNSKEY and SOA records respectively and are used to mark
328  * whether a key is already active in the zone.
329  */
330 
331 isc_result_t
332 dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
333 		      dns_dnsseckeylist_t *removed, dns_name_t *origin,
334 		      dns_ttl_t hint_ttl, dns_diff_t *diff, isc_boolean_t allzsk,
335 		      isc_mem_t *mctx, void (*report)(const char *, ...));
336 /*%<
337  * Update the list of keys in 'keys' with new key information in 'newkeys'.
338  *
339  * For each key in 'newkeys', see if it has a match in 'keys'.
340  * - If not, and if the metadata says the key should be published:
341  *   add it to 'keys', and place a dns_difftuple into 'diff' so
342  *   the key can be added to the DNSKEY set.  If the metadata says it
343  *   should be active, set the first_sign flag.
344  * - If so, and if the metadata says it should be removed:
345  *   remove it from 'keys', and place a dns_difftuple into 'diff' so
346  *   the key can be removed from the DNSKEY set.  if 'removed' is non-NULL,
347  *   copy the key into that list; otherwise destroy it.
348  * - Otherwise, make sure keys has current metadata.
349  *
350  * If 'allzsk' is true, we are allowing KSK-flagged keys to be used as
351  * ZSKs.
352  *
353  * 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no
354  * existing RRset, and if none of the keys to be added has a default TTL
355  * (in which case we would use the shortest one).  If the TTL is longer
356  * than the time until a new key will be activated, then we have to delay
357  * the key's activation.
358  *
359  * 'report' points to a function for reporting status.
360  *
361  * On completion, any remaining keys in 'newkeys' are freed.
362  */
363 ISC_LANG_ENDDECLS
364 
365 #endif /* DNS_DNSSEC_H */
366