OpenDNSSEC-signer  1.4.7
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 "shared/duration.h"
37 #include "shared/file.h"
38 #include "shared/log.h"
39 #include "shared/status.h"
40 #include "shared/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";
51 static allocator_type* tsig_allocator = NULL;
57 };
58 static tsig_key_table_type* tsig_key_table = NULL;
64 };
65 static tsig_algo_table_type* tsig_algo_table = NULL;
67 static size_t max_algo_digest_size = 0;
70  { TSIG_HMAC_MD5, "hmac-md5" },
71 #ifdef HAVE_EVP_SHA1
72  { TSIG_HMAC_SHA1, "hmac-sha1" },
73 #endif
74 #ifdef HAVE_EVP_SHA256
75  { TSIG_HMAC_SHA256, "hmac-sha256" },
76 #endif
77  { 0, NULL }
78 };
79 
80 
85 void
87 {
88  tsig_key_table_type* entry = NULL;
89  if (!key) {
90  return;
91  }
92  entry = (tsig_key_table_type *) allocator_alloc(tsig_allocator,
93  sizeof(tsig_key_table_type));
94  if (entry) {
95  entry->key = key;
96  entry->next = tsig_key_table;
97  tsig_key_table = entry;
98  }
99  return;
100 }
101 
102 
107 void
109 {
110  tsig_algo_table_type* entry = NULL;
111  if (!algo) {
112  return;
113  }
114  entry = (tsig_algo_table_type *) allocator_alloc(tsig_allocator,
115  sizeof(tsig_algo_table_type));
116  if (entry) {
117  entry->algorithm = algo;
118  entry->next = tsig_algo_table;
119  tsig_algo_table = entry;
120  if (algo->max_digest_size > max_algo_digest_size) {
121  max_algo_digest_size = algo->max_digest_size;
122  }
123  }
124  return;
125 }
126 
127 
134 {
135  if (!allocator) {
136  return ODS_STATUS_ERR;
137  }
138  tsig_allocator = allocator;
139  tsig_key_table = NULL;
140  tsig_algo_table = NULL;
141 #ifdef HAVE_SSL
142  ods_log_debug("[%s] init openssl", tsig_str);
143  return tsig_handler_openssl_init(allocator);
144 #endif
145  ods_log_debug("[%s] openssl disabled", tsig_str);
146  return ODS_STATUS_OK;
147 }
148 
149 
154 void
156 {
157  tsig_algo_table_type* aentry = NULL, *anext = NULL;
158  tsig_key_table_type* kentry = NULL, *knext = NULL;
159 #ifdef HAVE_SSL
160  tsig_handler_openssl_finalize();
161 #endif
162 
163  aentry = tsig_algo_table;
164  while (aentry) {
165  anext = aentry->next;
166  ldns_rdf_deep_free(aentry->algorithm->wf_name);
167  allocator_deallocate(tsig_allocator, (void*)aentry->algorithm);
168  allocator_deallocate(tsig_allocator, (void*)aentry);
169  aentry = anext;
170  }
171 
172  kentry = tsig_key_table;
173  while (kentry) {
174  knext = kentry->next;
175  ldns_rdf_deep_free(kentry->key->dname);
176  allocator_deallocate(tsig_allocator, (void*)kentry->key->data);
177  allocator_deallocate(tsig_allocator, (void*)kentry->key);
178  allocator_deallocate(tsig_allocator, (void*)kentry);
179  kentry = knext;
180  }
181  return;
182 }
183 
184 
191 {
192  tsig_key_type* key = NULL;
193  ldns_rdf* dname = NULL;
194  uint8_t* data = NULL;
195  int size = 0;
196  if (!allocator || !tsig || !tsig->name || !tsig->secret) {
197  return NULL;
198  }
199  key = (tsig_key_type*) allocator_alloc(allocator, sizeof(tsig_key_type));
200  if (!key) {
201  return NULL;
202  }
203  dname = ldns_dname_new_frm_str(tsig->name);
204  if (!dname) {
205  return NULL;
206  }
207  data = allocator_alloc(allocator, sizeof(uint8_t) *
208  util_b64_pton_calculate_size(strlen(tsig->secret)));
209  if (!data) {
210  ldns_rdf_deep_free(dname);
211  return NULL;
212  }
213  size = b64_pton(tsig->secret, data,
214  util_b64_pton_calculate_size(strlen(tsig->secret)));
215  if (size < 0) {
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);
219  allocator_deallocate(allocator, (void*)data);
220  }
221  key->dname = dname;
222  key->size = size;
223  key->data = data;
225  return key;
226 }
227 
228 
233 tsig_type*
234 tsig_create(allocator_type* allocator, char* name, char* algo, char* secret)
235 {
236  tsig_type* tsig = NULL;
237  if (!allocator || !name || !algo || !secret) {
238  return NULL;
239  }
240  tsig = (tsig_type*) allocator_alloc(allocator, sizeof(tsig_type));
241  if (!tsig) {
242  ods_log_error("[%s] unable to create tsig: allocator_alloc() "
243  "failed", tsig_str);
244  return NULL;
245  }
246  tsig->next = NULL;
247  tsig->name = allocator_strdup(allocator, name);
248  tsig->algorithm = allocator_strdup(allocator, algo);
249  tsig->secret = allocator_strdup(allocator, secret);
250  tsig->key = tsig_key_create(allocator, tsig);
251  if (!tsig->key) {
252  ods_log_error("[%s] unable to create tsig: tsig_key_create() "
253  "failed", tsig_str);
254  tsig_cleanup(tsig, allocator);
255  return NULL;
256  }
257  return tsig;
258 }
259 
260 
265 tsig_type*
266 tsig_lookup_by_name(tsig_type* tsig, const char* name)
267 {
268  tsig_type* find = NULL;
269  if (!tsig || !name) {
270  return NULL;
271  }
272  find = tsig;
273  while (find) {
274  if (ods_strlowercmp(find->name, name) == 0) {
275  return find;
276  }
277  find = find->next;
278  }
279  return NULL;
280 }
281 
282 
288 tsig_lookup_algo(const char* name)
289 {
290  tsig_algo_table_type* entry = NULL;
291  for (entry = tsig_algo_table; entry; entry = entry->next) {
292  if (ods_strlowercmp(name, entry->algorithm->txt_name) == 0) {
293  return entry->algorithm;
294  }
295  }
296  return NULL;
297 }
298 
299 
306 {
307  tsig_rr_type* trr = NULL;
308  if (!allocator) {
309  return NULL;
310  }
311  trr = (tsig_rr_type*) allocator_alloc(allocator, sizeof(tsig_rr_type));
312  if (!trr) {
313  ods_log_error("[%s] unable to create tsig rr: allocator_alloc() "
314  "failed", tsig_str);
315  return NULL;
316  }
317  trr->allocator = allocator;
318  trr->key_name = NULL;
319  trr->algo_name = NULL;
320  trr->mac_data = NULL;
321  trr->other_data = NULL;
322  tsig_rr_reset(trr, NULL, NULL);
323  return trr;
324 }
325 
326 
331 void
333 {
334  if (!trr) {
335  return;
336  }
337  tsig_rr_free(trr);
338  trr->status = TSIG_NOT_PRESENT;
339  trr->position = 0;
340  trr->response_count = 0;
341  trr->update_since_last_prepare = 0;
342  trr->context = NULL;
343  trr->algo = algo;
344  trr->key = key;
345  trr->prior_mac_size = 0;
346  trr->prior_mac_data = NULL;
347  trr->signed_time_high = 0;
348  trr->signed_time_low = 0;
349  trr->signed_time_fudge = 0;
350  trr->mac_size = 0;
351  trr->original_query_id = 0;
352  trr->error_code = LDNS_RCODE_NOERROR;
353  trr->other_size = 0;
354  return;
355 }
356 
357 
362 int
364 {
365  uint16_t dname_len = 0;
366  ldns_rr_type type = 0;
367  ldns_rr_class klass = 0;
368  uint32_t ttl = 0;
369  uint16_t rdlen = 0;
370  uint16_t curpos = 0;
371  ods_log_assert(trr);
373  ods_log_assert(buffer);
374  trr->status = TSIG_NOT_PRESENT;
375  trr->position = buffer_position(buffer);
376  curpos = trr->position;
377  if (!buffer_skip_dname(buffer)) {
378  buffer_set_position(buffer, trr->position);
379  ods_log_debug("[%s] parse: skip key name failed", tsig_str);
380  return 0;
381  }
382  dname_len = buffer_position(buffer) - curpos;
383  buffer_set_position(buffer, curpos);
384  trr->key_name = ldns_dname_new_frm_data(dname_len,
385  (const void*) buffer_current(buffer));
386  if (!trr->key_name) {
387  buffer_set_position(buffer, trr->position);
388  ods_log_debug("[%s] parse: read key name failed", tsig_str);
389  return 0;
390  }
391  buffer_set_position(buffer, curpos + dname_len);
392  if (!buffer_available(buffer, 10)) {
393  ods_log_debug("[%s] parse: not enough available", tsig_str);
394  buffer_set_position(buffer, trr->position);
395  return 0;
396  }
397  type = (ldns_rr_type) buffer_read_u16(buffer);
398  klass = (ldns_rr_class) buffer_read_u16(buffer);
399  if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
400  /* not present */
401  ods_log_debug("[%s] parse: not TSIG or not ANY", tsig_str,
402  klass, type);
403  buffer_set_position(buffer, trr->position);
404  return 1;
405  }
406  ttl = buffer_read_u32(buffer);
407  rdlen = buffer_read_u16(buffer);
408  /* default to error */
409  trr->status = TSIG_ERROR;
410  trr->error_code = LDNS_RCODE_FORMERR;
411  if (ttl || !buffer_available(buffer, rdlen)) {
412  ods_log_debug("[%s] parse: TTL!=0 or RDLEN=0", tsig_str);
413  buffer_set_position(buffer, trr->position);
414  return 0;
415  }
416  curpos = buffer_position(buffer);
417  if (!buffer_skip_dname(buffer)) {
418  ods_log_debug("[%s] parse: skip algo name failed", tsig_str);
419  buffer_set_position(buffer, trr->position);
420  return 0;
421  }
422  dname_len = buffer_position(buffer) - curpos;
423  buffer_set_position(buffer, curpos);
424  trr->algo_name = ldns_dname_new_frm_data(dname_len,
425  (const void*) buffer_current(buffer));
426  if (!trr->algo_name) {
427  ods_log_debug("[%s] parse: read algo name failed", tsig_str);
428  buffer_set_position(buffer, trr->position);
429  return 0;
430  }
431  buffer_set_position(buffer, curpos + dname_len);
432  if (!buffer_available(buffer, 10)) {
433  ods_log_debug("[%s] parse: not enough available", tsig_str);
434  buffer_set_position(buffer, trr->position);
435  return 0;
436  }
437  trr->signed_time_high = buffer_read_u16(buffer);
438  trr->signed_time_low = buffer_read_u32(buffer);
439  trr->signed_time_fudge = buffer_read_u16(buffer);
440  trr->mac_size = buffer_read_u16(buffer);
441  if (!buffer_available(buffer, trr->mac_size)) {
442  ods_log_debug("[%s] parse: wrong mac size", tsig_str);
443  buffer_set_position(buffer, trr->position);
444  trr->mac_size = 0;
445  return 0;
446  }
447  trr->mac_data = (uint8_t *) allocator_alloc_init(trr->allocator,
448  trr->mac_size, (const void*) buffer_current(buffer));
449  buffer_skip(buffer, trr->mac_size);
450  if (!buffer_available(buffer, 6)) {
451  ods_log_debug("[%s] parse: not enough available", tsig_str);
452  buffer_set_position(buffer, trr->position);
453  return 0;
454  }
455  trr->original_query_id = buffer_read_u16(buffer);
456  trr->error_code = buffer_read_u16(buffer);
457  trr->other_size = buffer_read_u16(buffer);
458  if (!buffer_available(buffer, trr->other_size) || trr->other_size > 16) {
459  ods_log_debug("[%s] parse: not enough available", tsig_str);
460  trr->other_size = 0;
461  buffer_set_position(buffer, trr->position);
462  return 0;
463  }
464  trr->other_data = (uint8_t *) allocator_alloc_init(trr->allocator,
465  trr->other_size, (const void*) buffer_current(buffer));
466  buffer_skip(buffer, trr->other_size);
467  trr->status = TSIG_OK;
468  return 1;
469 }
470 
471 
476 int
478 {
479  size_t saved_pos = 0;
480  size_t rrcount = 0;
481  size_t i = 0;
482  int result = 0;
483  ods_log_assert(trr);
484  ods_log_assert(buffer);
485  if (buffer_pkt_arcount(buffer) == 0) {
486  trr->status = TSIG_NOT_PRESENT;
487  return 1;
488  }
489  saved_pos = buffer_position(buffer);
490  rrcount = buffer_pkt_qdcount(buffer) + buffer_pkt_ancount(buffer) +
491  buffer_pkt_nscount(buffer) + buffer_pkt_arcount(buffer);
493  for (i=0; i < rrcount - 1; i++) {
494  if (!buffer_skip_rr(buffer, i < buffer_pkt_qdcount(buffer))) {
495  buffer_set_position(buffer, saved_pos);
496  return 0;
497  }
498  }
499  result = tsig_rr_parse(trr, buffer);
500  buffer_set_position(buffer, saved_pos);
501  return result;
502 }
503 
504 
509 int
511 {
512  tsig_key_table_type* kentry = NULL;
513  tsig_key_type* key = NULL;
514  tsig_algo_table_type* aentry = NULL;
515  tsig_algo_type* algorithm = NULL;
516  uint64_t current_time = 0;
517  uint64_t signed_time = 0;
518  ods_log_assert(trr);
519  ods_log_assert(trr->status == TSIG_OK);
520  ods_log_assert(!trr->algo);
521  ods_log_assert(!trr->key);
522  for (kentry = tsig_key_table; kentry; kentry = kentry->next) {
523  if (ldns_dname_compare(trr->key_name, kentry->key->dname) == 0) {
524  key = kentry->key;
525  break;
526  }
527  }
528  for (aentry = tsig_algo_table; aentry; aentry = aentry->next) {
529  if (ldns_dname_compare(trr->algo_name,
530  aentry->algorithm->wf_name) == 0) {
531  algorithm = aentry->algorithm;
532  break;
533  }
534  }
535  if (!key || !algorithm) {
536  /* algorithm or key is unknown, cannot authenticate. */
537  ods_log_debug("[%s] algorithm or key missing", tsig_str);
539  return 0;
540  }
541  if ((trr->algo && algorithm != trr->algo) ||
542  (trr->key && key != trr->key)) {
543  /* algorithm or key changed during a single connection, error. */
544  ods_log_debug("[%s] algorithm or key has changed", tsig_str);
546  return 0;
547  }
548  signed_time = ((((uint64_t) trr->signed_time_high) << 32) |
549  ((uint64_t) trr->signed_time_low));
550  current_time = (uint64_t) time_now();
551  if ((current_time < signed_time - trr->signed_time_fudge) ||
552  (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;
558  trr->other_size = 6;
559  trr->other_data = (uint8_t *) allocator_alloc(trr->allocator,
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);
563  ods_log_debug("[%s] bad time", tsig_str);
564  return 0;
565  }
566  trr->algo = algorithm;
567  trr->key = key;
568  trr->response_count = 0;
569  trr->prior_mac_size = 0;
570  return 1;
571 }
572 
573 
578 void
580 {
581  ods_log_assert(trr->algo);
583  if (!trr->context) {
584  trr->context = trr->algo->hmac_create(trr->allocator);
585  trr->prior_mac_data = (uint8_t *) allocator_alloc(
586  trr->allocator, trr->algo->max_digest_size);
587  }
588  trr->algo->hmac_init(trr->context, trr->algo, trr->key);
589  if (trr->prior_mac_size > 0) {
590  uint16_t mac_size = htons(trr->prior_mac_size);
591  trr->algo->hmac_update(trr->context, &mac_size, sizeof(mac_size));
592  trr->algo->hmac_update(trr->context, trr->prior_mac_data,
593  trr->prior_mac_size);
594  }
595  trr->update_since_last_prepare = 0;
596  return;
597 }
598 
603 void
604 tsig_rr_update(tsig_rr_type* trr, buffer_type* buffer, size_t length)
605 {
606  uint16_t original_query_id = 0;
607  ods_log_assert(trr);
608  ods_log_assert(trr->algo);
609  ods_log_assert(trr->context);
610  ods_log_assert(buffer);
611  ods_log_assert(length <= buffer_limit(buffer));
612  original_query_id = htons(trr->original_query_id);
613  trr->algo->hmac_update(trr->context, &original_query_id,
614  sizeof(original_query_id));
615  trr->algo->hmac_update(trr->context,
616  buffer_at(buffer, sizeof(original_query_id)),
617  length - sizeof(original_query_id));
618  if (buffer_pkt_qr(buffer)) {
619  ++trr->response_count;
620  }
622  return;
623 }
624 
625 
630 static void
631 tsig_rr_digest_variables(tsig_rr_type* trr, int tsig_timers_only)
632 {
633  uint16_t klass = htons(LDNS_RR_CLASS_ANY);
634  uint32_t ttl = htonl(0);
635  uint16_t signed_time_high = htons(trr->signed_time_high);
636  uint32_t signed_time_low = htonl(trr->signed_time_low);
637  uint16_t signed_time_fudge = htons(trr->signed_time_fudge);
638  uint16_t error_code = htons(trr->error_code);
639  uint16_t other_size = htons(trr->other_size);
640  ods_log_assert(trr->context);
641  ods_log_assert(trr->algo);
642  ods_log_assert(trr->key_name);
643  if (!tsig_timers_only) {
644  ods_log_assert(trr->key_name);
646  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->key_name),
647  ldns_rdf_size(trr->key_name));
648  trr->algo->hmac_update(trr->context, &klass, sizeof(klass));
649  trr->algo->hmac_update(trr->context, &ttl, sizeof(ttl));
650  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->algo_name),
651  ldns_rdf_size(trr->algo_name));
652  }
653  trr->algo->hmac_update(trr->context, &signed_time_high,
654  sizeof(signed_time_high));
655  trr->algo->hmac_update(trr->context, &signed_time_low,
656  sizeof(signed_time_low));
657  trr->algo->hmac_update(trr->context, &signed_time_fudge,
658  sizeof(signed_time_fudge));
659  if (!tsig_timers_only) {
660  trr->algo->hmac_update(trr->context, &error_code,
661  sizeof(error_code));
662  trr->algo->hmac_update(trr->context, &other_size,
663  sizeof(other_size));
664  trr->algo->hmac_update(trr->context, trr->other_data,
665  trr->other_size);
666  }
667  return;
668 }
669 
670 
675 void
677 {
678  uint64_t current_time = (uint64_t) time_now();
679  ods_log_assert(trr);
680  ods_log_assert(trr->context);
681  trr->signed_time_high = (uint16_t) (current_time >> 32);
682  trr->signed_time_low = (uint32_t) current_time;
684  tsig_rr_digest_variables(trr, trr->response_count > 1);
685  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
686  &trr->prior_mac_size);
687  trr->mac_size = trr->prior_mac_size;
688  trr->mac_data = trr->prior_mac_data;
689  return;
690 }
691 
692 
697 int
699 {
700  ods_log_assert(trr);
701  ods_log_assert(trr->algo);
702  tsig_rr_digest_variables(trr, trr->response_count > 1);
703  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
704  &trr->prior_mac_size);
705  if (trr->mac_size != trr->prior_mac_size ||
706  memcmp(trr->mac_data, trr->prior_mac_data, trr->mac_size) != 0) {
707  /* digest is incorrect, cannot authenticate. */
709  return 0;
710  }
711  return 1;
712 }
713 
714 
719 void
721 {
722  size_t rdlength_pos = 0;
723  if (!trr || !buffer) {
724  return;
725  }
726  /* [TODO] key name compression? */
727  if (trr->key_name) {
728  buffer_write_rdf(buffer, trr->key_name);
729  } else {
730  buffer_write_u8(buffer, 0);
731  }
732  buffer_write_u16(buffer, (uint16_t)LDNS_RR_TYPE_TSIG);
733  buffer_write_u16(buffer, (uint16_t)LDNS_RR_CLASS_ANY);
734  buffer_write_u32(buffer, 0); /* TTL */
735  rdlength_pos = buffer_position(buffer);
736  buffer_skip(buffer, sizeof(uint16_t));
737  if (trr->algo_name) {
738  buffer_write_rdf(buffer, trr->algo_name);
739  } else {
740  buffer_write_u8(buffer, 0);
741  }
742  buffer_write_u16(buffer, trr->signed_time_high);
743  buffer_write_u32(buffer, trr->signed_time_low);
744  buffer_write_u16(buffer, trr->signed_time_fudge);
745  buffer_write_u16(buffer, trr->mac_size);
746  buffer_write(buffer, trr->mac_data, trr->mac_size);
747  buffer_write_u16(buffer, trr->original_query_id);
748  buffer_write_u16(buffer, trr->error_code);
749  buffer_write_u16(buffer, trr->other_size);
750  buffer_write(buffer, trr->other_data, trr->other_size);
751  buffer_write_u16_at(buffer, rdlength_pos,
752  buffer_position(buffer) - rdlength_pos - sizeof(uint16_t));
753  return;
754 }
755 
756 
757 /*
758  * The amount of space to reserve in the response for the TSIG data.
759  *
760  */
761 size_t
763 {
764  if (!trr || trr->status == TSIG_NOT_PRESENT) {
765  return 0;
766  }
767  return (
768  (trr->key_name?ldns_rdf_size(trr->key_name):1)
769  + sizeof(uint16_t) /* Type */
770  + sizeof(uint16_t) /* Class */
771  + sizeof(uint32_t) /* TTL */
772  + sizeof(uint16_t) /* RDATA length */
773  + (trr->algo_name?ldns_rdf_size(trr->algo_name):1)
774  + sizeof(uint16_t) /* Signed time (high) */
775  + sizeof(uint32_t) /* Signed time (low) */
776  + sizeof(uint16_t) /* Signed time fudge */
777  + sizeof(uint16_t) /* MAC size */
778  + max_algo_digest_size /* MAC data */
779  + sizeof(uint16_t) /* Original query ID */
780  + sizeof(uint16_t) /* Error code */
781  + sizeof(uint16_t) /* Other size */
782  + trr->other_size); /* Other data */
783 }
784 
785 
790 void
792 {
793  if (!trr) {
794  return;
795  }
796  if (trr->mac_data) {
797  memset(trr->mac_data, 0, trr->mac_size);
798  }
799  trr->mac_size = 0;
800  return;
801 }
802 
803 
808 const char*
810 {
811  switch (status) {
812  case TSIG_NOT_PRESENT:
813  return "NOT PRESENT";
814  case TSIG_OK:
815  return "OK";
816  case TSIG_ERROR:
817  return "ERROR";
818  }
819  return "UNKNOWN";
820 }
821 
822 
827 const char*
828 tsig_strerror(uint16_t error)
829 {
830  static char message[1000];
831  switch (error) {
832  case 0:
833  return "No Error";
834  break;
835  case TSIG_ERROR_BADSIG:
836  return "Bad Signature";
837  break;
838  case TSIG_ERROR_BADKEY:
839  return "Bad Key";
840  break;
841  case TSIG_ERROR_BADTIME:
842  return "Bad Time";
843  break;
844  default:
845  if (error < 16) {
846  /* DNS rcodes */
847  return (const char*) ldns_pkt_rcode2str(error);
848  }
849  snprintf(message, sizeof(message), "Unknown Error %d", error);
850  break;
851  }
852  return message;
853 }
854 
855 
860 void
862 {
863  if (!trr || !trr->allocator) {
864  return;
865  }
866  ldns_rdf_deep_free(trr->key_name);
867  ldns_rdf_deep_free(trr->algo_name);
868  allocator_deallocate(trr->allocator, (void*) trr->mac_data);
869  allocator_deallocate(trr->allocator, (void*) trr->other_data);
870  trr->key_name = NULL;
871  trr->algo_name = NULL;
872  trr->mac_data = NULL;
873  trr->other_data = NULL;
874  return;
875 }
876 
877 
882 void
884 {
885  allocator_type* allocator = NULL;
886  if (!trr || !trr->allocator) {
887  return;
888  }
889  tsig_rr_free(trr);
890  allocator = trr->allocator;
891  allocator_deallocate(allocator, (void*) trr);
892  return;
893 }
894 
895 
900 void
902 {
903  if (!tsig || !allocator) {
904  return;
905  }
906  tsig_cleanup(tsig->next, allocator);
907  allocator_deallocate(allocator, (void*) tsig->name);
908  allocator_deallocate(allocator, (void*) tsig->algorithm);
909  allocator_deallocate(allocator, (void*) tsig->secret);
910  allocator_deallocate(allocator, (void*) tsig);
911  return;
912 }
#define TSIG_ERROR_BADTIME
Definition: tsig.h:46
void tsig_rr_free(tsig_rr_type *trr)
Definition: tsig.c:861
tsig_algo_type * algo
Definition: tsig.h:131
void tsig_handler_cleanup(void)
Definition: tsig.c:155
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:604
tsig_status status
Definition: tsig.h:126
tsig_algo_table_type * next
Definition: tsig.c:62
allocator_type * allocator
Definition: tsig.h:125
void *(* hmac_create)(allocator_type *allocator)
Definition: tsig.h:96
size_t max_digest_size
Definition: tsig.h:93
uint16_t mac_size
Definition: tsig.h:141
tsig_algo_type * algorithm
Definition: tsig.c:63
uint16_t signed_time_high
Definition: tsig.h:138
#define TSIG_HMAC_SHA256
Definition: tsig.h:50
void ods_log_debug(const char *format,...)
Definition: log.c:270
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:363
uint8_t * buffer_at(buffer_type *buffer, size_t at)
Definition: buffer.c:452
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1136
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:43
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:66
uint16_t error_code
Definition: tsig.h:144
const char * tsig_strerror(uint16_t error)
Definition: tsig.c:828
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:1061
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:186
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:781
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:380
#define TSIG_SIGNED_TIME_FUDGE
Definition: tsig.c:47
size_t util_b64_pton_calculate_size(size_t srcsize)
Definition: util.c:416
uint8_t * prior_mac_data
Definition: tsig.h:134
enum ods_enum_status ods_status
Definition: status.h:90
void buffer_write_u8(buffer_type *buffer, uint8_t data)
Definition: buffer.c:607
tsig_algo_type * tsig_lookup_algo(const char *name)
Definition: tsig.c:288
void ods_log_error(const char *format,...)
Definition: log.c:334
#define TSIG_HMAC_MD5
Definition: tsig.h:48
void(* hmac_update)(void *context, const void *data, size_t size)
Definition: tsig.h:101
ldns_rdf * wf_name
Definition: tsig.h:92
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:872
ods_status tsig_handler_init(allocator_type *allocator)
Definition: tsig.c:133
uint16_t signed_time_fudge
Definition: tsig.h:140
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:332
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:720
size_t update_since_last_prepare
Definition: tsig.h:129
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:592
uint8_t * other_data
Definition: tsig.h:146
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:489
size_t prior_mac_size
Definition: tsig.h:133
const char * algorithm
Definition: tsig.h:114
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:411
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1086
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:579
tsig_key_type * key
Definition: tsig.h:116
void tsig_cleanup(tsig_type *tsig, allocator_type *allocator)
Definition: tsig.c:901
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:809
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition: tsig.h:103
ldns_rdf * key_name
Definition: tsig.h:136
tsig_type * next
Definition: tsig.h:112
void tsig_handler_add_key(tsig_key_type *key)
Definition: tsig.c:86
uint8_t * mac_data
Definition: tsig.h:142
Definition: tsig.h:58
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:883
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:348
char * allocator_strdup(allocator_type *allocator, const char *string)
Definition: allocator.c:121
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.h:98
size_t size
Definition: tsig.h:81
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:796
tsig_key_type * key
Definition: tsig.h:132
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:698
uint32_t signed_time_low
Definition: tsig.h:139
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:621
ldns_rdf * dname
Definition: tsig.h:80
#define TSIG_HMAC_SHA1
Definition: tsig.h:49
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:635
#define TSIG_ERROR_BADSIG
Definition: tsig.h:44
tsig_rr_type * tsig_rr_create(allocator_type *allocator)
Definition: tsig.c:305
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:791
const char * secret
Definition: tsig.h:115
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1111
size_t position
Definition: tsig.h:127
tsig_type * tsig_create(allocator_type *allocator, char *name, char *algo, char *secret)
Definition: tsig.c:234
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:564
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:172
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:477
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:538
uint16_t other_size
Definition: tsig.h:145
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:510
#define TSIG_ERROR_BADKEY
Definition: tsig.h:45
void * context
Definition: tsig.h:130
tsig_lookup_table tsig_supported_algorithms[]
Definition: tsig.c:69
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:649
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:676
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:135
void * allocator_alloc_init(allocator_type *allocator, size_t size, const void *init)
Definition: allocator.c:105
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:160
ldns_rdf * algo_name
Definition: tsig.h:137
size_t response_count
Definition: tsig.h:128
tsig_key_type * tsig_key_create(allocator_type *allocator, tsig_type *tsig)
Definition: tsig.c:190
const uint8_t * data
Definition: tsig.h:82
tsig_key_table_type * next
Definition: tsig.c:55
int ods_strlowercmp(const char *str1, const char *str2)
Definition: file.c:342
tsig_key_type * key
Definition: tsig.c:56
const char * name
Definition: tsig.h:113
#define ods_log_assert(x)
Definition: log.h:154
const char * txt_name
Definition: tsig.h:91
enum tsig_status_enum tsig_status
Definition: tsig.h:61
uint16_t original_query_id
Definition: tsig.h:143
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
Definition: tsig.c:266
time_t time_now(void)
Definition: duration.c:513
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition: tsig.c:108
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:762