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