OpenDNSSEC-signer  2.1.5
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  free(key);
193  return NULL;
194  }
195  key->dname = dname;
196  key->size = size;
197  key->data = data;
199  return key;
200 }
201 
202 
207 tsig_type*
208 tsig_create(char* name, char* algo, char* secret)
209 {
210  tsig_type* tsig = NULL;
211  if (!name || !algo || !secret) {
212  return NULL;
213  }
214  CHECKALLOC(tsig = (tsig_type*) malloc(sizeof(tsig_type)));
215  tsig->next = NULL;
216  tsig->name = strdup(name);
217  tsig->algorithm = strdup(algo);
218  tsig->secret = strdup(secret);
219  tsig->key = tsig_key_create(tsig);
220  if (!tsig->key) {
221  ods_log_error("[%s] unable to create tsig: tsig_key_create() "
222  "failed", tsig_str);
223  tsig_cleanup(tsig);
224  return NULL;
225  }
226  return tsig;
227 }
228 
229 
234 tsig_type*
235 tsig_lookup_by_name(tsig_type* tsig, const char* name)
236 {
237  tsig_type* find = NULL;
238  if (!tsig || !name) {
239  return NULL;
240  }
241  find = tsig;
242  while (find) {
243  if (ods_strlowercmp(find->name, name) == 0) {
244  return find;
245  }
246  find = find->next;
247  }
248  return NULL;
249 }
250 
251 
257 tsig_lookup_algo(const char* name)
258 {
259  tsig_algo_table_type* entry = NULL;
260  for (entry = tsig_algo_table; entry; entry = entry->next) {
261  if (ods_strlowercmp(name, entry->algorithm->txt_name) == 0) {
262  return entry->algorithm;
263  }
264  }
265  return NULL;
266 }
267 
268 
275 {
276  tsig_rr_type* trr = NULL;
277  CHECKALLOC(trr = (tsig_rr_type*) malloc(sizeof(tsig_rr_type)));
278  trr->key_name = NULL;
279  trr->algo_name = NULL;
280  trr->mac_data = NULL;
281  trr->other_data = NULL;
282  tsig_rr_reset(trr, NULL, NULL);
283  return trr;
284 }
285 
286 
291 void
293 {
294  if (!trr) {
295  return;
296  }
297  tsig_rr_free(trr);
298  trr->status = TSIG_NOT_PRESENT;
299  trr->position = 0;
300  trr->response_count = 0;
301  trr->update_since_last_prepare = 0;
302  trr->context = NULL;
303  trr->algo = algo;
304  trr->key = key;
305  trr->prior_mac_size = 0;
306  trr->prior_mac_data = NULL;
307  trr->signed_time_high = 0;
308  trr->signed_time_low = 0;
309  trr->signed_time_fudge = 0;
310  trr->mac_size = 0;
311  trr->original_query_id = 0;
312  trr->error_code = LDNS_RCODE_NOERROR;
313  trr->other_size = 0;
314 }
315 
316 
321 int
323 {
324  uint16_t dname_len = 0;
325  ldns_rr_type type = 0;
326  ldns_rr_class klass = 0;
327  uint32_t ttl = 0;
328  uint16_t rdlen = 0;
329  uint16_t curpos = 0;
330  ods_log_assert(trr);
331  ods_log_assert(buffer);
332  trr->status = TSIG_NOT_PRESENT;
333  trr->position = buffer_position(buffer);
334  curpos = trr->position;
335  if (!buffer_skip_dname(buffer)) {
336  buffer_set_position(buffer, trr->position);
337  ods_log_debug("[%s] parse: skip key name failed", tsig_str);
338  return 0;
339  }
340  dname_len = buffer_position(buffer) - curpos;
341  buffer_set_position(buffer, curpos);
342  trr->key_name = ldns_dname_new_frm_data(dname_len,
343  (const void*) buffer_current(buffer));
344  if (!trr->key_name) {
345  buffer_set_position(buffer, trr->position);
346  ods_log_debug("[%s] parse: read key name failed", tsig_str);
347  return 0;
348  }
349  buffer_set_position(buffer, curpos + dname_len);
350  if (!buffer_available(buffer, 10)) {
351  ods_log_debug("[%s] parse: not enough available", tsig_str);
352  buffer_set_position(buffer, trr->position);
353  return 0;
354  }
355  type = (ldns_rr_type) buffer_read_u16(buffer);
356  klass = (ldns_rr_class) buffer_read_u16(buffer);
357  if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
358  /* not present */
359  ods_log_debug("[%s] parse: not TSIG or not ANY but %d:%d", tsig_str,
360  klass, type);
361  buffer_set_position(buffer, trr->position);
362  return 1;
363  }
364  ttl = buffer_read_u32(buffer);
365  rdlen = buffer_read_u16(buffer);
366  /* default to error */
367  trr->status = TSIG_ERROR;
368  trr->error_code = LDNS_RCODE_FORMERR;
369  if (ttl || !buffer_available(buffer, rdlen)) {
370  ods_log_debug("[%s] parse: TTL!=0 or RDLEN=0", tsig_str);
371  buffer_set_position(buffer, trr->position);
372  return 0;
373  }
374  curpos = buffer_position(buffer);
375  if (!buffer_skip_dname(buffer)) {
376  ods_log_debug("[%s] parse: skip algo name failed", tsig_str);
377  buffer_set_position(buffer, trr->position);
378  return 0;
379  }
380  dname_len = buffer_position(buffer) - curpos;
381  buffer_set_position(buffer, curpos);
382  trr->algo_name = ldns_dname_new_frm_data(dname_len,
383  (const void*) buffer_current(buffer));
384  if (!trr->algo_name) {
385  ods_log_debug("[%s] parse: read algo name failed", tsig_str);
386  buffer_set_position(buffer, trr->position);
387  return 0;
388  }
389  buffer_set_position(buffer, curpos + dname_len);
390  if (!buffer_available(buffer, 10)) {
391  ods_log_debug("[%s] parse: not enough available", tsig_str);
392  buffer_set_position(buffer, trr->position);
393  return 0;
394  }
395  trr->signed_time_high = buffer_read_u16(buffer);
396  trr->signed_time_low = buffer_read_u32(buffer);
397  trr->signed_time_fudge = buffer_read_u16(buffer);
398  trr->mac_size = buffer_read_u16(buffer);
399  if (!buffer_available(buffer, trr->mac_size)) {
400  ods_log_debug("[%s] parse: wrong mac size", tsig_str);
401  buffer_set_position(buffer, trr->position);
402  trr->mac_size = 0;
403  return 0;
404  }
405  CHECKALLOC(trr->mac_data = (uint8_t *) malloc(trr->mac_size));
406  memcpy(trr->mac_data, (const void*) buffer_current(buffer), trr->mac_size);
407  buffer_skip(buffer, trr->mac_size);
408  if (!buffer_available(buffer, 6)) {
409  ods_log_debug("[%s] parse: not enough available", tsig_str);
410  buffer_set_position(buffer, trr->position);
411  return 0;
412  }
413  trr->original_query_id = buffer_read_u16(buffer);
414  trr->error_code = buffer_read_u16(buffer);
415  trr->other_size = buffer_read_u16(buffer);
416  if (!buffer_available(buffer, trr->other_size) || trr->other_size > 16) {
417  ods_log_debug("[%s] parse: not enough available", tsig_str);
418  trr->other_size = 0;
419  buffer_set_position(buffer, trr->position);
420  return 0;
421  }
422  CHECKALLOC(trr->other_data = (uint8_t *) malloc(trr->other_size));
423  memcpy(trr->other_data, (const void*) buffer_current(buffer), trr->other_size);
424  buffer_skip(buffer, trr->other_size);
425  trr->status = TSIG_OK;
426  return 1;
427 }
428 
429 
434 int
436 {
437  size_t saved_pos = 0;
438  size_t rrcount = 0;
439  size_t i = 0;
440  int result = 0;
441  ods_log_assert(trr);
442  ods_log_assert(buffer);
443  if (buffer_pkt_arcount(buffer) == 0) {
444  trr->status = TSIG_NOT_PRESENT;
445  return 1;
446  }
447  saved_pos = buffer_position(buffer);
448  rrcount = buffer_pkt_qdcount(buffer) + buffer_pkt_ancount(buffer) +
449  buffer_pkt_nscount(buffer) + buffer_pkt_arcount(buffer);
450  rrcount &= 0x3FFFF; /* un-taint rrcount */
452  for (i=0; i < rrcount - 1; i++) {
453  if (!buffer_skip_rr(buffer, i < (buffer_pkt_qdcount(buffer)&0xFFFF))) {
454  buffer_set_position(buffer, saved_pos);
455  return 0;
456  }
457  }
458  result = tsig_rr_parse(trr, buffer);
459  buffer_set_position(buffer, saved_pos);
460  return result;
461 }
462 
463 
468 int
470 {
471  tsig_key_table_type* kentry = NULL;
472  tsig_key_type* key = NULL;
473  tsig_algo_table_type* aentry = NULL;
474  tsig_algo_type* algorithm = NULL;
475  uint64_t current_time = 0;
476  uint64_t signed_time = 0;
477  ods_log_assert(trr);
478  ods_log_assert(trr->status == TSIG_OK);
479  ods_log_assert(!trr->algo);
480  ods_log_assert(!trr->key);
481  for (kentry = tsig_key_table; kentry; kentry = kentry->next) {
482  if (ldns_dname_compare(trr->key_name, kentry->key->dname) == 0) {
483  key = kentry->key;
484  break;
485  }
486  }
487  for (aentry = tsig_algo_table; aentry; aentry = aentry->next) {
488  if (ldns_dname_compare(trr->algo_name,
489  aentry->algorithm->wf_name) == 0) {
490  algorithm = aentry->algorithm;
491  break;
492  }
493  }
494  if (!key || !algorithm) {
495  /* algorithm or key is unknown, cannot authenticate. */
496  ods_log_debug("[%s] algorithm or key missing", tsig_str);
498  return 0;
499  }
500  if ((trr->algo && algorithm != trr->algo) ||
501  (trr->key && key != trr->key)) {
502  /* algorithm or key changed during a single connection, error. */
503  ods_log_debug("[%s] algorithm or key has changed", tsig_str);
505  return 0;
506  }
507  signed_time = ((((uint64_t) trr->signed_time_high) << 32) |
508  ((uint64_t) trr->signed_time_low));
509  current_time = (uint64_t) time_now();
510  if ((current_time < signed_time - trr->signed_time_fudge) ||
511  (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;
517  trr->other_size = 6;
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);
522  return 0;
523  }
524  trr->algo = algorithm;
525  trr->key = key;
526  trr->response_count = 0;
527  trr->prior_mac_size = 0;
528  return 1;
529 }
530 
531 
536 void
538 {
539  ods_log_assert(trr->algo);
540  if (!trr->context) {
541  trr->context = trr->algo->hmac_create();
542  CHECKALLOC(trr->prior_mac_data = (uint8_t *) malloc(trr->algo->max_digest_size));
543  }
544  trr->algo->hmac_init(trr->context, trr->algo, trr->key);
545  if (trr->prior_mac_size > 0) {
546  uint16_t mac_size = htons(trr->prior_mac_size);
547  trr->algo->hmac_update(trr->context, &mac_size, sizeof(mac_size));
548  trr->algo->hmac_update(trr->context, trr->prior_mac_data,
549  trr->prior_mac_size);
550  }
551  trr->update_since_last_prepare = 0;
552 }
553 
558 void
559 tsig_rr_update(tsig_rr_type* trr, buffer_type* buffer, size_t length)
560 {
561  uint16_t original_query_id = 0;
562  ods_log_assert(trr);
563  ods_log_assert(trr->algo);
564  ods_log_assert(trr->context);
565  ods_log_assert(buffer);
566  ods_log_assert(length <= buffer_limit(buffer));
567  original_query_id = htons(trr->original_query_id);
568  trr->algo->hmac_update(trr->context, &original_query_id,
569  sizeof(original_query_id));
570  trr->algo->hmac_update(trr->context,
571  buffer_at(buffer, sizeof(original_query_id)),
572  length - sizeof(original_query_id));
573  if (buffer_pkt_qr(buffer)) {
574  ++trr->response_count;
575  }
577 }
578 
579 
584 static void
585 tsig_rr_digest_variables(tsig_rr_type* trr, int tsig_timers_only)
586 {
587  uint16_t klass = htons(LDNS_RR_CLASS_ANY);
588  uint32_t ttl = htonl(0);
589  uint16_t signed_time_high = htons(trr->signed_time_high);
590  uint32_t signed_time_low = htonl(trr->signed_time_low);
591  uint16_t signed_time_fudge = htons(trr->signed_time_fudge);
592  uint16_t error_code = htons(trr->error_code);
593  uint16_t other_size = htons(trr->other_size);
594  ods_log_assert(trr->context);
595  ods_log_assert(trr->algo);
596  ods_log_assert(trr->key_name);
597  if (!tsig_timers_only) {
598  ods_log_assert(trr->key_name);
599  ods_log_assert(trr->algo_name);
600  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->key_name),
601  ldns_rdf_size(trr->key_name));
602  trr->algo->hmac_update(trr->context, &klass, sizeof(klass));
603  trr->algo->hmac_update(trr->context, &ttl, sizeof(ttl));
604  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->algo_name),
605  ldns_rdf_size(trr->algo_name));
606  }
607  trr->algo->hmac_update(trr->context, &signed_time_high,
608  sizeof(signed_time_high));
609  trr->algo->hmac_update(trr->context, &signed_time_low,
610  sizeof(signed_time_low));
611  trr->algo->hmac_update(trr->context, &signed_time_fudge,
612  sizeof(signed_time_fudge));
613  if (!tsig_timers_only) {
614  trr->algo->hmac_update(trr->context, &error_code,
615  sizeof(error_code));
616  trr->algo->hmac_update(trr->context, &other_size,
617  sizeof(other_size));
618  trr->algo->hmac_update(trr->context, trr->other_data,
619  trr->other_size);
620  }
621 }
622 
623 
628 void
630 {
631  uint64_t current_time = (uint64_t) time_now();
632  ods_log_assert(trr);
633  ods_log_assert(trr->context);
634  trr->signed_time_high = (uint16_t) (current_time >> 32);
635  trr->signed_time_low = (uint32_t) current_time;
637  tsig_rr_digest_variables(trr, trr->response_count > 1);
638  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
639  &trr->prior_mac_size);
640  trr->mac_size = trr->prior_mac_size;
641  trr->mac_data = trr->prior_mac_data;
642 }
643 
644 
649 int
651 {
652  ods_log_assert(trr);
653  ods_log_assert(trr->algo);
654  tsig_rr_digest_variables(trr, trr->response_count > 1);
655  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
656  &trr->prior_mac_size);
657  if (trr->mac_size != trr->prior_mac_size ||
658  memcmp(trr->mac_data, trr->prior_mac_data, trr->mac_size) != 0) {
659  /* digest is incorrect, cannot authenticate. */
661  return 0;
662  }
663  return 1;
664 }
665 
666 
671 void
673 {
674  size_t rdlength_pos = 0;
675  if (!trr || !buffer) {
676  return;
677  }
678  /* [TODO] key name compression? */
679  if (trr->key_name) {
680  buffer_write_rdf(buffer, trr->key_name);
681  } else {
682  buffer_write_u8(buffer, 0);
683  }
684  buffer_write_u16(buffer, (uint16_t)LDNS_RR_TYPE_TSIG);
685  buffer_write_u16(buffer, (uint16_t)LDNS_RR_CLASS_ANY);
686  buffer_write_u32(buffer, 0); /* TTL */
687  rdlength_pos = buffer_position(buffer);
688  buffer_skip(buffer, sizeof(uint16_t));
689  if (trr->algo_name) {
690  buffer_write_rdf(buffer, trr->algo_name);
691  } else {
692  buffer_write_u8(buffer, 0);
693  }
694  buffer_write_u16(buffer, trr->signed_time_high);
695  buffer_write_u32(buffer, trr->signed_time_low);
696  buffer_write_u16(buffer, trr->signed_time_fudge);
697  buffer_write_u16(buffer, trr->mac_size);
698  buffer_write(buffer, trr->mac_data, trr->mac_size);
699  buffer_write_u16(buffer, trr->original_query_id);
700  buffer_write_u16(buffer, trr->error_code);
701  buffer_write_u16(buffer, trr->other_size);
702  buffer_write(buffer, trr->other_data, trr->other_size);
703  buffer_write_u16_at(buffer, rdlength_pos,
704  buffer_position(buffer) - rdlength_pos - sizeof(uint16_t));
705 }
706 
707 
708 /*
709  * The amount of space to reserve in the response for the TSIG data.
710  *
711  */
712 size_t
714 {
715  if (!trr || trr->status == TSIG_NOT_PRESENT) {
716  return 0;
717  }
718  return (
719  (trr->key_name?ldns_rdf_size(trr->key_name):1)
720  + sizeof(uint16_t) /* Type */
721  + sizeof(uint16_t) /* Class */
722  + sizeof(uint32_t) /* TTL */
723  + sizeof(uint16_t) /* RDATA length */
724  + (trr->algo_name?ldns_rdf_size(trr->algo_name):1)
725  + sizeof(uint16_t) /* Signed time (high) */
726  + sizeof(uint32_t) /* Signed time (low) */
727  + sizeof(uint16_t) /* Signed time fudge */
728  + sizeof(uint16_t) /* MAC size */
729  + max_algo_digest_size /* MAC data */
730  + sizeof(uint16_t) /* Original query ID */
731  + sizeof(uint16_t) /* Error code */
732  + sizeof(uint16_t) /* Other size */
733  + trr->other_size); /* Other data */
734 }
735 
736 
741 void
743 {
744  if (!trr) {
745  return;
746  }
747  if (trr->mac_data) {
748  memset(trr->mac_data, 0, trr->mac_size);
749  }
750  trr->mac_size = 0;
751 }
752 
753 
758 const char*
760 {
761  switch (status) {
762  case TSIG_NOT_PRESENT:
763  return "NOT PRESENT";
764  case TSIG_OK:
765  return "OK";
766  case TSIG_ERROR:
767  return "ERROR";
768  }
769  return "UNKNOWN";
770 }
771 
772 
777 const char*
778 tsig_strerror(uint16_t error)
779 {
780  static char message[1000];
781  switch (error) {
782  case 0:
783  return "No Error";
784  break;
785  case TSIG_ERROR_BADSIG:
786  return "Bad Signature";
787  break;
788  case TSIG_ERROR_BADKEY:
789  return "Bad Key";
790  break;
791  case TSIG_ERROR_BADTIME:
792  return "Bad Time";
793  break;
794  default:
795  if (error < 16) {
796  /* DNS rcodes */
797  return (const char*) ldns_pkt_rcode2str(error);
798  }
799  snprintf(message, sizeof(message), "Unknown Error %d", error);
800  break;
801  }
802  return message;
803 }
804 
805 
810 void
812 {
813  if (!trr) {
814  return;
815  }
816  ldns_rdf_deep_free(trr->key_name);
817  ldns_rdf_deep_free(trr->algo_name);
818  free(trr->mac_data);
819  free(trr->other_data);
820  trr->key_name = NULL;
821  trr->algo_name = NULL;
822  trr->mac_data = NULL;
823  trr->other_data = NULL;
824 }
825 
826 
831 void
833 {
834  if (!trr) {
835  return;
836  }
837  tsig_rr_free(trr);
838  free(trr);
839 }
840 
841 
846 void
848 {
849  if (!tsig) {
850  return;
851  }
852  tsig_cleanup(tsig->next);
853  free((void*)tsig->name);
854  free((void*)tsig->algorithm);
855  free((void*)tsig->secret);
856  free(tsig);
857 }
TSIG_ERROR
@ TSIG_ERROR
Definition: tsig.h:58
tsig_rr_struct::algo_name
ldns_rdf * algo_name
Definition: tsig.h:135
tsig_key_struct::data
const uint8_t * data
Definition: tsig.h:81
tsig_algo_struct::hmac_update
void(* hmac_update)(void *context, const void *data, size_t size)
Definition: tsig.h:100
tsig_rr_struct::error_code
uint16_t error_code
Definition: tsig.h:142
tsig_rr_struct::signed_time_high
uint16_t signed_time_high
Definition: tsig.h:136
tsig_algo_struct::txt_name
const char * txt_name
Definition: tsig.h:90
tsig_struct::name
const char * name
Definition: tsig.h:112
tsig_rr_error
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:742
buffer_pkt_qr
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:810
tsig_rr_prepare
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:537
tsig_struct
Definition: tsig.h:110
tsig_algo_struct::hmac_init
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.h:97
tsig_rr_struct::mac_size
uint16_t mac_size
Definition: tsig.h:139
tsig_key_table_struct::key
tsig_key_type * key
Definition: tsig.c:54
buffer_pkt_ancount
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1018
tsig_rr_cleanup
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:832
TSIG_ERROR_BADTIME
#define TSIG_ERROR_BADTIME
Definition: tsig.h:45
tsig_status
enum tsig_status_enum tsig_status
Definition: tsig.h:60
tsig_rr_update
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:559
tsig_lookup_by_name
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
Definition: tsig.c:235
buffer_position
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:125
tsig_struct::key
tsig_key_type * key
Definition: tsig.h:115
tsig_status2str
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:759
tsig_handler_add_algo
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition: tsig.c:93
tsig_create
tsig_type * tsig_create(char *name, char *algo, char *secret)
Definition: tsig.c:208
tsig_rr_struct
Definition: tsig.h:123
TSIG_ERROR_BADSIG
#define TSIG_ERROR_BADSIG
Definition: tsig.h:43
buffer_write_u16
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:565
tsig_rr_parse
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:322
tsig_rr_struct::prior_mac_data
uint8_t * prior_mac_data
Definition: tsig.h:132
tsig_rr_struct::signed_time_fudge
uint16_t signed_time_fudge
Definition: tsig.h:138
tsig_algo_table_struct::next
tsig_algo_table_type * next
Definition: tsig.c:60
tsig_rr_struct::update_since_last_prepare
size_t update_since_last_prepare
Definition: tsig.h:127
tsig_cleanup
void tsig_cleanup(tsig_type *tsig)
Definition: tsig.c:847
buffer_read_u32
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:736
tsig_rr_struct::other_data
uint8_t * other_data
Definition: tsig.h:144
tsig_algo_struct::wf_name
ldns_rdf * wf_name
Definition: tsig.h:91
tsig_struct::next
tsig_type * next
Definition: tsig.h:111
tsig_key_table_struct::next
tsig_key_table_type * next
Definition: tsig.c:53
tsig_rr_struct::prior_mac_size
size_t prior_mac_size
Definition: tsig.h:131
buffer_write_u16_at
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:512
tsig_algo_table_struct::algorithm
tsig_algo_type * algorithm
Definition: tsig.c:61
buffer_set_position
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:137
tsig_struct::algorithm
const char * algorithm
Definition: tsig.h:113
tsig_rr_free
void tsig_rr_free(tsig_rr_type *trr)
Definition: tsig.c:811
tsig_lookup_algo
tsig_algo_type * tsig_lookup_algo(const char *name)
Definition: tsig.c:257
tsig_handler_cleanup
void tsig_handler_cleanup(void)
Definition: tsig.c:135
buffer_pkt_nscount
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1042
buffer_skip
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:150
buffer_pkt_arcount
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1066
tsig_algo_struct
Definition: tsig.h:89
buffer_struct
Definition: buffer.h:112
tsig_key_table_struct
Definition: tsig.c:52
tsig_rr_struct::key_name
ldns_rdf * key_name
Definition: tsig.h:134
buffer_write_rdf
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:591
tsig_rr_struct::position
size_t position
Definition: tsig.h:125
tsig.h
tsig_rr_reset
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:292
tsig_algo_struct::max_digest_size
size_t max_digest_size
Definition: tsig.h:92
TSIG_ERROR_BADKEY
#define TSIG_ERROR_BADKEY
Definition: tsig.h:44
buffer.h
tsig-openssl.h
tsig_rr_struct::signed_time_low
uint32_t signed_time_low
Definition: tsig.h:137
tsig_rr_struct::key
tsig_key_type * key
Definition: tsig.h:130
tsig_key_struct::size
size_t size
Definition: tsig.h:80
tsig_handler_add_key
void tsig_handler_add_key(tsig_key_type *key)
Definition: tsig.c:73
TSIG_NOT_PRESENT
@ TSIG_NOT_PRESENT
Definition: tsig.h:56
tsig_rr_struct::mac_data
uint8_t * mac_data
Definition: tsig.h:140
tsig_rr_reserved_space
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:713
tsig_struct::secret
const char * secret
Definition: tsig.h:114
buffer_current
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:438
tsig_key_struct
Definition: tsig.h:78
buffer_write
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:538
tsig_rr_append
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:672
tsig_algo_table_struct
Definition: tsig.c:59
tsig_handler_init
ods_status tsig_handler_init()
Definition: tsig.c:116
tsig_algo_struct::hmac_final
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition: tsig.h:102
buffer_limit
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:373
buffer_at
uint8_t * buffer_at(buffer_type *buffer, size_t at)
Definition: buffer.c:413
BUFFER_PKT_HEADER_SIZE
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:43
TSIG_OK
@ TSIG_OK
Definition: tsig.h:57
tsig_rr_struct::original_query_id
uint16_t original_query_id
Definition: tsig.h:141
tsig_rr_create
tsig_rr_type * tsig_rr_create()
Definition: tsig.c:274
buffer_skip_dname
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:310
tsig_key_struct::dname
ldns_rdf * dname
Definition: tsig.h:79
buffer_read_u16
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:721
tsig_rr_verify
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:650
tsig_strerror
const char * tsig_strerror(uint16_t error)
Definition: tsig.c:778
buffer_write_u32
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:578
tsig_rr_struct::status
tsig_status status
Definition: tsig.h:124
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
buffer_write_u8
void buffer_write_u8(buffer_type *buffer, uint8_t data)
Definition: buffer.c:552
tsig_rr_lookup
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:469
buffer_pkt_qdcount
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:994
tsig_rr_struct::context
void * context
Definition: tsig.h:128
buffer_skip_rr
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:342
tsig_algo_struct::hmac_create
void *(* hmac_create)(void)
Definition: tsig.h:95
tsig_rr_sign
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:629
TSIG_SIGNED_TIME_FUDGE
#define TSIG_SIGNED_TIME_FUDGE
Definition: tsig.c:47
tsig_rr_find
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:435
buffer_available
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:487
tsig_rr_struct::algo
tsig_algo_type * algo
Definition: tsig.h:129