dnssec.h

Go to the documentation of this file.
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 */

Generated on Tue Apr 28 17:40:57 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha