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