#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"
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)
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);
+}
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.
*/
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
/** 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 */