Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: tsig.h,v 1.1 2024/02/18 20:57:38 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #ifndef DNS_TSIG_H
     17 #define DNS_TSIG_H 1
     18 
     19 /*! \file dns/tsig.h */
     20 
     21 #include <stdbool.h>
     22 
     23 #include <isc/lang.h>
     24 #include <isc/refcount.h>
     25 #include <isc/rwlock.h>
     26 #include <isc/stdio.h>
     27 #include <isc/stdtime.h>
     28 
     29 #include <dns/name.h>
     30 #include <dns/types.h>
     31 
     32 #include <dst/dst.h>
     33 #include <pk11/site.h>
     34 
     35 /*
     36  * Algorithms.
     37  */
     38 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_hmacmd5_name;
     39 #define DNS_TSIG_HMACMD5_NAME dns_tsig_hmacmd5_name
     40 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_gssapi_name;
     41 #define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name
     42 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_gssapims_name;
     43 #define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name
     44 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_hmacsha1_name;
     45 #define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name
     46 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_hmacsha224_name;
     47 #define DNS_TSIG_HMACSHA224_NAME dns_tsig_hmacsha224_name
     48 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_hmacsha256_name;
     49 #define DNS_TSIG_HMACSHA256_NAME dns_tsig_hmacsha256_name
     50 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_hmacsha384_name;
     51 #define DNS_TSIG_HMACSHA384_NAME dns_tsig_hmacsha384_name
     52 LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_tsig_hmacsha512_name;
     53 #define DNS_TSIG_HMACSHA512_NAME dns_tsig_hmacsha512_name
     54 
     55 /*%
     56  * Default fudge value.
     57  */
     58 #define DNS_TSIG_FUDGE 300
     59 
     60 struct dns_tsig_keyring {
     61 	dns_rbt_t   *keys;
     62 	unsigned int writecount;
     63 	isc_rwlock_t lock;
     64 	isc_mem_t   *mctx;
     65 	/*
     66 	 * LRU list of generated key along with a count of the keys on the
     67 	 * list and a maximum size.
     68 	 */
     69 	unsigned int generated;
     70 	unsigned int maxgenerated;
     71 	ISC_LIST(dns_tsigkey_t) lru;
     72 	isc_refcount_t references;
     73 };
     74 
     75 struct dns_tsigkey {
     76 	/* Unlocked */
     77 	unsigned int	    magic; /*%< Magic number. */
     78 	isc_mem_t	   *mctx;
     79 	dst_key_t	   *key;       /*%< Key */
     80 	dns_name_t	    name;      /*%< Key name */
     81 	const dns_name_t   *algorithm; /*%< Algorithm name */
     82 	dns_name_t	   *creator;   /*%< name that created secret */
     83 	bool		    generated; /*%< was this generated? */
     84 	isc_stdtime_t	    inception; /*%< start of validity period */
     85 	isc_stdtime_t	    expire;    /*%< end of validity period */
     86 	dns_tsig_keyring_t *ring;      /*%< the enclosing keyring */
     87 	isc_refcount_t	    refs;      /*%< reference counter */
     88 	ISC_LINK(dns_tsigkey_t) link;
     89 };
     90 
     91 ISC_LANG_BEGINDECLS
     92 
     93 const dns_name_t *
     94 dns_tsigkey_identity(const dns_tsigkey_t *tsigkey);
     95 /*%<
     96  *	Returns the identity of the provided TSIG key.
     97  *
     98  *	Requires:
     99  *\li		'tsigkey' is a valid TSIG key or NULL
    100  *
    101  *	Returns:
    102  *\li		NULL if 'tsigkey' was NULL
    103  *\li		identity of the provided TSIG key
    104  */
    105 
    106 isc_result_t
    107 dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm,
    108 		   unsigned char *secret, int length, bool generated,
    109 		   const dns_name_t *creator, isc_stdtime_t inception,
    110 		   isc_stdtime_t expire, isc_mem_t *mctx,
    111 		   dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
    112 
    113 isc_result_t
    114 dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
    115 			  dst_key_t *dstkey, bool generated,
    116 			  const dns_name_t *creator, isc_stdtime_t inception,
    117 			  isc_stdtime_t expire, isc_mem_t *mctx,
    118 			  dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
    119 /*%<
    120  *	Creates a tsig key structure and saves it in the keyring.  If key is
    121  *	not NULL, *key will contain a copy of the key.  The keys validity
    122  *	period is specified by (inception, expire), and will not expire if
    123  *	inception == expire.  If the key was generated, the creating identity,
    124  *	if there is one, should be in the creator parameter.  Specifying an
    125  *	unimplemented algorithm will cause failure only if dstkey != NULL; this
    126  *	allows a transient key with an invalid algorithm to exist long enough
    127  *	to generate a BADKEY response.
    128  *
    129  *	If dns_tsigkey_createfromkey is successful a new reference to 'dstkey'
    130  *	will have been made.
    131  *
    132  *	Requires:
    133  *\li		'name' is a valid dns_name_t
    134  *\li		'algorithm' is a valid dns_name_t
    135  *\li		'secret' is a valid pointer
    136  *\li		'length' is an integer >= 0
    137  *\li		'dstkey' is a valid dst key or NULL
    138  *\li		'creator' points to a valid dns_name_t or is NULL
    139  *\li		'mctx' is a valid memory context
    140  *\li		'ring' is a valid TSIG keyring or NULL
    141  *\li		'key' or '*key' must be NULL
    142  *
    143  *	Returns:
    144  *\li		#ISC_R_SUCCESS
    145  *\li		#ISC_R_EXISTS - a key with this name already exists
    146  *\li		#ISC_R_NOTIMPLEMENTED - algorithm is not implemented
    147  *\li		#ISC_R_NOMEMORY
    148  */
    149 
    150 void
    151 dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp);
    152 /*%<
    153  *	Attach '*targetp' to 'source'.
    154  *
    155  *	Requires:
    156  *\li		'key' is a valid TSIG key
    157  *
    158  *	Ensures:
    159  *\li		*targetp is attached to source.
    160  */
    161 
    162 void
    163 dns_tsigkey_detach(dns_tsigkey_t **keyp);
    164 /*%<
    165  *	Detaches from the tsig key structure pointed to by '*key'.
    166  *
    167  *	Requires:
    168  *\li		'keyp' is not NULL and '*keyp' is a valid TSIG key
    169  *
    170  *	Ensures:
    171  *\li		'keyp' points to NULL
    172  */
    173 
    174 void
    175 dns_tsigkey_setdeleted(dns_tsigkey_t *key);
    176 /*%<
    177  *	Prevents this key from being used again.  It will be deleted when
    178  *	no references exist.
    179  *
    180  *	Requires:
    181  *\li		'key' is a valid TSIG key on a keyring
    182  */
    183 
    184 isc_result_t
    185 dns_tsig_sign(dns_message_t *msg);
    186 /*%<
    187  *	Generates a TSIG record for this message
    188  *
    189  *	Requires:
    190  *\li		'msg' is a valid message
    191  *\li		'msg->tsigkey' is a valid TSIG key
    192  *\li		'msg->tsig' is NULL
    193  *
    194  *	Returns:
    195  *\li		#ISC_R_SUCCESS
    196  *\li		#ISC_R_NOMEMORY
    197  *\li		#ISC_R_NOSPACE
    198  *\li		#DNS_R_EXPECTEDTSIG
    199  *			- this is a response & msg->querytsig is NULL
    200  */
    201 
    202 isc_result_t
    203 dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
    204 		dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2);
    205 /*%<
    206  *	Verifies the TSIG record in this message
    207  *
    208  *	Requires:
    209  *\li		'source' is a valid buffer containing the unparsed message
    210  *\li		'msg' is a valid message
    211  *\li		'msg->tsigkey' is a valid TSIG key if this is a response
    212  *\li		'msg->tsig' is NULL
    213  *\li		'msg->querytsig' is not NULL if this is a response
    214  *\li		'ring1' and 'ring2' are each either a valid keyring or NULL
    215  *
    216  *	Returns:
    217  *\li		#ISC_R_SUCCESS
    218  *\li		#ISC_R_NOMEMORY
    219  *\li		#DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen
    220  *\li		#DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected
    221  *\li		#DNS_R_TSIGERRORSET - the TSIG verified but ->error was set
    222  *				     and this is a query
    223  *\li		#DNS_R_CLOCKSKEW - the TSIG failed to verify because of
    224  *				  the time was out of the allowed range.
    225  *\li		#DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify
    226  *\li		#DNS_R_EXPECTEDRESPONSE - the message was set over TCP and
    227  *					 should have been a response,
    228  *					 but was not.
    229  */
    230 
    231 isc_result_t
    232 dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
    233 		 const dns_name_t *algorithm, dns_tsig_keyring_t *ring);
    234 /*%<
    235  *	Returns the TSIG key corresponding to this name and (possibly)
    236  *	algorithm.  Also increments the key's reference counter.
    237  *
    238  *	Requires:
    239  *\li		'tsigkey' is not NULL
    240  *\li		'*tsigkey' is NULL
    241  *\li		'name' is a valid dns_name_t
    242  *\li		'algorithm' is a valid dns_name_t or NULL
    243  *\li		'ring' is a valid keyring
    244  *
    245  *	Returns:
    246  *\li		#ISC_R_SUCCESS
    247  *\li		#ISC_R_NOTFOUND
    248  */
    249 
    250 isc_result_t
    251 dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp);
    252 /*%<
    253  *	Create an empty TSIG key ring.
    254  *
    255  *	Requires:
    256  *\li		'mctx' is not NULL
    257  *\li		'ringp' is not NULL, and '*ringp' is NULL
    258  *
    259  *	Returns:
    260  *\li		#ISC_R_SUCCESS
    261  *\li		#ISC_R_NOMEMORY
    262  */
    263 
    264 isc_result_t
    265 dns_tsigkeyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name,
    266 		    dns_tsigkey_t *tkey);
    267 /*%<
    268  *      Place a TSIG key onto a key ring.
    269  *
    270  *	Requires:
    271  *\li		'ring', 'name' and 'tkey' are not NULL
    272  *
    273  *	Returns:
    274  *\li		#ISC_R_SUCCESS
    275  *\li		Any other value indicates failure.
    276  */
    277 
    278 void
    279 dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target);
    280 
    281 void
    282 dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp);
    283 
    284 isc_result_t
    285 dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp);
    286 
    287 /*%<
    288  *	Destroy a TSIG key ring.
    289  *
    290  *	Requires:
    291  *\li		'ringp' is not NULL
    292  */
    293 
    294 void
    295 dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp);
    296 
    297 ISC_LANG_ENDDECLS
    298 
    299 #endif /* DNS_TSIG_H */
    300