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