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