tsig.c
Go to the documentation of this file.
/*
* Copyright (c) 2011 NLNet Labs. All rights reserved.
*
* Taken from NSD3 and adjusted for OpenDNSSEC, NLnet Labs.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "compat.h"
#include "duration.h"
#include "file.h"
#include "log.h"
#include "status.h"
#include "util.h"
#include "wire/buffer.h"
#include "wire/tsig.h"
#include "wire/tsig-openssl.h"
#include <arpa/inet.h>
#define TSIG_SIGNED_TIME_FUDGE 300
static const char* tsig_str = "tsig";
typedef struct tsig_key_table_struct tsig_key_table_type;
struct tsig_key_table_struct {
tsig_key_table_type* next;
tsig_key_type* key;
};
static tsig_key_table_type* tsig_key_table = NULL;
typedef struct tsig_algo_table_struct tsig_algo_table_type;
struct tsig_algo_table_struct {
tsig_algo_table_type* next;
tsig_algo_type* algorithm;
};
static tsig_algo_table_type* tsig_algo_table = NULL;
static size_t max_algo_digest_size = 0;
void
tsig_handler_add_key(tsig_key_type* key)
{
tsig_key_table_type* entry = NULL;
if (!key) {
return;
}
CHECKALLOC(entry = (tsig_key_table_type *) malloc(sizeof(tsig_key_table_type)));
if (entry) {
entry->key = key;
entry->next = tsig_key_table;
tsig_key_table = entry;
}
}
void
tsig_handler_add_algo(tsig_algo_type* algo)
{
tsig_algo_table_type* entry = NULL;
if (!algo) {
return;
}
CHECKALLOC(entry = (tsig_algo_table_type *) malloc(sizeof(tsig_algo_table_type)));
if (entry) {
entry->algorithm = algo;
entry->next = tsig_algo_table;
tsig_algo_table = entry;
if (algo->max_digest_size > max_algo_digest_size) {
max_algo_digest_size = algo->max_digest_size;
}
}
}
ods_status
tsig_handler_init()
{
tsig_key_table = NULL;
tsig_algo_table = NULL;
#ifdef HAVE_SSL
ods_log_debug("[%s] init openssl", tsig_str);
return tsig_handler_openssl_init();
#else
ods_log_debug("[%s] openssl disabled", tsig_str);
return ODS_STATUS_OK;
#endif
}
void
tsig_handler_cleanup(void)
{
tsig_algo_table_type* aentry = NULL, *anext = NULL;
tsig_key_table_type* kentry = NULL, *knext = NULL;
#ifdef HAVE_SSL
tsig_handler_openssl_finalize();
#endif
aentry = tsig_algo_table;
while (aentry) {
anext = aentry->next;
ldns_rdf_deep_free(aentry->algorithm->wf_name);
free(aentry->algorithm);
free(aentry);
aentry = anext;
}
kentry = tsig_key_table;
while (kentry) {
knext = kentry->next;
ldns_rdf_deep_free(kentry->key->dname);
free((void*)kentry->key->data);
free((void*)kentry->key);
free(kentry);
kentry = knext;
}
}
static tsig_key_type*
tsig_key_create(tsig_type* tsig)
{
tsig_key_type* key = NULL;
ldns_rdf* dname = NULL;
uint8_t* data = NULL;
int size = 0;
if (!tsig || !tsig->name || !tsig->secret) {
return NULL;
}
CHECKALLOC(key = (tsig_key_type*) malloc(sizeof(tsig_key_type)));
dname = ldns_dname_new_frm_str(tsig->name);
if (!dname) {
free(key);
return NULL;
}
CHECKALLOC(data = malloc(sizeof(uint8_t) * util_b64_pton_calculate_size(strlen(tsig->secret))));
size = b64_pton(tsig->secret, data,
util_b64_pton_calculate_size(strlen(tsig->secret)));
if (size < 0) {
ods_log_error("[%s] unable to create tsig key %s: failed to parse "
"secret", tsig_str, tsig->name);
ldns_rdf_deep_free(dname);
free(data);
free(key);
return NULL;
}
key->dname = dname;
key->size = size;
key->data = data;
tsig_handler_add_key(key);
return key;
}
tsig_type*
tsig_create(char* name, char* algo, char* secret)
{
tsig_type* tsig = NULL;
if (!name || !algo || !secret) {
return NULL;
}
CHECKALLOC(tsig = (tsig_type*) malloc(sizeof(tsig_type)));
tsig->next = NULL;
tsig->name = strdup(name);
tsig->algorithm = strdup(algo);
tsig->secret = strdup(secret);
tsig->key = tsig_key_create(tsig);
if (!tsig->key) {
ods_log_error("[%s] unable to create tsig: tsig_key_create() "
"failed", tsig_str);
tsig_cleanup(tsig);
return NULL;
}
return tsig;
}
tsig_type*
tsig_lookup_by_name(tsig_type* tsig, const char* name)
{
tsig_type* find = NULL;
if (!tsig || !name) {
return NULL;
}
find = tsig;
while (find) {
if (ods_strlowercmp(find->name, name) == 0) {
return find;
}
find = find->next;
}
return NULL;
}
tsig_algo_type*
tsig_lookup_algo(const char* name)
{
tsig_algo_table_type* entry = NULL;
for (entry = tsig_algo_table; entry; entry = entry->next) {
if (ods_strlowercmp(name, entry->algorithm->txt_name) == 0) {
return entry->algorithm;
}
}
return NULL;
}
tsig_rr_type*
tsig_rr_create()
{
tsig_rr_type* trr = NULL;
CHECKALLOC(trr = (tsig_rr_type*) malloc(sizeof(tsig_rr_type)));
trr->key_name = NULL;
trr->algo_name = NULL;
trr->mac_data = NULL;
trr->other_data = NULL;
tsig_rr_reset(trr, NULL, NULL);
return trr;
}
void
tsig_rr_reset(tsig_rr_type* trr, tsig_algo_type* algo, tsig_key_type* key)
{
if (!trr) {
return;
}
tsig_rr_free(trr);
trr->status = TSIG_NOT_PRESENT;
trr->position = 0;
trr->response_count = 0;
trr->update_since_last_prepare = 0;
trr->context = NULL;
trr->algo = algo;
trr->key = key;
trr->prior_mac_size = 0;
trr->prior_mac_data = NULL;
trr->signed_time_high = 0;
trr->signed_time_low = 0;
trr->signed_time_fudge = 0;
trr->mac_size = 0;
trr->original_query_id = 0;
trr->error_code = LDNS_RCODE_NOERROR;
trr->other_size = 0;
}
int
tsig_rr_parse(tsig_rr_type* trr, buffer_type* buffer)
{
uint16_t dname_len = 0;
ldns_rr_type type = 0;
ldns_rr_class klass = 0;
uint32_t ttl = 0;
uint16_t rdlen = 0;
uint16_t curpos = 0;
ods_log_assert(trr);
ods_log_assert(buffer);
trr->status = TSIG_NOT_PRESENT;
trr->position = buffer_position(buffer);
curpos = trr->position;
if (!buffer_skip_dname(buffer)) {
buffer_set_position(buffer, trr->position);
ods_log_debug("[%s] parse: skip key name failed", tsig_str);
return 0;
}
dname_len = buffer_position(buffer) - curpos;
buffer_set_position(buffer, curpos);
trr->key_name = ldns_dname_new_frm_data(dname_len,
(const void*) buffer_current(buffer));
if (!trr->key_name) {
buffer_set_position(buffer, trr->position);
ods_log_debug("[%s] parse: read key name failed", tsig_str);
return 0;
}
buffer_set_position(buffer, curpos + dname_len);
if (!buffer_available(buffer, 10)) {
ods_log_debug("[%s] parse: not enough available", tsig_str);
buffer_set_position(buffer, trr->position);
return 0;
}
type = (ldns_rr_type) buffer_read_u16(buffer);
klass = (ldns_rr_class) buffer_read_u16(buffer);
if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
/* not present */
ods_log_debug("[%s] parse: not TSIG or not ANY but %d:%d", tsig_str,
klass, type);
buffer_set_position(buffer, trr->position);
return 1;
}
ttl = buffer_read_u32(buffer);
rdlen = buffer_read_u16(buffer);
/* default to error */
trr->status = TSIG_ERROR;
trr->error_code = LDNS_RCODE_FORMERR;
if (ttl || !buffer_available(buffer, rdlen)) {
ods_log_debug("[%s] parse: TTL!=0 or RDLEN=0", tsig_str);
buffer_set_position(buffer, trr->position);
return 0;
}
curpos = buffer_position(buffer);
if (!buffer_skip_dname(buffer)) {
ods_log_debug("[%s] parse: skip algo name failed", tsig_str);
buffer_set_position(buffer, trr->position);
return 0;
}
dname_len = buffer_position(buffer) - curpos;
buffer_set_position(buffer, curpos);
trr->algo_name = ldns_dname_new_frm_data(dname_len,
(const void*) buffer_current(buffer));
if (!trr->algo_name) {
ods_log_debug("[%s] parse: read algo name failed", tsig_str);
buffer_set_position(buffer, trr->position);
return 0;
}
buffer_set_position(buffer, curpos + dname_len);
if (!buffer_available(buffer, 10)) {
ods_log_debug("[%s] parse: not enough available", tsig_str);
buffer_set_position(buffer, trr->position);
return 0;
}
trr->signed_time_high = buffer_read_u16(buffer);
trr->signed_time_low = buffer_read_u32(buffer);
trr->signed_time_fudge = buffer_read_u16(buffer);
trr->mac_size = buffer_read_u16(buffer);
if (!buffer_available(buffer, trr->mac_size)) {
ods_log_debug("[%s] parse: wrong mac size", tsig_str);
buffer_set_position(buffer, trr->position);
trr->mac_size = 0;
return 0;
}
CHECKALLOC(trr->mac_data = (uint8_t *) malloc(trr->mac_size));
memcpy(trr->mac_data, (const void*) buffer_current(buffer), trr->mac_size);
buffer_skip(buffer, trr->mac_size);
if (!buffer_available(buffer, 6)) {
ods_log_debug("[%s] parse: not enough available", tsig_str);
buffer_set_position(buffer, trr->position);
return 0;
}
trr->original_query_id = buffer_read_u16(buffer);
trr->error_code = buffer_read_u16(buffer);
trr->other_size = buffer_read_u16(buffer);
if (!buffer_available(buffer, trr->other_size) || trr->other_size > 16) {
ods_log_debug("[%s] parse: not enough available", tsig_str);
trr->other_size = 0;
buffer_set_position(buffer, trr->position);
return 0;
}
CHECKALLOC(trr->other_data = (uint8_t *) malloc(trr->other_size));
memcpy(trr->other_data, (const void*) buffer_current(buffer), trr->other_size);
buffer_skip(buffer, trr->other_size);
trr->status = TSIG_OK;
return 1;
}
int
tsig_rr_find(tsig_rr_type* trr, buffer_type* buffer)
{
size_t saved_pos = 0;
size_t rrcount = 0;
size_t i = 0;
int result = 0;
ods_log_assert(trr);
ods_log_assert(buffer);
if (buffer_pkt_arcount(buffer) == 0) {
trr->status = TSIG_NOT_PRESENT;
return 1;
}
saved_pos = buffer_position(buffer);
rrcount = buffer_pkt_qdcount(buffer) + buffer_pkt_ancount(buffer) +
buffer_pkt_nscount(buffer) + buffer_pkt_arcount(buffer);
rrcount &= 0x3FFFF; /* un-taint rrcount */
buffer_set_position(buffer, BUFFER_PKT_HEADER_SIZE);
for (i=0; i < rrcount - 1; i++) {
if (!buffer_skip_rr(buffer, i < (buffer_pkt_qdcount(buffer)&0xFFFF))) {
buffer_set_position(buffer, saved_pos);
return 0;
}
}
result = tsig_rr_parse(trr, buffer);
buffer_set_position(buffer, saved_pos);
return result;
}
int
tsig_rr_lookup(tsig_rr_type* trr)
{
tsig_key_table_type* kentry = NULL;
tsig_key_type* key = NULL;
tsig_algo_table_type* aentry = NULL;
tsig_algo_type* algorithm = NULL;
uint64_t current_time = 0;
uint64_t signed_time = 0;
ods_log_assert(trr);
ods_log_assert(trr->status == TSIG_OK);
ods_log_assert(!trr->algo);
ods_log_assert(!trr->key);
for (kentry = tsig_key_table; kentry; kentry = kentry->next) {
if (ldns_dname_compare(trr->key_name, kentry->key->dname) == 0) {
key = kentry->key;
break;
}
}
for (aentry = tsig_algo_table; aentry; aentry = aentry->next) {
if (ldns_dname_compare(trr->algo_name,
aentry->algorithm->wf_name) == 0) {
algorithm = aentry->algorithm;
break;
}
}
if (!key || !algorithm) {
/* algorithm or key is unknown, cannot authenticate. */
ods_log_debug("[%s] algorithm or key missing", tsig_str);
trr->error_code = TSIG_ERROR_BADKEY;
return 0;
}
if ((trr->algo && algorithm != trr->algo) ||
(trr->key && key != trr->key)) {
/* algorithm or key changed during a single connection, error. */
ods_log_debug("[%s] algorithm or key has changed", tsig_str);
trr->error_code = TSIG_ERROR_BADKEY;
return 0;
}
signed_time = ((((uint64_t) trr->signed_time_high) << 32) |
((uint64_t) trr->signed_time_low));
current_time = (uint64_t) time_now();
if ((current_time < signed_time - trr->signed_time_fudge) ||
(current_time > signed_time + trr->signed_time_fudge)) {
uint16_t current_time_high;
uint32_t current_time_low;
trr->error_code = TSIG_ERROR_BADTIME;
current_time_high = (uint16_t) (current_time >> 32);
current_time_low = (uint32_t) current_time;
trr->other_size = 6;
CHECKALLOC(trr->other_data = (uint8_t *) malloc(sizeof(uint16_t) + sizeof(uint32_t)));
write_uint16(trr->other_data, current_time_high);
write_uint32(trr->other_data + 2, current_time_low);
ods_log_debug("[%s] bad time", tsig_str);
return 0;
}
trr->algo = algorithm;
trr->key = key;
trr->response_count = 0;
trr->prior_mac_size = 0;
return 1;
}
void
tsig_rr_prepare(tsig_rr_type* trr)
{
ods_log_assert(trr->algo);
if (!trr->context) {
trr->context = trr->algo->hmac_create();
CHECKALLOC(trr->prior_mac_data = (uint8_t *) malloc(trr->algo->max_digest_size));
}
trr->algo->hmac_init(trr->context, trr->algo, trr->key);
if (trr->prior_mac_size > 0) {
uint16_t mac_size = htons(trr->prior_mac_size);
trr->algo->hmac_update(trr->context, &mac_size, sizeof(mac_size));
trr->algo->hmac_update(trr->context, trr->prior_mac_data,
trr->prior_mac_size);
}
trr->update_since_last_prepare = 0;
}
void
tsig_rr_update(tsig_rr_type* trr, buffer_type* buffer, size_t length)
{
uint16_t original_query_id = 0;
ods_log_assert(trr);
ods_log_assert(trr->algo);
ods_log_assert(trr->context);
ods_log_assert(buffer);
ods_log_assert(length <= buffer_limit(buffer));
original_query_id = htons(trr->original_query_id);
trr->algo->hmac_update(trr->context, &original_query_id,
sizeof(original_query_id));
trr->algo->hmac_update(trr->context,
buffer_at(buffer, sizeof(original_query_id)),
length - sizeof(original_query_id));
if (buffer_pkt_qr(buffer)) {
++trr->response_count;
}
++trr->update_since_last_prepare;
}
static void
tsig_rr_digest_variables(tsig_rr_type* trr, int tsig_timers_only)
{
uint16_t klass = htons(LDNS_RR_CLASS_ANY);
uint32_t ttl = htonl(0);
uint16_t signed_time_high = htons(trr->signed_time_high);
uint32_t signed_time_low = htonl(trr->signed_time_low);
uint16_t signed_time_fudge = htons(trr->signed_time_fudge);
uint16_t error_code = htons(trr->error_code);
uint16_t other_size = htons(trr->other_size);
ods_log_assert(trr->context);
ods_log_assert(trr->algo);
ods_log_assert(trr->key_name);
if (!tsig_timers_only) {
ods_log_assert(trr->key_name);
ods_log_assert(trr->algo_name);
trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->key_name),
ldns_rdf_size(trr->key_name));
trr->algo->hmac_update(trr->context, &klass, sizeof(klass));
trr->algo->hmac_update(trr->context, &ttl, sizeof(ttl));
trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->algo_name),
ldns_rdf_size(trr->algo_name));
}
trr->algo->hmac_update(trr->context, &signed_time_high,
sizeof(signed_time_high));
trr->algo->hmac_update(trr->context, &signed_time_low,
sizeof(signed_time_low));
trr->algo->hmac_update(trr->context, &signed_time_fudge,
sizeof(signed_time_fudge));
if (!tsig_timers_only) {
trr->algo->hmac_update(trr->context, &error_code,
sizeof(error_code));
trr->algo->hmac_update(trr->context, &other_size,
sizeof(other_size));
trr->algo->hmac_update(trr->context, trr->other_data,
trr->other_size);
}
}
void
tsig_rr_sign(tsig_rr_type* trr)
{
uint64_t current_time = (uint64_t) time_now();
ods_log_assert(trr);
ods_log_assert(trr->context);
trr->signed_time_high = (uint16_t) (current_time >> 32);
trr->signed_time_low = (uint32_t) current_time;
trr->signed_time_fudge = TSIG_SIGNED_TIME_FUDGE;
tsig_rr_digest_variables(trr, trr->response_count > 1);
trr->algo->hmac_final(trr->context, trr->prior_mac_data,
&trr->prior_mac_size);
trr->mac_size = trr->prior_mac_size;
trr->mac_data = trr->prior_mac_data;
}
int
tsig_rr_verify(tsig_rr_type* trr)
{
ods_log_assert(trr);
ods_log_assert(trr->algo);
tsig_rr_digest_variables(trr, trr->response_count > 1);
trr->algo->hmac_final(trr->context, trr->prior_mac_data,
&trr->prior_mac_size);
if (trr->mac_size != trr->prior_mac_size ||
memcmp(trr->mac_data, trr->prior_mac_data, trr->mac_size) != 0) {
/* digest is incorrect, cannot authenticate. */
trr->error_code = TSIG_ERROR_BADSIG;
return 0;
}
return 1;
}
void
tsig_rr_append(tsig_rr_type* trr, buffer_type* buffer)
{
size_t rdlength_pos = 0;
if (!trr || !buffer) {
return;
}
/* [TODO] key name compression? */
if (trr->key_name) {
buffer_write_rdf(buffer, trr->key_name);
} else {
buffer_write_u8(buffer, 0);
}
buffer_write_u16(buffer, (uint16_t)LDNS_RR_TYPE_TSIG);
buffer_write_u16(buffer, (uint16_t)LDNS_RR_CLASS_ANY);
buffer_write_u32(buffer, 0); /* TTL */
rdlength_pos = buffer_position(buffer);
buffer_skip(buffer, sizeof(uint16_t));
if (trr->algo_name) {
buffer_write_rdf(buffer, trr->algo_name);
} else {
buffer_write_u8(buffer, 0);
}
buffer_write_u16(buffer, trr->signed_time_high);
buffer_write_u32(buffer, trr->signed_time_low);
buffer_write_u16(buffer, trr->signed_time_fudge);
buffer_write_u16(buffer, trr->mac_size);
buffer_write(buffer, trr->mac_data, trr->mac_size);
buffer_write_u16(buffer, trr->original_query_id);
buffer_write_u16(buffer, trr->error_code);
buffer_write_u16(buffer, trr->other_size);
buffer_write(buffer, trr->other_data, trr->other_size);
buffer_write_u16_at(buffer, rdlength_pos,
buffer_position(buffer) - rdlength_pos - sizeof(uint16_t));
}
/*
* The amount of space to reserve in the response for the TSIG data.
*
*/
size_t
tsig_rr_reserved_space(tsig_rr_type* trr)
{
if (!trr || trr->status == TSIG_NOT_PRESENT) {
return 0;
}
return (
(trr->key_name?ldns_rdf_size(trr->key_name):1)
+ sizeof(uint16_t) /* Type */
+ sizeof(uint16_t) /* Class */
+ sizeof(uint32_t) /* TTL */
+ sizeof(uint16_t) /* RDATA length */
+ (trr->algo_name?ldns_rdf_size(trr->algo_name):1)
+ sizeof(uint16_t) /* Signed time (high) */
+ sizeof(uint32_t) /* Signed time (low) */
+ sizeof(uint16_t) /* Signed time fudge */
+ sizeof(uint16_t) /* MAC size */
+ max_algo_digest_size /* MAC data */
+ sizeof(uint16_t) /* Original query ID */
+ sizeof(uint16_t) /* Error code */
+ sizeof(uint16_t) /* Other size */
+ trr->other_size); /* Other data */
}
void
tsig_rr_error(tsig_rr_type* trr)
{
if (!trr) {
return;
}
if (trr->mac_data) {
memset(trr->mac_data, 0, trr->mac_size);
}
trr->mac_size = 0;
}
const char*
tsig_status2str(tsig_status status)
{
switch (status) {
case TSIG_NOT_PRESENT:
return "NOT PRESENT";
case TSIG_OK:
return "OK";
case TSIG_ERROR:
return "ERROR";
}
return "UNKNOWN";
}
const char*
tsig_strerror(uint16_t error)
{
static char message[1000];
switch (error) {
case 0:
return "No Error";
break;
case TSIG_ERROR_BADSIG:
return "Bad Signature";
break;
case TSIG_ERROR_BADKEY:
return "Bad Key";
break;
case TSIG_ERROR_BADTIME:
return "Bad Time";
break;
default:
if (error < 16) {
/* DNS rcodes */
return (const char*) ldns_pkt_rcode2str(error);
}
snprintf(message, sizeof(message), "Unknown Error %d", error);
break;
}
return message;
}
void
tsig_rr_free(tsig_rr_type* trr)
{
if (!trr) {
return;
}
ldns_rdf_deep_free(trr->key_name);
ldns_rdf_deep_free(trr->algo_name);
free(trr->mac_data);
free(trr->other_data);
trr->key_name = NULL;
trr->algo_name = NULL;
trr->mac_data = NULL;
trr->other_data = NULL;
}
void
tsig_rr_cleanup(tsig_rr_type* trr)
{
if (!trr) {
return;
}
tsig_rr_free(trr);
free(trr);
}
void
tsig_cleanup(tsig_type* tsig)
{
if (!tsig) {
return;
}
tsig_cleanup(tsig->next);
free((void*)tsig->name);
free((void*)tsig->algorithm);
free((void*)tsig->secret);
free(tsig);
}
buffer_available
int buffer_available(buffer_type *buffer, size_t count)
Definition buffer.c:487
buffer_pkt_qdcount
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition buffer.c:994
buffer_skip_rr
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition buffer.c:342
buffer_read_u32
uint32_t buffer_read_u32(buffer_type *buffer)
Definition buffer.c:736
buffer_read_u16
uint16_t buffer_read_u16(buffer_type *buffer)
Definition buffer.c:721
buffer_current
uint8_t * buffer_current(buffer_type *buffer)
Definition buffer.c:438
buffer_write_u8
void buffer_write_u8(buffer_type *buffer, uint8_t data)
Definition buffer.c:552
buffer_set_position
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition buffer.c:137
buffer_pkt_qr
int buffer_pkt_qr(buffer_type *buffer)
Definition buffer.c:810
buffer_at
uint8_t * buffer_at(buffer_type *buffer, size_t at)
Definition buffer.c:413
buffer_position
size_t buffer_position(buffer_type *buffer)
Definition buffer.c:125
buffer_pkt_arcount
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition buffer.c:1066
buffer_write
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition buffer.c:538
buffer_write_rdf
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition buffer.c:591
buffer_write_u16_at
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition buffer.c:512
buffer_skip
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition buffer.c:150
buffer_skip_dname
int buffer_skip_dname(buffer_type *buffer)
Definition buffer.c:310
buffer_write_u32
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition buffer.c:578
buffer_write_u16
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition buffer.c:565
buffer_limit
size_t buffer_limit(buffer_type *buffer)
Definition buffer.c:373
buffer_pkt_ancount
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition buffer.c:1018
buffer_pkt_nscount
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition buffer.c:1042
buffer.h
BUFFER_PKT_HEADER_SIZE
#define BUFFER_PKT_HEADER_SIZE
Definition buffer.h:43
buffer_type
struct buffer_struct buffer_type
Definition buffer.h:111
tsig_algo_struct::wf_name
ldns_rdf * wf_name
Definition tsig.h:91
tsig_algo_struct::max_digest_size
size_t max_digest_size
Definition tsig.h:92
tsig_algo_struct::hmac_final
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition tsig.h:102
tsig_algo_struct::hmac_create
void *(* hmac_create)(void)
Definition tsig.h:95
tsig_algo_struct::txt_name
const char * txt_name
Definition tsig.h:90
tsig_algo_struct::hmac_init
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition tsig.h:97
tsig_algo_struct::hmac_update
void(* hmac_update)(void *context, const void *data, size_t size)
Definition tsig.h:100
tsig_algo_table_struct
Definition tsig.c:59
tsig_algo_table_struct::algorithm
tsig_algo_type * algorithm
Definition tsig.c:61
tsig_algo_table_struct::next
tsig_algo_table_type * next
Definition tsig.c:60
tsig_key_struct::dname
ldns_rdf * dname
Definition tsig.h:79
tsig_key_struct::data
const uint8_t * data
Definition tsig.h:81
tsig_key_struct::size
size_t size
Definition tsig.h:80
tsig_key_table_struct
Definition tsig.c:52
tsig_key_table_struct::key
tsig_key_type * key
Definition tsig.c:54
tsig_key_table_struct::next
tsig_key_table_type * next
Definition tsig.c:53
tsig_rr_struct::algo
tsig_algo_type * algo
Definition tsig.h:129
tsig_rr_struct::context
void * context
Definition tsig.h:128
tsig_rr_struct::prior_mac_size
size_t prior_mac_size
Definition tsig.h:131
tsig_rr_struct::position
size_t position
Definition tsig.h:125
tsig_rr_struct::key
tsig_key_type * key
Definition tsig.h:130
tsig_rr_struct::error_code
uint16_t error_code
Definition tsig.h:142
tsig_rr_struct::response_count
size_t response_count
Definition tsig.h:126
tsig_rr_struct::other_size
uint16_t other_size
Definition tsig.h:143
tsig_rr_struct::update_since_last_prepare
size_t update_since_last_prepare
Definition tsig.h:127
tsig_rr_struct::signed_time_high
uint16_t signed_time_high
Definition tsig.h:136
tsig_rr_struct::signed_time_low
uint32_t signed_time_low
Definition tsig.h:137
tsig_rr_struct::mac_data
uint8_t * mac_data
Definition tsig.h:140
tsig_rr_struct::status
tsig_status status
Definition tsig.h:124
tsig_rr_struct::prior_mac_data
uint8_t * prior_mac_data
Definition tsig.h:132
tsig_rr_struct::original_query_id
uint16_t original_query_id
Definition tsig.h:141
tsig_rr_struct::signed_time_fudge
uint16_t signed_time_fudge
Definition tsig.h:138
tsig_rr_struct::algo_name
ldns_rdf * algo_name
Definition tsig.h:135
tsig_rr_struct::other_data
uint8_t * other_data
Definition tsig.h:144
tsig_rr_struct::mac_size
uint16_t mac_size
Definition tsig.h:139
tsig_rr_struct::key_name
ldns_rdf * key_name
Definition tsig.h:134
tsig_struct::key
tsig_key_type * key
Definition tsig.h:115
tsig_struct::secret
const char * secret
Definition tsig.h:114
tsig_struct::name
const char * name
Definition tsig.h:112
tsig_struct::algorithm
const char * algorithm
Definition tsig.h:113
tsig_struct::next
tsig_type * next
Definition tsig.h:111
tsig-openssl.h
tsig_rr_lookup
int tsig_rr_lookup(tsig_rr_type *trr)
Definition tsig.c:469
tsig_rr_cleanup
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition tsig.c:832
tsig_algo_table_type
struct tsig_algo_table_struct tsig_algo_table_type
Definition tsig.c:58
tsig_strerror
const char * tsig_strerror(uint16_t error)
Definition tsig.c:778
tsig_handler_init
ods_status tsig_handler_init()
Definition tsig.c:116
tsig_rr_verify
int tsig_rr_verify(tsig_rr_type *trr)
Definition tsig.c:650
TSIG_SIGNED_TIME_FUDGE
#define TSIG_SIGNED_TIME_FUDGE
Definition tsig.c:47
tsig_create
tsig_type * tsig_create(char *name, char *algo, char *secret)
Definition tsig.c:208
tsig_rr_error
void tsig_rr_error(tsig_rr_type *trr)
Definition tsig.c:742
tsig_rr_reserved_space
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition tsig.c:713
tsig_handler_add_algo
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition tsig.c:93
tsig_cleanup
void tsig_cleanup(tsig_type *tsig)
Definition tsig.c:847
tsig_rr_append
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition tsig.c:672
tsig_status2str
const char * tsig_status2str(tsig_status status)
Definition tsig.c:759
tsig_rr_sign
void tsig_rr_sign(tsig_rr_type *trr)
Definition tsig.c:629
tsig_rr_parse
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition tsig.c:322
tsig_rr_free
void tsig_rr_free(tsig_rr_type *trr)
Definition tsig.c:811
tsig_handler_add_key
void tsig_handler_add_key(tsig_key_type *key)
Definition tsig.c:73
tsig_rr_reset
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition tsig.c:292
tsig_rr_update
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition tsig.c:559
tsig_rr_prepare
void tsig_rr_prepare(tsig_rr_type *trr)
Definition tsig.c:537
tsig_rr_create
tsig_rr_type * tsig_rr_create()
Definition tsig.c:274
tsig_handler_cleanup
void tsig_handler_cleanup(void)
Definition tsig.c:135
tsig_key_table_type
struct tsig_key_table_struct tsig_key_table_type
Definition tsig.c:51
tsig_rr_find
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
Definition tsig.c:435
tsig_lookup_algo
tsig_algo_type * tsig_lookup_algo(const char *name)
Definition tsig.c:257
tsig_lookup_by_name
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
Definition tsig.c:235
tsig.h
tsig_algo_type
struct tsig_algo_struct tsig_algo_type
Definition tsig.h:88
TSIG_ERROR_BADSIG
#define TSIG_ERROR_BADSIG
Definition tsig.h:43
tsig_type
struct tsig_struct tsig_type
Definition tsig.h:109
tsig_rr_type
struct tsig_rr_struct tsig_rr_type
Definition tsig.h:122
tsig_key_type
struct tsig_key_struct tsig_key_type
Definition tsig.h:77
TSIG_ERROR_BADKEY
#define TSIG_ERROR_BADKEY
Definition tsig.h:44
TSIG_OK
@ TSIG_OK
Definition tsig.h:57
TSIG_ERROR
@ TSIG_ERROR
Definition tsig.h:58
TSIG_NOT_PRESENT
@ TSIG_NOT_PRESENT
Definition tsig.h:56
tsig_status
enum tsig_status_enum tsig_status
Definition tsig.h:60
TSIG_ERROR_BADTIME
#define TSIG_ERROR_BADTIME
Definition tsig.h:45