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