45 #include <arpa/inet.h>
47 #define TSIG_SIGNED_TIME_FUDGE 300
49 static const char* tsig_str =
"tsig";
67 static size_t max_algo_digest_size = 0;
74 #ifdef HAVE_EVP_SHA256
96 entry->
next = tsig_key_table;
97 tsig_key_table = entry;
118 entry->
next = tsig_algo_table;
119 tsig_algo_table = entry;
138 tsig_allocator = allocator;
139 tsig_key_table = NULL;
140 tsig_algo_table = NULL;
143 return tsig_handler_openssl_init(allocator);
160 tsig_handler_openssl_finalize();
163 aentry = tsig_algo_table;
165 anext = aentry->
next;
172 kentry = tsig_key_table;
174 knext = kentry->
next;
175 ldns_rdf_deep_free(kentry->
key->
dname);
193 ldns_rdf* dname = NULL;
194 uint8_t* data = NULL;
196 if (!allocator || !tsig || !tsig->
name || !tsig->
secret) {
203 dname = ldns_dname_new_frm_str(tsig->
name);
210 ldns_rdf_deep_free(dname);
213 size = b64_pton(tsig->
secret, data,
216 ods_log_error(
"[%s] unable to create tsig key %s: failed to parse "
217 "secret", tsig_str, tsig->
name);
218 ldns_rdf_deep_free(dname);
237 if (!allocator || !name || !algo || !secret) {
242 ods_log_error(
"[%s] unable to create tsig: allocator_alloc() "
252 ods_log_error(
"[%s] unable to create tsig: tsig_key_create() "
269 if (!tsig || !name) {
291 for (entry = tsig_algo_table; entry; entry = entry->
next) {
313 ods_log_error(
"[%s] unable to create tsig rr: allocator_alloc() "
365 uint16_t dname_len = 0;
366 ldns_rr_type type = 0;
367 ldns_rr_class klass = 0;
384 trr->
key_name = ldns_dname_new_frm_data(dname_len,
399 if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
418 ods_log_debug(
"[%s] parse: skip algo name failed", tsig_str);
424 trr->
algo_name = ldns_dname_new_frm_data(dname_len,
427 ods_log_debug(
"[%s] parse: read algo name failed", tsig_str);
479 size_t saved_pos = 0;
493 for (i=0; i < rrcount - 1; i++) {
516 uint64_t current_time = 0;
517 uint64_t signed_time = 0;
522 for (kentry = tsig_key_table; kentry; kentry = kentry->
next) {
528 for (aentry = tsig_algo_table; aentry; aentry = aentry->
next) {
535 if (!key || !algorithm) {
541 if ((trr->
algo && algorithm != trr->
algo) ||
542 (trr->
key && key != trr->
key)) {
544 ods_log_debug(
"[%s] algorithm or key has changed", tsig_str);
550 current_time = (uint64_t)
time_now();
551 if ((current_time < signed_time - trr->signed_time_fudge) ||
553 uint16_t current_time_high;
554 uint32_t current_time_low;
556 current_time_high = (uint16_t) (current_time >> 32);
557 current_time_low = (uint32_t) current_time;
560 sizeof(uint16_t) +
sizeof(uint32_t));
561 write_uint16(trr->
other_data, current_time_high);
562 write_uint32(trr->
other_data + 2, current_time_low);
566 trr->
algo = algorithm;
606 uint16_t original_query_id = 0;
614 sizeof(original_query_id));
616 buffer_at(buffer,
sizeof(original_query_id)),
617 length -
sizeof(original_query_id));
631 tsig_rr_digest_variables(
tsig_rr_type* trr,
int tsig_timers_only)
633 uint16_t klass = htons(LDNS_RR_CLASS_ANY);
634 uint32_t ttl = htonl(0);
643 if (!tsig_timers_only) {
654 sizeof(signed_time_high));
656 sizeof(signed_time_low));
658 sizeof(signed_time_fudge));
659 if (!tsig_timers_only) {
678 uint64_t current_time = (uint64_t)
time_now();
722 size_t rdlength_pos = 0;
723 if (!trr || !buffer) {
778 + max_algo_digest_size
813 return "NOT PRESENT";
830 static char message[1000];
836 return "Bad Signature";
847 return (
const char*) ldns_pkt_rcode2str(error);
849 snprintf(message,
sizeof(message),
"Unknown Error %d", error);
903 if (!tsig || !allocator) {
#define TSIG_ERROR_BADTIME
void tsig_rr_free(tsig_rr_type *trr)
void tsig_handler_cleanup(void)
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
tsig_algo_table_type * next
allocator_type * allocator
void *(* hmac_create)(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,...)
void(* hmac_update)(void *context, const void *data, size_t size)
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(* hmac_final)(void *context, uint8_t *digest, size_t *size)
void tsig_handler_add_key(tsig_key_type *key)
void tsig_rr_cleanup(tsig_rr_type *trr)
int buffer_skip_dname(buffer_type *buffer)
char * allocator_strdup(allocator_type *allocator, const char *string)
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
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)
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)