47 #include <arpa/inet.h>
49 #define TSIG_SIGNED_TIME_FUDGE 300
51 static const char* tsig_str =
"tsig";
69 static size_t max_algo_digest_size = 0;
76 #ifdef HAVE_EVP_SHA256
98 entry->
next = tsig_key_table;
99 tsig_key_table = entry;
120 entry->
next = tsig_algo_table;
121 tsig_algo_table = entry;
140 tsig_allocator = allocator;
141 tsig_key_table = NULL;
142 tsig_algo_table = NULL;
145 return tsig_handler_openssl_init(allocator);
162 tsig_handler_openssl_finalize();
165 aentry = tsig_algo_table;
167 anext = aentry->
next;
174 kentry = tsig_key_table;
176 knext = kentry->
next;
177 ldns_rdf_deep_free(kentry->
key->
dname);
195 ldns_rdf* dname = NULL;
196 uint8_t* data = NULL;
198 if (!allocator || !tsig || !tsig->
name || !tsig->
secret) {
205 dname = ldns_dname_new_frm_str(tsig->
name);
212 ldns_rdf_deep_free(dname);
215 size = b64_pton(tsig->
secret, data,
218 ods_log_error(
"[%s] unable to create tsig key %s: failed to parse "
219 "secret", tsig_str, tsig->
name);
220 ldns_rdf_deep_free(dname);
239 if (!allocator || !name || !algo || !secret) {
244 ods_log_error(
"[%s] unable to create tsig: allocator_alloc() "
254 ods_log_error(
"[%s] unable to create tsig: tsig_key_create() "
271 if (!tsig || !name) {
293 for (entry = tsig_algo_table; entry; entry = entry->
next) {
315 ods_log_error(
"[%s] unable to create tsig rr: allocator_alloc() "
367 uint16_t dname_len = 0;
368 ldns_rr_type type = 0;
369 ldns_rr_class klass = 0;
386 trr->
key_name = ldns_dname_new_frm_data(dname_len,
401 if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
420 ods_log_debug(
"[%s] parse: skip algo name failed", tsig_str);
426 trr->
algo_name = ldns_dname_new_frm_data(dname_len,
429 ods_log_debug(
"[%s] parse: read algo name failed", tsig_str);
481 size_t saved_pos = 0;
495 for (i=0; i < rrcount - 1; i++) {
518 uint64_t current_time = 0;
519 uint64_t signed_time = 0;
524 for (kentry = tsig_key_table; kentry; kentry = kentry->
next) {
530 for (aentry = tsig_algo_table; aentry; aentry = aentry->
next) {
537 if (!key || !algorithm) {
543 if ((trr->
algo && algorithm != trr->
algo) ||
544 (trr->
key && key != trr->
key)) {
546 ods_log_debug(
"[%s] algorithm or key has changed", tsig_str);
552 current_time = (uint64_t)
time_now();
553 if ((current_time < signed_time - trr->signed_time_fudge) ||
555 uint16_t current_time_high;
556 uint32_t current_time_low;
558 current_time_high = (uint16_t) (current_time >> 32);
559 current_time_low = (uint32_t) current_time;
562 sizeof(uint16_t) +
sizeof(uint32_t));
563 write_uint16(trr->
other_data, current_time_high);
564 write_uint32(trr->
other_data + 2, current_time_low);
568 trr->
algo = algorithm;
608 uint16_t original_query_id = 0;
616 sizeof(original_query_id));
618 buffer_at(buffer,
sizeof(original_query_id)),
619 length -
sizeof(original_query_id));
633 tsig_rr_digest_variables(
tsig_rr_type* trr,
int tsig_timers_only)
635 uint16_t klass = htons(LDNS_RR_CLASS_ANY);
636 uint32_t ttl = htonl(0);
645 if (!tsig_timers_only) {
656 sizeof(signed_time_high));
658 sizeof(signed_time_low));
660 sizeof(signed_time_fudge));
661 if (!tsig_timers_only) {
680 uint64_t current_time = (uint64_t)
time_now();
724 size_t rdlength_pos = 0;
725 if (!trr || !buffer) {
780 + max_algo_digest_size
815 return "NOT PRESENT";
832 static char message[1000];
838 return "Bad Signature";
849 return (
const char*) ldns_pkt_rcode2str(error);
851 snprintf(message,
sizeof(message),
"Unknown Error %d", error);
905 if (!tsig || !allocator) {
void(* hmac_update)(void *context, const void *data, size_t size)
#define TSIG_ERROR_BADTIME
void tsig_rr_free(tsig_rr_type *trr)
void tsig_handler_cleanup(void)
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
tsig_algo_table_type * next
allocator_type * allocator
tsig_algo_type * algorithm
uint16_t signed_time_high
void ods_log_debug(const char *format,...)
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
uint8_t * buffer_at(buffer_type *buffer, size_t at)
uint16_t buffer_pkt_arcount(buffer_type *buffer)
#define BUFFER_PKT_HEADER_SIZE
void * allocator_alloc(allocator_type *allocator, size_t size)
const char * tsig_strerror(uint16_t error)
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
void buffer_skip(buffer_type *buffer, ssize_t count)
uint16_t buffer_read_u16(buffer_type *buffer)
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
#define TSIG_SIGNED_TIME_FUDGE
size_t util_b64_pton_calculate_size(size_t srcsize)
enum ods_enum_status ods_status
void buffer_write_u8(buffer_type *buffer, uint8_t data)
tsig_algo_type * tsig_lookup_algo(const char *name)
void ods_log_error(const char *format,...)
int buffer_pkt_qr(buffer_type *buffer)
ods_status tsig_handler_init(allocator_type *allocator)
uint16_t signed_time_fudge
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
size_t update_since_last_prepare
void buffer_write(buffer_type *buffer, const void *data, size_t count)
uint8_t * buffer_current(buffer_type *buffer)
size_t buffer_limit(buffer_type *buffer)
uint16_t buffer_pkt_ancount(buffer_type *buffer)
void tsig_rr_prepare(tsig_rr_type *trr)
void tsig_cleanup(tsig_type *tsig, allocator_type *allocator)
const char * tsig_status2str(tsig_status status)
void tsig_handler_add_key(tsig_key_type *key)
void *(* hmac_create)(allocator_type *allocator)
void tsig_rr_cleanup(tsig_rr_type *trr)
int buffer_skip_dname(buffer_type *buffer)
char * allocator_strdup(allocator_type *allocator, const char *string)
uint32_t buffer_read_u32(buffer_type *buffer)
int tsig_rr_verify(tsig_rr_type *trr)
void buffer_write_u16(buffer_type *buffer, uint16_t data)
void buffer_write_u32(buffer_type *buffer, uint32_t data)
#define TSIG_ERROR_BADSIG
tsig_rr_type * tsig_rr_create(allocator_type *allocator)
void tsig_rr_error(tsig_rr_type *trr)
uint16_t buffer_pkt_nscount(buffer_type *buffer)
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
tsig_type * tsig_create(allocator_type *allocator, char *name, char *algo, char *secret)
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
void buffer_set_position(buffer_type *buffer, size_t pos)
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
int buffer_available(buffer_type *buffer, size_t count)
int tsig_rr_lookup(tsig_rr_type *trr)
#define TSIG_ERROR_BADKEY
tsig_lookup_table tsig_supported_algorithms[]
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
void tsig_rr_sign(tsig_rr_type *trr)
void allocator_deallocate(allocator_type *allocator, void *data)
void * allocator_alloc_init(allocator_type *allocator, size_t size, const void *init)
size_t buffer_position(buffer_type *buffer)
tsig_key_type * tsig_key_create(allocator_type *allocator, tsig_type *tsig)
tsig_key_table_type * next
int ods_strlowercmp(const char *str1, const char *str2)
#define ods_log_assert(x)
enum tsig_status_enum tsig_status
uint16_t original_query_id
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
void tsig_handler_add_algo(tsig_algo_type *algo)
size_t tsig_rr_reserved_space(tsig_rr_type *trr)