From 69354298fc1735c0dca7fbb070a94faf3716a45c Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 17 Jun 2025 16:54:52 +0200 Subject: [PATCH] - xfr-tsig, tsig_create and tsig_delete. --- util/tsig.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ util/tsig.h | 53 +++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/util/tsig.c b/util/tsig.c index 79438adc0..984e3ba5b 100644 --- a/util/tsig.c +++ b/util/tsig.c @@ -43,6 +43,7 @@ #include "util/tsig.h" #include "util/config_file.h" #include "util/log.h" +#include "util/net_help.h" #include "sldns/parseutil.h" #include "sldns/pkthdr.h" #include "sldns/rrdef.h" @@ -206,6 +207,20 @@ tsig_key_table_apply_cfg(struct tsig_key_table* key_table, return 1; } +struct tsig_key* +tsig_key_table_search(struct tsig_key_table* key_table, uint8_t* name, + size_t namelen) +{ + rbnode_type* node; + struct tsig_key k; + k.node.key = &k; + k.name = name; + k.name_len = namelen; + node = rbtree_search(key_table->tree, &k); + if(!node) return NULL; + return (struct tsig_key*)node->key; +} + void tsig_key_delete(struct tsig_key* key) { if(!key) @@ -560,3 +575,64 @@ tsig_verify(sldns_buffer* pkt, const uint8_t* name, const uint8_t* alg, sldns_buffer_set_position(pkt, end_of_message); return LDNS_TSIG_ERROR_BADSIG; } + +struct tsig_data* +tsig_create(struct tsig_key_table* key_table, uint8_t* name, size_t namelen) +{ + struct tsig_key* key; + struct tsig_data* tsig; + lock_rw_rdlock(&key_table->lock); + key = tsig_key_table_search(key_table, name, namelen); + if(!key) { + lock_rw_unlock(&key_table->lock); + return NULL; + } + /* the key table lock is also on the returned key */ + + tsig = calloc(1, sizeof(*tsig)); + if(!tsig) { + lock_rw_unlock(&key_table->lock); + log_err("out of memory"); + return NULL; + } + tsig->key_name_len = key->name_len; + tsig->key_name = memdup(key->name, key->name_len); + if(!tsig->key_name) { + lock_rw_unlock(&key_table->lock); + tsig_delete(tsig); + log_err("out of memory"); + return NULL; + } + tsig->algorithm_name_len = key->algo->wireformat_name_len; + tsig->mac_size = key->algo->max_digest_size; + tsig->mac = calloc(1, tsig->mac_size); + if(!tsig->mac) { + lock_rw_unlock(&key_table->lock); + tsig_delete(tsig); + log_err("out of memory"); + return NULL; + } + lock_rw_unlock(&key_table->lock); + return tsig; +} + +struct tsig_data* +tsig_create_fromstr(struct tsig_key_table* key_table, char* name) +{ + uint8_t buf[LDNS_MAX_DOMAINLEN+1]; + size_t len = sizeof(buf); + if(!sldns_str2wire_dname_buf(name, buf, &len)) { + log_err("could not parse '%s'", name); + return NULL; + } + return tsig_create(key_table, buf, len); +} + +void +tsig_delete(struct tsig_data* tsig) +{ + if(!tsig) return; + free(tsig->key_name); + free(tsig->mac); + free(tsig); +} diff --git a/util/tsig.h b/util/tsig.h index d0d4226ca..68b71c23d 100644 --- a/util/tsig.h +++ b/util/tsig.h @@ -79,6 +79,23 @@ struct tsig_record { uint8_t* other_data; }; +/** + * TSIG data. This keeps track of the information between packets, + * for the TSIG signature, and state, errors, key. + */ +struct tsig_data { + /** The key name, in wireformat */ + uint8_t* key_name; + /** length of the key name */ + size_t key_name_len; + /** length of the algorithm name */ + size_t algorithm_name_len; + /** mac size */ + size_t mac_size; + /** digest buffer */ + uint8_t* mac; +}; + /** * TSIG algorithm. This is the HMAC algorithm used for the TSIG mac. */ @@ -156,6 +173,17 @@ void tsig_key_table_delete(struct tsig_key_table* key_table); int tsig_key_table_apply_cfg(struct tsig_key_table* key_table, struct config_file* cfg); +/** + * Find key in key table. Caller must hold lock on the table. + * @param key_table: the tsig key table. + * @param name: name to look for in wireformat. + * @param namelen: length of name. + * @return the found key or NULL if not found. The item is locked + * by the key_table lock. + */ +struct tsig_key* tsig_key_table_search(struct tsig_key_table* key_table, + uint8_t* name, size_t namelen); + /** * Delete TSIG key. * @param key: to delete @@ -189,4 +217,29 @@ int tsig_verify(struct sldns_buffer* pkt, const uint8_t* name, /** Compare function for the key table keys. */ int tsig_key_compare(const void* v1, const void* v2); +/** + * Find tsig key and create new tsig data. + * @param key_table: the tsig key table. + * @param name: key name in wireformat. + * @param namelen: length of name. + * @return NULL if not found, or alloc failure. + */ +struct tsig_data* tsig_create(struct tsig_key_table* key_table, + uint8_t* name, size_t namelen); + +/** + * Find tsig key and create new tsig data. + * @param key_table: the tsig key table. + * @param name: key name string. + * @return NULL if not found, or alloc failure, or could not parse string. + */ +struct tsig_data* tsig_create_fromstr(struct tsig_key_table* key_table, + char* name); + +/** + * Delete tsig data. + * @param tsig: the tsig data to delete. + */ +void tsig_delete(struct tsig_data* tsig); + #endif /* UTIL_TSIG_H */ -- 2.47.2