00001 /* 00002 * Copyright (C) 2004-2007, 2009-2014 Internet Systems Consortium, Inc. ("ISC") 00003 * Copyright (C) 1999-2002 Internet Software Consortium. 00004 * 00005 * Permission to use, copy, modify, and/or distribute this software for any 00006 * purpose with or without fee is hereby granted, provided that the above 00007 * copyright notice and this permission notice appear in all copies. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 00010 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00011 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 00012 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00013 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00014 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00015 * PERFORMANCE OF THIS SOFTWARE. 00016 */ 00017 00018 /* $Id$ */ 00019 00020 #ifndef DNS_DNSSEC_H 00021 #define DNS_DNSSEC_H 1 00022 00023 /*! \file dns/dnssec.h */ 00024 00025 #include <isc/lang.h> 00026 #include <isc/stdtime.h> 00027 #include <isc/stats.h> 00028 00029 #include <dns/diff.h> 00030 #include <dns/types.h> 00031 00032 #include <dst/dst.h> 00033 00034 ISC_LANG_BEGINDECLS 00035 00036 LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats; 00037 00038 /*%< Maximum number of keys supported in a zone. */ 00039 #define DNS_MAXZONEKEYS 32 00040 00041 /* 00042 * Indicates how the signer found this key: in the key repository, at the 00043 * zone apex, or specified by the user. 00044 */ 00045 typedef enum { 00046 dns_keysource_unknown, 00047 dns_keysource_repository, 00048 dns_keysource_zoneapex, 00049 dns_keysource_user 00050 } dns_keysource_t; 00051 00052 /* 00053 * A DNSSEC key and hints about its intended use gleaned from metadata 00054 */ 00055 struct dns_dnsseckey { 00056 dst_key_t *key; 00057 isc_boolean_t hint_publish; /*% metadata says to publish */ 00058 isc_boolean_t force_publish; /*% publish regardless of metadata */ 00059 isc_boolean_t hint_sign; /*% metadata says to sign with this key */ 00060 isc_boolean_t force_sign; /*% sign with key regardless of metadata */ 00061 isc_boolean_t hint_remove; /*% metadata says *don't* publish */ 00062 isc_boolean_t is_active; /*% key is already active */ 00063 isc_boolean_t first_sign; /*% key is newly becoming active */ 00064 unsigned int prepublish; /*% how long until active? */ 00065 dns_keysource_t source; /*% how the key was found */ 00066 isc_boolean_t ksk; /*% this is a key-signing key */ 00067 isc_boolean_t legacy; /*% this is old-style key with no 00068 metadata (possibly generated by 00069 an older version of BIND9) and 00070 should be ignored when searching 00071 for keys to import into the zone */ 00072 unsigned int index; /*% position in list */ 00073 ISC_LINK(dns_dnsseckey_t) link; 00074 }; 00075 00076 isc_result_t 00077 dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, 00078 dst_key_t **key); 00079 /*%< 00080 * Creates a DST key from a DNS record. Basically a wrapper around 00081 * dst_key_fromdns(). 00082 * 00083 * Requires: 00084 *\li 'name' is not NULL 00085 *\li 'rdata' is not NULL 00086 *\li 'mctx' is not NULL 00087 *\li 'key' is not NULL 00088 *\li '*key' is NULL 00089 * 00090 * Returns: 00091 *\li #ISC_R_SUCCESS 00092 *\li #ISC_R_NOMEMORY 00093 *\li DST_R_INVALIDPUBLICKEY 00094 *\li various errors from dns_name_totext 00095 */ 00096 00097 isc_result_t 00098 dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, 00099 isc_stdtime_t *inception, isc_stdtime_t *expire, 00100 isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata); 00101 /*%< 00102 * Generates a RRSIG record covering this rdataset. This has no effect 00103 * on existing RRSIG records. 00104 * 00105 * Requires: 00106 *\li 'name' (the owner name of the record) is a valid name 00107 *\li 'set' is a valid rdataset 00108 *\li 'key' is a valid key 00109 *\li 'inception' is not NULL 00110 *\li 'expire' is not NULL 00111 *\li 'mctx' is not NULL 00112 *\li 'buffer' is not NULL 00113 *\li 'sigrdata' is not NULL 00114 * 00115 * Returns: 00116 *\li #ISC_R_SUCCESS 00117 *\li #ISC_R_NOMEMORY 00118 *\li #ISC_R_NOSPACE 00119 *\li #DNS_R_INVALIDTIME - the expiration is before the inception 00120 *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either 00121 * it is not a zone key or its flags prevent 00122 * authentication) 00123 *\li DST_R_* 00124 */ 00125 00126 isc_result_t 00127 dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, 00128 isc_boolean_t ignoretime, isc_mem_t *mctx, 00129 dns_rdata_t *sigrdata); 00130 00131 isc_result_t 00132 dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, 00133 isc_boolean_t ignoretime, isc_mem_t *mctx, 00134 dns_rdata_t *sigrdata, dns_name_t *wild); 00135 00136 isc_result_t 00137 dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, 00138 isc_boolean_t ignoretime, unsigned int maxbits, 00139 isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); 00140 /*%< 00141 * Verifies the RRSIG record covering this rdataset signed by a specific 00142 * key. This does not determine if the key's owner is authorized to sign 00143 * this record, as this requires a resolver or database. 00144 * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked. 00145 * 00146 * 'maxbits' specifies the maximum number of rsa exponent bits accepted. 00147 * 00148 * Requires: 00149 *\li 'name' (the owner name of the record) is a valid name 00150 *\li 'set' is a valid rdataset 00151 *\li 'key' is a valid key 00152 *\li 'mctx' is not NULL 00153 *\li 'sigrdata' is a valid rdata containing a SIG record 00154 *\li 'wild' if non-NULL then is a valid and has a buffer. 00155 * 00156 * Returns: 00157 *\li #ISC_R_SUCCESS 00158 *\li #ISC_R_NOMEMORY 00159 *\li #DNS_R_FROMWILDCARD - the signature is valid and is from 00160 * a wildcard expansion. dns_dnssec_verify2() only. 00161 * 'wild' contains the name of the wildcard if non-NULL. 00162 *\li #DNS_R_SIGINVALID - the signature fails to verify 00163 *\li #DNS_R_SIGEXPIRED - the signature has expired 00164 *\li #DNS_R_SIGFUTURE - the signature's validity period has not begun 00165 *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either 00166 * it is not a zone key or its flags prevent 00167 * authentication) 00168 *\li DST_R_* 00169 */ 00170 00171 /*@{*/ 00172 isc_result_t 00173 dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 00174 dns_name_t *name, isc_mem_t *mctx, 00175 unsigned int maxkeys, dst_key_t **keys, 00176 unsigned int *nkeys); 00177 00178 isc_result_t 00179 dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, 00180 dns_dbnode_t *node, dns_name_t *name, 00181 const char *directory, isc_mem_t *mctx, 00182 unsigned int maxkeys, dst_key_t **keys, 00183 unsigned int *nkeys); 00184 /*%< 00185 * Finds a set of zone keys. 00186 * XXX temporary - this should be handled in dns_zone_t. 00187 */ 00188 /*@}*/ 00189 00190 isc_boolean_t 00191 dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now); 00192 /*%< 00193 * 00194 * Returns ISC_TRUE if 'key' is active as of the time specified 00195 * in 'now' (i.e., if the activation date has passed, inactivation or 00196 * deletion date has not yet been reached, and the key is not revoked 00197 * -- or if it is a legacy key without metadata). Otherwise returns 00198 * ISC_FALSE. 00199 * 00200 * Requires: 00201 *\li 'key' is a valid key 00202 */ 00203 00204 isc_result_t 00205 dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key); 00206 /*%< 00207 * Signs a message with a SIG(0) record. This is implicitly called by 00208 * dns_message_renderend() if msg->sig0key is not NULL. 00209 * 00210 * Requires: 00211 *\li 'msg' is a valid message 00212 *\li 'key' is a valid key that can be used for signing 00213 * 00214 * Returns: 00215 *\li #ISC_R_SUCCESS 00216 *\li #ISC_R_NOMEMORY 00217 *\li DST_R_* 00218 */ 00219 00220 isc_result_t 00221 dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, 00222 dst_key_t *key); 00223 /*%< 00224 * Verifies a message signed by a SIG(0) record. This is not 00225 * called implicitly by dns_message_parse(). If dns_message_signer() 00226 * is called before dns_dnssec_verifymessage(), it will return 00227 * #DNS_R_NOTVERIFIEDYET. dns_dnssec_verifymessage() will set 00228 * the verified_sig0 flag in msg if the verify succeeds, and 00229 * the sig0status field otherwise. 00230 * 00231 * Requires: 00232 *\li 'source' is a valid buffer containing the unparsed message 00233 *\li 'msg' is a valid message 00234 *\li 'key' is a valid key 00235 * 00236 * Returns: 00237 *\li #ISC_R_SUCCESS 00238 *\li #ISC_R_NOMEMORY 00239 *\li #ISC_R_NOTFOUND - no SIG(0) was found 00240 *\li #DNS_R_SIGINVALID - the SIG record is not well-formed or 00241 * was not generated by the key. 00242 *\li DST_R_* 00243 */ 00244 00245 isc_boolean_t 00246 dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, 00247 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 00248 isc_boolean_t ignoretime, isc_mem_t *mctx); 00249 00250 00251 isc_boolean_t 00252 dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name, 00253 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 00254 isc_boolean_t ignoretime, isc_mem_t *mctx); 00255 /*%< 00256 * Verify that 'rdataset' is validly signed in 'sigrdataset' by 00257 * the key in 'rdata'. 00258 * 00259 * dns_dnssec_selfsigns() requires that rdataset be a DNSKEY or KEY 00260 * rrset. dns_dnssec_signs() works on any rrset. 00261 */ 00262 00263 00264 isc_result_t 00265 dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey, 00266 dns_dnsseckey_t **dkp); 00267 /*%< 00268 * Create and initialize a dns_dnsseckey_t structure. 00269 * 00270 * Requires: 00271 *\li 'dkp' is not NULL and '*dkp' is NULL. 00272 * 00273 * Returns: 00274 *\li #ISC_R_SUCCESS 00275 *\li #ISC_R_NOMEMORY 00276 */ 00277 00278 void 00279 dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp); 00280 /*%< 00281 * Reclaim a dns_dnsseckey_t structure. 00282 * 00283 * Requires: 00284 *\li 'dkp' is not NULL and '*dkp' is not NULL. 00285 * 00286 * Ensures: 00287 *\li '*dkp' is NULL. 00288 */ 00289 00290 isc_result_t 00291 dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, 00292 isc_mem_t *mctx, dns_dnsseckeylist_t *keylist); 00293 /*%< 00294 * Search 'directory' for K* key files matching the name in 'origin'. 00295 * Append all such keys, along with use hints gleaned from their 00296 * metadata, onto 'keylist'. 00297 * 00298 * Requires: 00299 *\li 'keylist' is not NULL 00300 * 00301 * Returns: 00302 *\li #ISC_R_SUCCESS 00303 *\li #ISC_R_NOTFOUND 00304 *\li #ISC_R_NOMEMORY 00305 *\li any error returned by dns_name_totext(), isc_dir_open(), or 00306 * dst_key_fromnamedfile() 00307 * 00308 * Ensures: 00309 *\li On error, keylist is unchanged 00310 */ 00311 00312 isc_result_t 00313 dns_dnssec_keylistfromrdataset(dns_name_t *origin, 00314 const char *directory, isc_mem_t *mctx, 00315 dns_rdataset_t *keyset, dns_rdataset_t *keysigs, 00316 dns_rdataset_t *soasigs, isc_boolean_t savekeys, 00317 isc_boolean_t publickey, 00318 dns_dnsseckeylist_t *keylist); 00319 /*%< 00320 * Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'. 00321 * Omit duplicates. If 'publickey' is ISC_FALSE, search 'directory' for 00322 * matching key files, and load the private keys that go with 00323 * the public ones. If 'savekeys' is ISC_TRUE, mark the keys so 00324 * they will not be deleted or inactivated regardless of metadata. 00325 * 00326 * 'keysigs' and 'soasigs', if not NULL and associated, contain the 00327 * RRSIGS for the DNSKEY and SOA records respectively and are used to mark 00328 * whether a key is already active in the zone. 00329 */ 00330 00331 isc_result_t 00332 dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, 00333 dns_dnsseckeylist_t *removed, dns_name_t *origin, 00334 dns_ttl_t hint_ttl, dns_diff_t *diff, isc_boolean_t allzsk, 00335 isc_mem_t *mctx, void (*report)(const char *, ...)); 00336 /*%< 00337 * Update the list of keys in 'keys' with new key information in 'newkeys'. 00338 * 00339 * For each key in 'newkeys', see if it has a match in 'keys'. 00340 * - If not, and if the metadata says the key should be published: 00341 * add it to 'keys', and place a dns_difftuple into 'diff' so 00342 * the key can be added to the DNSKEY set. If the metadata says it 00343 * should be active, set the first_sign flag. 00344 * - If so, and if the metadata says it should be removed: 00345 * remove it from 'keys', and place a dns_difftuple into 'diff' so 00346 * the key can be removed from the DNSKEY set. if 'removed' is non-NULL, 00347 * copy the key into that list; otherwise destroy it. 00348 * - Otherwise, make sure keys has current metadata. 00349 * 00350 * If 'allzsk' is true, we are allowing KSK-flagged keys to be used as 00351 * ZSKs. 00352 * 00353 * 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no 00354 * existing RRset, and if none of the keys to be added has a default TTL 00355 * (in which case we would use the shortest one). If the TTL is longer 00356 * than the time until a new key will be activated, then we have to delay 00357 * the key's activation. 00358 * 00359 * 'report' points to a function for reporting status. 00360 * 00361 * On completion, any remaining keys in 'newkeys' are freed. 00362 */ 00363 ISC_LANG_ENDDECLS 00364 00365 #endif /* DNS_DNSSEC_H */