47#define TSIG_SIGNED_TIME_FUDGE 300
49static const char* tsig_str =
"tsig";
65static size_t max_algo_digest_size = 0;
82 entry->
next = tsig_key_table;
83 tsig_key_table = entry;
102 entry->
next = tsig_algo_table;
103 tsig_algo_table = entry;
118 tsig_key_table = NULL;
119 tsig_algo_table = NULL;
121 ods_log_debug(
"[%s] init openssl", tsig_str);
122 return tsig_handler_openssl_init();
124 ods_log_debug(
"[%s] openssl disabled", tsig_str);
125 return ODS_STATUS_OK;
140 tsig_handler_openssl_finalize();
143 aentry = tsig_algo_table;
145 anext = aentry->
next;
152 kentry = tsig_key_table;
154 knext = kentry->
next;
155 ldns_rdf_deep_free(kentry->
key->
dname);
156 free((
void*)kentry->
key->
data);
157 free((
void*)kentry->
key);
172 ldns_rdf* dname = NULL;
173 uint8_t* data = NULL;
179 dname = ldns_dname_new_frm_str(tsig->
name);
184 CHECKALLOC(data = malloc(
sizeof(uint8_t) * util_b64_pton_calculate_size(strlen(tsig->
secret))));
185 size = b64_pton(tsig->
secret, data,
186 util_b64_pton_calculate_size(strlen(tsig->
secret)));
188 ods_log_error(
"[%s] unable to create tsig key %s: failed to parse "
189 "secret", tsig_str, tsig->
name);
190 ldns_rdf_deep_free(dname);
211 if (!name || !algo || !secret) {
216 tsig->
name = strdup(name);
218 tsig->
secret = strdup(secret);
219 tsig->
key = tsig_key_create(tsig);
221 ods_log_error(
"[%s] unable to create tsig: tsig_key_create() "
238 if (!tsig || !name) {
243 if (ods_strlowercmp(find->
name, name) == 0) {
260 for (entry = tsig_algo_table; entry; entry = entry->
next) {
324 uint16_t dname_len = 0;
325 ldns_rr_type type = 0;
326 ldns_rr_class klass = 0;
331 ods_log_assert(buffer);
337 ods_log_debug(
"[%s] parse: skip key name failed", tsig_str);
342 trr->
key_name = ldns_dname_new_frm_data(dname_len,
346 ods_log_debug(
"[%s] parse: read key name failed", tsig_str);
351 ods_log_debug(
"[%s] parse: not enough available", tsig_str);
357 if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
359 ods_log_debug(
"[%s] parse: not TSIG or not ANY but %d:%d", tsig_str,
370 ods_log_debug(
"[%s] parse: TTL!=0 or RDLEN=0", tsig_str);
376 ods_log_debug(
"[%s] parse: skip algo name failed", tsig_str);
382 trr->
algo_name = ldns_dname_new_frm_data(dname_len,
385 ods_log_debug(
"[%s] parse: read algo name failed", tsig_str);
391 ods_log_debug(
"[%s] parse: not enough available", tsig_str);
400 ods_log_debug(
"[%s] parse: wrong mac size", tsig_str);
409 ods_log_debug(
"[%s] parse: not enough available", tsig_str);
417 ods_log_debug(
"[%s] parse: not enough available", tsig_str);
437 size_t saved_pos = 0;
442 ods_log_assert(buffer);
452 for (i=0; i < rrcount - 1; i++) {
475 uint64_t current_time = 0;
476 uint64_t signed_time = 0;
479 ods_log_assert(!trr->
algo);
480 ods_log_assert(!trr->
key);
481 for (kentry = tsig_key_table; kentry; kentry = kentry->
next) {
487 for (aentry = tsig_algo_table; aentry; aentry = aentry->
next) {
494 if (!key || !algorithm) {
496 ods_log_debug(
"[%s] algorithm or key missing", tsig_str);
500 if ((trr->
algo && algorithm != trr->
algo) ||
501 (trr->
key && key != trr->
key)) {
503 ods_log_debug(
"[%s] algorithm or key has changed", tsig_str);
509 current_time = (uint64_t) time_now();
510 if ((current_time < signed_time - trr->signed_time_fudge) ||
512 uint16_t current_time_high;
513 uint32_t current_time_low;
515 current_time_high = (uint16_t) (current_time >> 32);
516 current_time_low = (uint32_t) current_time;
518 CHECKALLOC(trr->
other_data = (uint8_t *) malloc(
sizeof(uint16_t) +
sizeof(uint32_t)));
519 write_uint16(trr->
other_data, current_time_high);
520 write_uint32(trr->
other_data + 2, current_time_low);
521 ods_log_debug(
"[%s] bad time", tsig_str);
524 trr->
algo = algorithm;
539 ods_log_assert(trr->
algo);
561 uint16_t original_query_id = 0;
563 ods_log_assert(trr->
algo);
565 ods_log_assert(buffer);
569 sizeof(original_query_id));
571 buffer_at(buffer,
sizeof(original_query_id)),
572 length -
sizeof(original_query_id));
585tsig_rr_digest_variables(
tsig_rr_type* trr,
int tsig_timers_only)
587 uint16_t klass = htons(LDNS_RR_CLASS_ANY);
588 uint32_t ttl = htonl(0);
595 ods_log_assert(trr->
algo);
597 if (!tsig_timers_only) {
608 sizeof(signed_time_high));
610 sizeof(signed_time_low));
612 sizeof(signed_time_fudge));
613 if (!tsig_timers_only) {
631 uint64_t current_time = (uint64_t) time_now();
653 ods_log_assert(trr->
algo);
674 size_t rdlength_pos = 0;
675 if (!trr || !buffer) {
729 + max_algo_digest_size
763 return "NOT PRESENT";
780 static char message[1000];
786 return "Bad Signature";
797 return (
const char*) ldns_pkt_rcode2str(error);
799 snprintf(message,
sizeof(message),
"Unknown Error %d", error);
853 free((
void*)tsig->
name);
855 free((
void*)tsig->
secret);
int buffer_available(buffer_type *buffer, size_t count)
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
uint32_t buffer_read_u32(buffer_type *buffer)
uint16_t buffer_read_u16(buffer_type *buffer)
uint8_t * buffer_current(buffer_type *buffer)
void buffer_write_u8(buffer_type *buffer, uint8_t data)
void buffer_set_position(buffer_type *buffer, size_t pos)
int buffer_pkt_qr(buffer_type *buffer)
uint8_t * buffer_at(buffer_type *buffer, size_t at)
size_t buffer_position(buffer_type *buffer)
uint16_t buffer_pkt_arcount(buffer_type *buffer)
void buffer_write(buffer_type *buffer, const void *data, size_t count)
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
void buffer_skip(buffer_type *buffer, ssize_t count)
int buffer_skip_dname(buffer_type *buffer)
void buffer_write_u32(buffer_type *buffer, uint32_t data)
void buffer_write_u16(buffer_type *buffer, uint16_t data)
size_t buffer_limit(buffer_type *buffer)
uint16_t buffer_pkt_ancount(buffer_type *buffer)
uint16_t buffer_pkt_nscount(buffer_type *buffer)
#define BUFFER_PKT_HEADER_SIZE
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
void *(* hmac_create)(void)
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
void(* hmac_update)(void *context, const void *data, size_t size)
tsig_algo_type * algorithm
tsig_algo_table_type * next
tsig_key_table_type * next
size_t update_since_last_prepare
uint16_t signed_time_high
uint16_t original_query_id
uint16_t signed_time_fudge
int tsig_rr_lookup(tsig_rr_type *trr)
void tsig_rr_cleanup(tsig_rr_type *trr)
const char * tsig_strerror(uint16_t error)
ods_status tsig_handler_init()
int tsig_rr_verify(tsig_rr_type *trr)
#define TSIG_SIGNED_TIME_FUDGE
tsig_type * tsig_create(char *name, char *algo, char *secret)
void tsig_rr_error(tsig_rr_type *trr)
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
void tsig_handler_add_algo(tsig_algo_type *algo)
void tsig_cleanup(tsig_type *tsig)
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
const char * tsig_status2str(tsig_status status)
void tsig_rr_sign(tsig_rr_type *trr)
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
void tsig_rr_free(tsig_rr_type *trr)
void tsig_handler_add_key(tsig_key_type *key)
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
void tsig_rr_prepare(tsig_rr_type *trr)
tsig_rr_type * tsig_rr_create()
void tsig_handler_cleanup(void)
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
tsig_algo_type * tsig_lookup_algo(const char *name)
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
#define TSIG_ERROR_BADSIG
#define TSIG_ERROR_BADKEY
enum tsig_status_enum tsig_status
#define TSIG_ERROR_BADTIME