OpenDNSSEC-signer  2.0.2
tsig.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 NLNet Labs. All rights reserved.
3  *
4  * Taken from NSD3 and adjusted for OpenDNSSEC, NLnet Labs.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "compat.h"
36 #include "duration.h"
37 #include "file.h"
38 #include "log.h"
39 #include "status.h"
40 #include "util.h"
41 #include "wire/buffer.h"
42 #include "wire/tsig.h"
43 #include "wire/tsig-openssl.h"
44 
45 #include <arpa/inet.h>
46 
47 #define TSIG_SIGNED_TIME_FUDGE 300
48 
49 static const char* tsig_str = "tsig";
55 };
56 static tsig_key_table_type* tsig_key_table = NULL;
62 };
63 static tsig_algo_table_type* tsig_algo_table = NULL;
65 static size_t max_algo_digest_size = 0;
66 
67 
72 void
74 {
75  tsig_key_table_type* entry = NULL;
76  if (!key) {
77  return;
78  }
79  CHECKALLOC(entry = (tsig_key_table_type *) malloc(sizeof(tsig_key_table_type)));
80  if (entry) {
81  entry->key = key;
82  entry->next = tsig_key_table;
83  tsig_key_table = entry;
84  }
85 }
86 
87 
92 void
94 {
95  tsig_algo_table_type* entry = NULL;
96  if (!algo) {
97  return;
98  }
99  CHECKALLOC(entry = (tsig_algo_table_type *) malloc(sizeof(tsig_algo_table_type)));
100  if (entry) {
101  entry->algorithm = algo;
102  entry->next = tsig_algo_table;
103  tsig_algo_table = entry;
104  if (algo->max_digest_size > max_algo_digest_size) {
105  max_algo_digest_size = algo->max_digest_size;
106  }
107  }
108 }
109 
110 
115 ods_status
117 {
118  tsig_key_table = NULL;
119  tsig_algo_table = NULL;
120 #ifdef HAVE_SSL
121  ods_log_debug("[%s] init openssl", tsig_str);
122  return tsig_handler_openssl_init();
123 #else
124  ods_log_debug("[%s] openssl disabled", tsig_str);
125  return ODS_STATUS_OK;
126 #endif
127 }
128 
129 
134 void
136 {
137  tsig_algo_table_type* aentry = NULL, *anext = NULL;
138  tsig_key_table_type* kentry = NULL, *knext = NULL;
139 #ifdef HAVE_SSL
140  tsig_handler_openssl_finalize();
141 #endif
142 
143  aentry = tsig_algo_table;
144  while (aentry) {
145  anext = aentry->next;
146  ldns_rdf_deep_free(aentry->algorithm->wf_name);
147  free(aentry->algorithm);
148  free(aentry);
149  aentry = anext;
150  }
151 
152  kentry = tsig_key_table;
153  while (kentry) {
154  knext = kentry->next;
155  ldns_rdf_deep_free(kentry->key->dname);
156  free((void*)kentry->key->data);
157  free((void*)kentry->key);
158  free(kentry);
159  kentry = knext;
160  }
161 }
162 
163 
168 static tsig_key_type*
169 tsig_key_create(tsig_type* tsig)
170 {
171  tsig_key_type* key = NULL;
172  ldns_rdf* dname = NULL;
173  uint8_t* data = NULL;
174  int size = 0;
175  if (!tsig || !tsig->name || !tsig->secret) {
176  return NULL;
177  }
178  CHECKALLOC(key = (tsig_key_type*) malloc(sizeof(tsig_key_type)));
179  dname = ldns_dname_new_frm_str(tsig->name);
180  if (!dname) {
181  free(key);
182  return NULL;
183  }
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)));
187  if (size < 0) {
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);
191  free(data);
192  return NULL;
193  }
194  key->dname = dname;
195  key->size = size;
196  key->data = data;
198  return key;
199 }
200 
201 
206 tsig_type*
207 tsig_create(char* name, char* algo, char* secret)
208 {
209  tsig_type* tsig = NULL;
210  if (!name || !algo || !secret) {
211  return NULL;
212  }
213  CHECKALLOC(tsig = (tsig_type*) malloc(sizeof(tsig_type)));
214  tsig->next = NULL;
215  tsig->name = strdup(name);
216  tsig->algorithm = strdup(algo);
217  tsig->secret = strdup(secret);
218  tsig->key = tsig_key_create(tsig);
219  if (!tsig->key) {
220  ods_log_error("[%s] unable to create tsig: tsig_key_create() "
221  "failed", tsig_str);
222  tsig_cleanup(tsig);
223  return NULL;
224  }
225  return tsig;
226 }
227 
228 
233 tsig_type*
234 tsig_lookup_by_name(tsig_type* tsig, const char* name)
235 {
236  tsig_type* find = NULL;
237  if (!tsig || !name) {
238  return NULL;
239  }
240  find = tsig;
241  while (find) {
242  if (ods_strlowercmp(find->name, name) == 0) {
243  return find;
244  }
245  find = find->next;
246  }
247  return NULL;
248 }
249 
250 
256 tsig_lookup_algo(const char* name)
257 {
258  tsig_algo_table_type* entry = NULL;
259  for (entry = tsig_algo_table; entry; entry = entry->next) {
260  if (ods_strlowercmp(name, entry->algorithm->txt_name) == 0) {
261  return entry->algorithm;
262  }
263  }
264  return NULL;
265 }
266 
267 
274 {
275  tsig_rr_type* trr = NULL;
276  CHECKALLOC(trr = (tsig_rr_type*) malloc(sizeof(tsig_rr_type)));
277  trr->key_name = NULL;
278  trr->algo_name = NULL;
279  trr->mac_data = NULL;
280  trr->other_data = NULL;
281  tsig_rr_reset(trr, NULL, NULL);
282  return trr;
283 }
284 
285 
290 void
292 {
293  if (!trr) {
294  return;
295  }
296  tsig_rr_free(trr);
297  trr->status = TSIG_NOT_PRESENT;
298  trr->position = 0;
299  trr->response_count = 0;
300  trr->update_since_last_prepare = 0;
301  trr->context = NULL;
302  trr->algo = algo;
303  trr->key = key;
304  trr->prior_mac_size = 0;
305  trr->prior_mac_data = NULL;
306  trr->signed_time_high = 0;
307  trr->signed_time_low = 0;
308  trr->signed_time_fudge = 0;
309  trr->mac_size = 0;
310  trr->original_query_id = 0;
311  trr->error_code = LDNS_RCODE_NOERROR;
312  trr->other_size = 0;
313 }
314 
315 
320 int
322 {
323  uint16_t dname_len = 0;
324  ldns_rr_type type = 0;
325  ldns_rr_class klass = 0;
326  uint32_t ttl = 0;
327  uint16_t rdlen = 0;
328  uint16_t curpos = 0;
329  ods_log_assert(trr);
330  ods_log_assert(buffer);
331  trr->status = TSIG_NOT_PRESENT;
332  trr->position = buffer_position(buffer);
333  curpos = trr->position;
334  if (!buffer_skip_dname(buffer)) {
335  buffer_set_position(buffer, trr->position);
336  ods_log_debug("[%s] parse: skip key name failed", tsig_str);
337  return 0;
338  }
339  dname_len = buffer_position(buffer) - curpos;
340  buffer_set_position(buffer, curpos);
341  trr->key_name = ldns_dname_new_frm_data(dname_len,
342  (const void*) buffer_current(buffer));
343  if (!trr->key_name) {
344  buffer_set_position(buffer, trr->position);
345  ods_log_debug("[%s] parse: read key name failed", tsig_str);
346  return 0;
347  }
348  buffer_set_position(buffer, curpos + dname_len);
349  if (!buffer_available(buffer, 10)) {
350  ods_log_debug("[%s] parse: not enough available", tsig_str);
351  buffer_set_position(buffer, trr->position);
352  return 0;
353  }
354  type = (ldns_rr_type) buffer_read_u16(buffer);
355  klass = (ldns_rr_class) buffer_read_u16(buffer);
356  if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
357  /* not present */
358  ods_log_debug("[%s] parse: not TSIG or not ANY but %d:%d", tsig_str,
359  klass, type);
360  buffer_set_position(buffer, trr->position);
361  return 1;
362  }
363  ttl = buffer_read_u32(buffer);
364  rdlen = buffer_read_u16(buffer);
365  /* default to error */
366  trr->status = TSIG_ERROR;
367  trr->error_code = LDNS_RCODE_FORMERR;
368  if (ttl || !buffer_available(buffer, rdlen)) {
369  ods_log_debug("[%s] parse: TTL!=0 or RDLEN=0", tsig_str);
370  buffer_set_position(buffer, trr->position);
371  return 0;
372  }
373  curpos = buffer_position(buffer);
374  if (!buffer_skip_dname(buffer)) {
375  ods_log_debug("[%s] parse: skip algo name failed", tsig_str);
376  buffer_set_position(buffer, trr->position);
377  return 0;
378  }
379  dname_len = buffer_position(buffer) - curpos;
380  buffer_set_position(buffer, curpos);
381  trr->algo_name = ldns_dname_new_frm_data(dname_len,
382  (const void*) buffer_current(buffer));
383  if (!trr->algo_name) {
384  ods_log_debug("[%s] parse: read algo name failed", tsig_str);
385  buffer_set_position(buffer, trr->position);
386  return 0;
387  }
388  buffer_set_position(buffer, curpos + dname_len);
389  if (!buffer_available(buffer, 10)) {
390  ods_log_debug("[%s] parse: not enough available", tsig_str);
391  buffer_set_position(buffer, trr->position);
392  return 0;
393  }
394  trr->signed_time_high = buffer_read_u16(buffer);
395  trr->signed_time_low = buffer_read_u32(buffer);
396  trr->signed_time_fudge = buffer_read_u16(buffer);
397  trr->mac_size = buffer_read_u16(buffer);
398  if (!buffer_available(buffer, trr->mac_size)) {
399  ods_log_debug("[%s] parse: wrong mac size", tsig_str);
400  buffer_set_position(buffer, trr->position);
401  trr->mac_size = 0;
402  return 0;
403  }
404  CHECKALLOC(trr->mac_data = (uint8_t *) malloc(trr->mac_size));
405  memcpy(trr->mac_data, (const void*) buffer_current(buffer), trr->mac_size);
406  buffer_skip(buffer, trr->mac_size);
407  if (!buffer_available(buffer, 6)) {
408  ods_log_debug("[%s] parse: not enough available", tsig_str);
409  buffer_set_position(buffer, trr->position);
410  return 0;
411  }
412  trr->original_query_id = buffer_read_u16(buffer);
413  trr->error_code = buffer_read_u16(buffer);
414  trr->other_size = buffer_read_u16(buffer);
415  if (!buffer_available(buffer, trr->other_size) || trr->other_size > 16) {
416  ods_log_debug("[%s] parse: not enough available", tsig_str);
417  trr->other_size = 0;
418  buffer_set_position(buffer, trr->position);
419  return 0;
420  }
421  CHECKALLOC(trr->other_data = (uint8_t *) malloc(trr->other_size));
422  memcpy(trr->other_data, (const void*) buffer_current(buffer), trr->other_size);
423  buffer_skip(buffer, trr->other_size);
424  trr->status = TSIG_OK;
425  return 1;
426 }
427 
428 
433 int
435 {
436  size_t saved_pos = 0;
437  size_t rrcount = 0;
438  size_t i = 0;
439  int result = 0;
440  ods_log_assert(trr);
441  ods_log_assert(buffer);
442  if (buffer_pkt_arcount(buffer) == 0) {
443  trr->status = TSIG_NOT_PRESENT;
444  return 1;
445  }
446  saved_pos = buffer_position(buffer);
447  rrcount = buffer_pkt_qdcount(buffer) + buffer_pkt_ancount(buffer) +
448  buffer_pkt_nscount(buffer) + buffer_pkt_arcount(buffer);
450  for (i=0; i < rrcount - 1; i++) {
451  if (!buffer_skip_rr(buffer, i < buffer_pkt_qdcount(buffer))) {
452  buffer_set_position(buffer, saved_pos);
453  return 0;
454  }
455  }
456  result = tsig_rr_parse(trr, buffer);
457  buffer_set_position(buffer, saved_pos);
458  return result;
459 }
460 
461 
466 int
468 {
469  tsig_key_table_type* kentry = NULL;
470  tsig_key_type* key = NULL;
471  tsig_algo_table_type* aentry = NULL;
472  tsig_algo_type* algorithm = NULL;
473  uint64_t current_time = 0;
474  uint64_t signed_time = 0;
475  ods_log_assert(trr);
476  ods_log_assert(trr->status == TSIG_OK);
477  ods_log_assert(!trr->algo);
478  ods_log_assert(!trr->key);
479  for (kentry = tsig_key_table; kentry; kentry = kentry->next) {
480  if (ldns_dname_compare(trr->key_name, kentry->key->dname) == 0) {
481  key = kentry->key;
482  break;
483  }
484  }
485  for (aentry = tsig_algo_table; aentry; aentry = aentry->next) {
486  if (ldns_dname_compare(trr->algo_name,
487  aentry->algorithm->wf_name) == 0) {
488  algorithm = aentry->algorithm;
489  break;
490  }
491  }
492  if (!key || !algorithm) {
493  /* algorithm or key is unknown, cannot authenticate. */
494  ods_log_debug("[%s] algorithm or key missing", tsig_str);
496  return 0;
497  }
498  if ((trr->algo && algorithm != trr->algo) ||
499  (trr->key && key != trr->key)) {
500  /* algorithm or key changed during a single connection, error. */
501  ods_log_debug("[%s] algorithm or key has changed", tsig_str);
503  return 0;
504  }
505  signed_time = ((((uint64_t) trr->signed_time_high) << 32) |
506  ((uint64_t) trr->signed_time_low));
507  current_time = (uint64_t) time_now();
508  if ((current_time < signed_time - trr->signed_time_fudge) ||
509  (current_time > signed_time + trr->signed_time_fudge)) {
510  uint16_t current_time_high;
511  uint32_t current_time_low;
513  current_time_high = (uint16_t) (current_time >> 32);
514  current_time_low = (uint32_t) current_time;
515  trr->other_size = 6;
516  CHECKALLOC(trr->other_data = (uint8_t *) malloc(sizeof(uint16_t) + sizeof(uint32_t)));
517  write_uint16(trr->other_data, current_time_high);
518  write_uint32(trr->other_data + 2, current_time_low);
519  ods_log_debug("[%s] bad time", tsig_str);
520  return 0;
521  }
522  trr->algo = algorithm;
523  trr->key = key;
524  trr->response_count = 0;
525  trr->prior_mac_size = 0;
526  return 1;
527 }
528 
529 
534 void
536 {
537  ods_log_assert(trr->algo);
538  if (!trr->context) {
539  trr->context = trr->algo->hmac_create();
540  CHECKALLOC(trr->prior_mac_data = (uint8_t *) malloc(trr->algo->max_digest_size));
541  }
542  trr->algo->hmac_init(trr->context, trr->algo, trr->key);
543  if (trr->prior_mac_size > 0) {
544  uint16_t mac_size = htons(trr->prior_mac_size);
545  trr->algo->hmac_update(trr->context, &mac_size, sizeof(mac_size));
546  trr->algo->hmac_update(trr->context, trr->prior_mac_data,
547  trr->prior_mac_size);
548  }
549  trr->update_since_last_prepare = 0;
550 }
551 
556 void
557 tsig_rr_update(tsig_rr_type* trr, buffer_type* buffer, size_t length)
558 {
559  uint16_t original_query_id = 0;
560  ods_log_assert(trr);
561  ods_log_assert(trr->algo);
562  ods_log_assert(trr->context);
563  ods_log_assert(buffer);
564  ods_log_assert(length <= buffer_limit(buffer));
565  original_query_id = htons(trr->original_query_id);
566  trr->algo->hmac_update(trr->context, &original_query_id,
567  sizeof(original_query_id));
568  trr->algo->hmac_update(trr->context,
569  buffer_at(buffer, sizeof(original_query_id)),
570  length - sizeof(original_query_id));
571  if (buffer_pkt_qr(buffer)) {
572  ++trr->response_count;
573  }
575 }
576 
577 
582 static void
583 tsig_rr_digest_variables(tsig_rr_type* trr, int tsig_timers_only)
584 {
585  uint16_t klass = htons(LDNS_RR_CLASS_ANY);
586  uint32_t ttl = htonl(0);
587  uint16_t signed_time_high = htons(trr->signed_time_high);
588  uint32_t signed_time_low = htonl(trr->signed_time_low);
589  uint16_t signed_time_fudge = htons(trr->signed_time_fudge);
590  uint16_t error_code = htons(trr->error_code);
591  uint16_t other_size = htons(trr->other_size);
592  ods_log_assert(trr->context);
593  ods_log_assert(trr->algo);
594  ods_log_assert(trr->key_name);
595  if (!tsig_timers_only) {
596  ods_log_assert(trr->key_name);
597  ods_log_assert(trr->algo_name);
598  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->key_name),
599  ldns_rdf_size(trr->key_name));
600  trr->algo->hmac_update(trr->context, &klass, sizeof(klass));
601  trr->algo->hmac_update(trr->context, &ttl, sizeof(ttl));
602  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->algo_name),
603  ldns_rdf_size(trr->algo_name));
604  }
605  trr->algo->hmac_update(trr->context, &signed_time_high,
606  sizeof(signed_time_high));
607  trr->algo->hmac_update(trr->context, &signed_time_low,
608  sizeof(signed_time_low));
609  trr->algo->hmac_update(trr->context, &signed_time_fudge,
610  sizeof(signed_time_fudge));
611  if (!tsig_timers_only) {
612  trr->algo->hmac_update(trr->context, &error_code,
613  sizeof(error_code));
614  trr->algo->hmac_update(trr->context, &other_size,
615  sizeof(other_size));
616  trr->algo->hmac_update(trr->context, trr->other_data,
617  trr->other_size);
618  }
619 }
620 
621 
626 void
628 {
629  uint64_t current_time = (uint64_t) time_now();
630  ods_log_assert(trr);
631  ods_log_assert(trr->context);
632  trr->signed_time_high = (uint16_t) (current_time >> 32);
633  trr->signed_time_low = (uint32_t) current_time;
635  tsig_rr_digest_variables(trr, trr->response_count > 1);
636  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
637  &trr->prior_mac_size);
638  trr->mac_size = trr->prior_mac_size;
639  trr->mac_data = trr->prior_mac_data;
640 }
641 
642 
647 int
649 {
650  ods_log_assert(trr);
651  ods_log_assert(trr->algo);
652  tsig_rr_digest_variables(trr, trr->response_count > 1);
653  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
654  &trr->prior_mac_size);
655  if (trr->mac_size != trr->prior_mac_size ||
656  memcmp(trr->mac_data, trr->prior_mac_data, trr->mac_size) != 0) {
657  /* digest is incorrect, cannot authenticate. */
659  return 0;
660  }
661  return 1;
662 }
663 
664 
669 void
671 {
672  size_t rdlength_pos = 0;
673  if (!trr || !buffer) {
674  return;
675  }
676  /* [TODO] key name compression? */
677  if (trr->key_name) {
678  buffer_write_rdf(buffer, trr->key_name);
679  } else {
680  buffer_write_u8(buffer, 0);
681  }
682  buffer_write_u16(buffer, (uint16_t)LDNS_RR_TYPE_TSIG);
683  buffer_write_u16(buffer, (uint16_t)LDNS_RR_CLASS_ANY);
684  buffer_write_u32(buffer, 0); /* TTL */
685  rdlength_pos = buffer_position(buffer);
686  buffer_skip(buffer, sizeof(uint16_t));
687  if (trr->algo_name) {
688  buffer_write_rdf(buffer, trr->algo_name);
689  } else {
690  buffer_write_u8(buffer, 0);
691  }
692  buffer_write_u16(buffer, trr->signed_time_high);
693  buffer_write_u32(buffer, trr->signed_time_low);
694  buffer_write_u16(buffer, trr->signed_time_fudge);
695  buffer_write_u16(buffer, trr->mac_size);
696  buffer_write(buffer, trr->mac_data, trr->mac_size);
697  buffer_write_u16(buffer, trr->original_query_id);
698  buffer_write_u16(buffer, trr->error_code);
699  buffer_write_u16(buffer, trr->other_size);
700  buffer_write(buffer, trr->other_data, trr->other_size);
701  buffer_write_u16_at(buffer, rdlength_pos,
702  buffer_position(buffer) - rdlength_pos - sizeof(uint16_t));
703 }
704 
705 
706 /*
707  * The amount of space to reserve in the response for the TSIG data.
708  *
709  */
710 size_t
712 {
713  if (!trr || trr->status == TSIG_NOT_PRESENT) {
714  return 0;
715  }
716  return (
717  (trr->key_name?ldns_rdf_size(trr->key_name):1)
718  + sizeof(uint16_t) /* Type */
719  + sizeof(uint16_t) /* Class */
720  + sizeof(uint32_t) /* TTL */
721  + sizeof(uint16_t) /* RDATA length */
722  + (trr->algo_name?ldns_rdf_size(trr->algo_name):1)
723  + sizeof(uint16_t) /* Signed time (high) */
724  + sizeof(uint32_t) /* Signed time (low) */
725  + sizeof(uint16_t) /* Signed time fudge */
726  + sizeof(uint16_t) /* MAC size */
727  + max_algo_digest_size /* MAC data */
728  + sizeof(uint16_t) /* Original query ID */
729  + sizeof(uint16_t) /* Error code */
730  + sizeof(uint16_t) /* Other size */
731  + trr->other_size); /* Other data */
732 }
733 
734 
739 void
741 {
742  if (!trr) {
743  return;
744  }
745  if (trr->mac_data) {
746  memset(trr->mac_data, 0, trr->mac_size);
747  }
748  trr->mac_size = 0;
749 }
750 
751 
756 const char*
758 {
759  switch (status) {
760  case TSIG_NOT_PRESENT:
761  return "NOT PRESENT";
762  case TSIG_OK:
763  return "OK";
764  case TSIG_ERROR:
765  return "ERROR";
766  }
767  return "UNKNOWN";
768 }
769 
770 
775 const char*
776 tsig_strerror(uint16_t error)
777 {
778  static char message[1000];
779  switch (error) {
780  case 0:
781  return "No Error";
782  break;
783  case TSIG_ERROR_BADSIG:
784  return "Bad Signature";
785  break;
786  case TSIG_ERROR_BADKEY:
787  return "Bad Key";
788  break;
789  case TSIG_ERROR_BADTIME:
790  return "Bad Time";
791  break;
792  default:
793  if (error < 16) {
794  /* DNS rcodes */
795  return (const char*) ldns_pkt_rcode2str(error);
796  }
797  snprintf(message, sizeof(message), "Unknown Error %d", error);
798  break;
799  }
800  return message;
801 }
802 
803 
808 void
810 {
811  if (!trr) {
812  return;
813  }
814  ldns_rdf_deep_free(trr->key_name);
815  ldns_rdf_deep_free(trr->algo_name);
816  free(trr->mac_data);
817  free(trr->other_data);
818  trr->key_name = NULL;
819  trr->algo_name = NULL;
820  trr->mac_data = NULL;
821  trr->other_data = NULL;
822 }
823 
824 
829 void
831 {
832  if (!trr) {
833  return;
834  }
835  tsig_rr_free(trr);
836  free(trr);
837 }
838 
839 
844 void
846 {
847  if (!tsig) {
848  return;
849  }
850  tsig_cleanup(tsig->next);
851  free((void*)tsig->name);
852  free((void*)tsig->algorithm);
853  free((void*)tsig->secret);
854  free(tsig);
855 }
#define TSIG_ERROR_BADTIME
Definition: tsig.h:45
void tsig_cleanup(tsig_type *tsig)
Definition: tsig.c:845
void tsig_rr_free(tsig_rr_type *trr)
Definition: tsig.c:809
tsig_algo_type * algo
Definition: tsig.h:129
void tsig_handler_cleanup(void)
Definition: tsig.c:135
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:557
tsig_status status
Definition: tsig.h:124
tsig_algo_table_type * next
Definition: tsig.c:60
size_t max_digest_size
Definition: tsig.h:92
uint16_t mac_size
Definition: tsig.h:139
tsig_algo_type * algorithm
Definition: tsig.c:61
uint16_t signed_time_high
Definition: tsig.h:136
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:321
uint8_t * buffer_at(buffer_type *buffer, size_t at)
Definition: buffer.c:413
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1066
ods_status tsig_handler_init()
Definition: tsig.c:116
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:43
uint16_t error_code
Definition: tsig.h:142
const char * tsig_strerror(uint16_t error)
Definition: tsig.c:776
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:994
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:150
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:721
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:342
#define TSIG_SIGNED_TIME_FUDGE
Definition: tsig.c:47
uint8_t * prior_mac_data
Definition: tsig.h:132
void buffer_write_u8(buffer_type *buffer, uint8_t data)
Definition: buffer.c:552
tsig_algo_type * tsig_lookup_algo(const char *name)
Definition: tsig.c:256
void(* hmac_update)(void *context, const void *data, size_t size)
Definition: tsig.h:100
ldns_rdf * wf_name
Definition: tsig.h:91
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:810
uint16_t signed_time_fudge
Definition: tsig.h:138
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:291
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:670
size_t update_since_last_prepare
Definition: tsig.h:127
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:538
uint8_t * other_data
Definition: tsig.h:144
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:438
size_t prior_mac_size
Definition: tsig.h:131
const char * algorithm
Definition: tsig.h:113
tsig_type * tsig_create(char *name, char *algo, char *secret)
Definition: tsig.c:207
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:373
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1018
tsig_rr_type * tsig_rr_create()
Definition: tsig.c:273
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:535
tsig_key_type * key
Definition: tsig.h:115
void *(* hmac_create)(void)
Definition: tsig.h:95
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:757
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition: tsig.h:102
ldns_rdf * key_name
Definition: tsig.h:134
tsig_type * next
Definition: tsig.h:111
void tsig_handler_add_key(tsig_key_type *key)
Definition: tsig.c:73
uint8_t * mac_data
Definition: tsig.h:140
Definition: tsig.h:57
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:830
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:310
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.h:97
size_t size
Definition: tsig.h:80
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:736
tsig_key_type * key
Definition: tsig.h:130
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:648
uint32_t signed_time_low
Definition: tsig.h:137
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:565
ldns_rdf * dname
Definition: tsig.h:79
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:578
#define TSIG_ERROR_BADSIG
Definition: tsig.h:43
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:740
const char * secret
Definition: tsig.h:114
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1042
size_t position
Definition: tsig.h:125
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:512
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:137
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:434
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:487
uint16_t other_size
Definition: tsig.h:143
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:467
#define TSIG_ERROR_BADKEY
Definition: tsig.h:44
void * context
Definition: tsig.h:128
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:591
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:627
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:125
ldns_rdf * algo_name
Definition: tsig.h:135
size_t response_count
Definition: tsig.h:126
const uint8_t * data
Definition: tsig.h:81
tsig_key_table_type * next
Definition: tsig.c:53
tsig_key_type * key
Definition: tsig.c:54
const char * name
Definition: tsig.h:112
const char * txt_name
Definition: tsig.h:90
enum tsig_status_enum tsig_status
Definition: tsig.h:60
uint16_t original_query_id
Definition: tsig.h:141
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
Definition: tsig.c:234
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition: tsig.c:93
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:711