OpenDNSSEC-signer  1.4.1
tsig.c
Go to the documentation of this file.
1 /*
2  * $Id: tsig.c 4958 2011-04-18 07:11:09Z matthijs $
3  *
4  * Copyright (c) 2011 NLNet Labs. All rights reserved.
5  *
6  * Taken from NSD3 and adjusted for OpenDNSSEC, NLnet Labs.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
36 #include "config.h"
37 #include "compat.h"
38 #include "shared/duration.h"
39 #include "shared/file.h"
40 #include "shared/log.h"
41 #include "shared/status.h"
42 #include "shared/util.h"
43 #include "wire/buffer.h"
44 #include "wire/tsig.h"
45 #include "wire/tsig-openssl.h"
46 
47 #include <arpa/inet.h>
48 
49 #define TSIG_SIGNED_TIME_FUDGE 300
50 
51 static const char* tsig_str = "tsig";
53 static allocator_type* tsig_allocator = NULL;
59 };
60 static tsig_key_table_type* tsig_key_table = NULL;
66 };
67 static tsig_algo_table_type* tsig_algo_table = NULL;
69 static size_t max_algo_digest_size = 0;
72  { TSIG_HMAC_MD5, "hmac-md5" },
73 #ifdef HAVE_EVP_SHA1
74  { TSIG_HMAC_SHA1, "hmac-sha1" },
75 #endif
76 #ifdef HAVE_EVP_SHA256
77  { TSIG_HMAC_SHA256, "hmac-sha256" },
78 #endif
79  { 0, NULL }
80 };
81 
82 
87 void
89 {
90  tsig_key_table_type* entry = NULL;
91  if (!key) {
92  return;
93  }
94  entry = (tsig_key_table_type *) allocator_alloc(tsig_allocator,
95  sizeof(tsig_key_table_type));
96  if (entry) {
97  entry->key = key;
98  entry->next = tsig_key_table;
99  tsig_key_table = entry;
100  }
101  return;
102 }
103 
104 
109 void
111 {
112  tsig_algo_table_type* entry = NULL;
113  if (!algo) {
114  return;
115  }
116  entry = (tsig_algo_table_type *) allocator_alloc(tsig_allocator,
117  sizeof(tsig_algo_table_type));
118  if (entry) {
119  entry->algorithm = algo;
120  entry->next = tsig_algo_table;
121  tsig_algo_table = entry;
122  if (algo->max_digest_size > max_algo_digest_size) {
123  max_algo_digest_size = algo->max_digest_size;
124  }
125  }
126  return;
127 }
128 
129 
136 {
137  if (!allocator) {
138  return ODS_STATUS_ERR;
139  }
140  tsig_allocator = allocator;
141  tsig_key_table = NULL;
142  tsig_algo_table = NULL;
143 #ifdef HAVE_SSL
144  ods_log_debug("[%s] init openssl", tsig_str);
145  return tsig_handler_openssl_init(allocator);
146 #endif
147  ods_log_debug("[%s] openssl disabled", tsig_str);
148  return ODS_STATUS_OK;
149 }
150 
151 
156 void
158 {
159  tsig_algo_table_type* aentry = NULL, *anext = NULL;
160  tsig_key_table_type* kentry = NULL, *knext = NULL;
161 #ifdef HAVE_SSL
162  tsig_handler_openssl_finalize();
163 #endif
164 
165  aentry = tsig_algo_table;
166  while (aentry) {
167  anext = aentry->next;
168  ldns_rdf_deep_free(aentry->algorithm->wf_name);
169  allocator_deallocate(tsig_allocator, (void*)aentry->algorithm);
170  allocator_deallocate(tsig_allocator, (void*)aentry);
171  aentry = anext;
172  }
173 
174  kentry = tsig_key_table;
175  while (kentry) {
176  knext = kentry->next;
177  ldns_rdf_deep_free(kentry->key->dname);
178  allocator_deallocate(tsig_allocator, (void*)kentry->key->data);
179  allocator_deallocate(tsig_allocator, (void*)kentry->key);
180  allocator_deallocate(tsig_allocator, (void*)kentry);
181  kentry = knext;
182  }
183  return;
184 }
185 
186 
193 {
194  tsig_key_type* key = NULL;
195  ldns_rdf* dname = NULL;
196  uint8_t* data = NULL;
197  int size = 0;
198  if (!allocator || !tsig || !tsig->name || !tsig->secret) {
199  return NULL;
200  }
201  key = (tsig_key_type*) allocator_alloc(allocator, sizeof(tsig_key_type));
202  if (!key) {
203  return NULL;
204  }
205  dname = ldns_dname_new_frm_str(tsig->name);
206  if (!dname) {
207  return NULL;
208  }
209  data = allocator_alloc(allocator, sizeof(uint8_t) *
210  util_b64_pton_calculate_size(strlen(tsig->secret)));
211  if (!data) {
212  ldns_rdf_deep_free(dname);
213  return NULL;
214  }
215  size = b64_pton(tsig->secret, data,
216  util_b64_pton_calculate_size(strlen(tsig->secret)));
217  if (size < 0) {
218  ods_log_error("[%s] unable to create tsig key %s: failed to parse "
219  "secret", tsig_str, tsig->name);
220  ldns_rdf_deep_free(dname);
221  allocator_deallocate(allocator, (void*)data);
222  }
223  key->dname = dname;
224  key->size = size;
225  key->data = data;
227  return key;
228 }
229 
230 
235 tsig_type*
236 tsig_create(allocator_type* allocator, char* name, char* algo, char* secret)
237 {
238  tsig_type* tsig = NULL;
239  if (!allocator || !name || !algo || !secret) {
240  return NULL;
241  }
242  tsig = (tsig_type*) allocator_alloc(allocator, sizeof(tsig_type));
243  if (!tsig) {
244  ods_log_error("[%s] unable to create tsig: allocator_alloc() "
245  "failed", tsig_str);
246  return NULL;
247  }
248  tsig->next = NULL;
249  tsig->name = allocator_strdup(allocator, name);
250  tsig->algorithm = allocator_strdup(allocator, algo);
251  tsig->secret = allocator_strdup(allocator, secret);
252  tsig->key = tsig_key_create(allocator, tsig);
253  if (!tsig->key) {
254  ods_log_error("[%s] unable to create tsig: tsig_key_create() "
255  "failed", tsig_str);
256  tsig_cleanup(tsig, allocator);
257  return NULL;
258  }
259  return tsig;
260 }
261 
262 
267 tsig_type*
268 tsig_lookup_by_name(tsig_type* tsig, const char* name)
269 {
270  tsig_type* find = NULL;
271  if (!tsig || !name) {
272  return NULL;
273  }
274  find = tsig;
275  while (find) {
276  if (ods_strlowercmp(find->name, name) == 0) {
277  return find;
278  }
279  find = find->next;
280  }
281  return NULL;
282 }
283 
284 
290 tsig_lookup_algo(const char* name)
291 {
292  tsig_algo_table_type* entry = NULL;
293  for (entry = tsig_algo_table; entry; entry = entry->next) {
294  if (ods_strlowercmp(name, entry->algorithm->txt_name) == 0) {
295  return entry->algorithm;
296  }
297  }
298  return NULL;
299 }
300 
301 
308 {
309  tsig_rr_type* trr = NULL;
310  if (!allocator) {
311  return NULL;
312  }
313  trr = (tsig_rr_type*) allocator_alloc(allocator, sizeof(tsig_rr_type));
314  if (!trr) {
315  ods_log_error("[%s] unable to create tsig rr: allocator_alloc() "
316  "failed", tsig_str);
317  return NULL;
318  }
319  trr->allocator = allocator;
320  trr->key_name = NULL;
321  trr->algo_name = NULL;
322  trr->mac_data = NULL;
323  trr->other_data = NULL;
324  tsig_rr_reset(trr, NULL, NULL);
325  return trr;
326 }
327 
328 
333 void
335 {
336  if (!trr) {
337  return;
338  }
339  tsig_rr_free(trr);
340  trr->status = TSIG_NOT_PRESENT;
341  trr->position = 0;
342  trr->response_count = 0;
343  trr->update_since_last_prepare = 0;
344  trr->context = NULL;
345  trr->algo = algo;
346  trr->key = key;
347  trr->prior_mac_size = 0;
348  trr->prior_mac_data = NULL;
349  trr->signed_time_high = 0;
350  trr->signed_time_low = 0;
351  trr->signed_time_fudge = 0;
352  trr->mac_size = 0;
353  trr->original_query_id = 0;
354  trr->error_code = LDNS_RCODE_NOERROR;
355  trr->other_size = 0;
356  return;
357 }
358 
359 
364 int
366 {
367  uint16_t dname_len = 0;
368  ldns_rr_type type = 0;
369  ldns_rr_class klass = 0;
370  uint32_t ttl = 0;
371  uint16_t rdlen = 0;
372  uint16_t curpos = 0;
373  ods_log_assert(trr);
375  ods_log_assert(buffer);
376  trr->status = TSIG_NOT_PRESENT;
377  trr->position = buffer_position(buffer);
378  curpos = trr->position;
379  if (!buffer_skip_dname(buffer)) {
380  buffer_set_position(buffer, trr->position);
381  ods_log_debug("[%s] parse: skip key name failed", tsig_str);
382  return 0;
383  }
384  dname_len = buffer_position(buffer) - curpos;
385  buffer_set_position(buffer, curpos);
386  trr->key_name = ldns_dname_new_frm_data(dname_len,
387  (const void*) buffer_current(buffer));
388  if (!trr->key_name) {
389  buffer_set_position(buffer, trr->position);
390  ods_log_debug("[%s] parse: read key name failed", tsig_str);
391  return 0;
392  }
393  buffer_set_position(buffer, curpos + dname_len);
394  if (!buffer_available(buffer, 10)) {
395  ods_log_debug("[%s] parse: not enough available", tsig_str);
396  buffer_set_position(buffer, trr->position);
397  return 0;
398  }
399  type = (ldns_rr_type) buffer_read_u16(buffer);
400  klass = (ldns_rr_class) buffer_read_u16(buffer);
401  if (type != LDNS_RR_TYPE_TSIG || klass != LDNS_RR_CLASS_ANY) {
402  /* not present */
403  ods_log_debug("[%s] parse: not TSIG or not ANY", tsig_str,
404  klass, type);
405  buffer_set_position(buffer, trr->position);
406  return 1;
407  }
408  ttl = buffer_read_u32(buffer);
409  rdlen = buffer_read_u16(buffer);
410  /* default to error */
411  trr->status = TSIG_ERROR;
412  trr->error_code = LDNS_RCODE_FORMERR;
413  if (ttl || !buffer_available(buffer, rdlen)) {
414  ods_log_debug("[%s] parse: TTL!=0 or RDLEN=0", tsig_str);
415  buffer_set_position(buffer, trr->position);
416  return 0;
417  }
418  curpos = buffer_position(buffer);
419  if (!buffer_skip_dname(buffer)) {
420  ods_log_debug("[%s] parse: skip algo name failed", tsig_str);
421  buffer_set_position(buffer, trr->position);
422  return 0;
423  }
424  dname_len = buffer_position(buffer) - curpos;
425  buffer_set_position(buffer, curpos);
426  trr->algo_name = ldns_dname_new_frm_data(dname_len,
427  (const void*) buffer_current(buffer));
428  if (!trr->algo_name) {
429  ods_log_debug("[%s] parse: read algo name failed", tsig_str);
430  buffer_set_position(buffer, trr->position);
431  return 0;
432  }
433  buffer_set_position(buffer, curpos + dname_len);
434  if (!buffer_available(buffer, 10)) {
435  ods_log_debug("[%s] parse: not enough available", tsig_str);
436  buffer_set_position(buffer, trr->position);
437  return 0;
438  }
439  trr->signed_time_high = buffer_read_u16(buffer);
440  trr->signed_time_low = buffer_read_u32(buffer);
441  trr->signed_time_fudge = buffer_read_u16(buffer);
442  trr->mac_size = buffer_read_u16(buffer);
443  if (!buffer_available(buffer, trr->mac_size)) {
444  ods_log_debug("[%s] parse: wrong mac size", tsig_str);
445  buffer_set_position(buffer, trr->position);
446  trr->mac_size = 0;
447  return 0;
448  }
449  trr->mac_data = (uint8_t *) allocator_alloc_init(trr->allocator,
450  trr->mac_size, (const void*) buffer_current(buffer));
451  buffer_skip(buffer, trr->mac_size);
452  if (!buffer_available(buffer, 6)) {
453  ods_log_debug("[%s] parse: not enough available", tsig_str);
454  buffer_set_position(buffer, trr->position);
455  return 0;
456  }
457  trr->original_query_id = buffer_read_u16(buffer);
458  trr->error_code = buffer_read_u16(buffer);
459  trr->other_size = buffer_read_u16(buffer);
460  if (!buffer_available(buffer, trr->other_size) || trr->other_size > 16) {
461  ods_log_debug("[%s] parse: not enough available", tsig_str);
462  trr->other_size = 0;
463  buffer_set_position(buffer, trr->position);
464  return 0;
465  }
466  trr->other_data = (uint8_t *) allocator_alloc_init(trr->allocator,
467  trr->other_size, (const void*) buffer_current(buffer));
468  buffer_skip(buffer, trr->other_size);
469  trr->status = TSIG_OK;
470  return 1;
471 }
472 
473 
478 int
480 {
481  size_t saved_pos = 0;
482  size_t rrcount = 0;
483  size_t i = 0;
484  int result = 0;
485  ods_log_assert(trr);
486  ods_log_assert(buffer);
487  if (buffer_pkt_arcount(buffer) == 0) {
488  trr->status = TSIG_NOT_PRESENT;
489  return 1;
490  }
491  saved_pos = buffer_position(buffer);
492  rrcount = buffer_pkt_qdcount(buffer) + buffer_pkt_ancount(buffer) +
493  buffer_pkt_nscount(buffer) + buffer_pkt_arcount(buffer);
495  for (i=0; i < rrcount - 1; i++) {
496  if (!buffer_skip_rr(buffer, i < buffer_pkt_qdcount(buffer))) {
497  buffer_set_position(buffer, saved_pos);
498  return 0;
499  }
500  }
501  result = tsig_rr_parse(trr, buffer);
502  buffer_set_position(buffer, saved_pos);
503  return result;
504 }
505 
506 
511 int
513 {
514  tsig_key_table_type* kentry = NULL;
515  tsig_key_type* key = NULL;
516  tsig_algo_table_type* aentry = NULL;
517  tsig_algo_type* algorithm = NULL;
518  uint64_t current_time = 0;
519  uint64_t signed_time = 0;
520  ods_log_assert(trr);
521  ods_log_assert(trr->status == TSIG_OK);
522  ods_log_assert(!trr->algo);
523  ods_log_assert(!trr->key);
524  for (kentry = tsig_key_table; kentry; kentry = kentry->next) {
525  if (ldns_dname_compare(trr->key_name, kentry->key->dname) == 0) {
526  key = kentry->key;
527  break;
528  }
529  }
530  for (aentry = tsig_algo_table; aentry; aentry = aentry->next) {
531  if (ldns_dname_compare(trr->algo_name,
532  aentry->algorithm->wf_name) == 0) {
533  algorithm = aentry->algorithm;
534  break;
535  }
536  }
537  if (!key || !algorithm) {
538  /* algorithm or key is unknown, cannot authenticate. */
539  ods_log_debug("[%s] algorithm or key missing", tsig_str);
541  return 0;
542  }
543  if ((trr->algo && algorithm != trr->algo) ||
544  (trr->key && key != trr->key)) {
545  /* algorithm or key changed during a single connection, error. */
546  ods_log_debug("[%s] algorithm or key has changed", tsig_str);
548  return 0;
549  }
550  signed_time = ((((uint64_t) trr->signed_time_high) << 32) |
551  ((uint64_t) trr->signed_time_low));
552  current_time = (uint64_t) time_now();
553  if ((current_time < signed_time - trr->signed_time_fudge) ||
554  (current_time > signed_time + trr->signed_time_fudge)) {
555  uint16_t current_time_high;
556  uint32_t current_time_low;
558  current_time_high = (uint16_t) (current_time >> 32);
559  current_time_low = (uint32_t) current_time;
560  trr->other_size = 6;
561  trr->other_data = (uint8_t *) allocator_alloc(trr->allocator,
562  sizeof(uint16_t) + sizeof(uint32_t));
563  write_uint16(trr->other_data, current_time_high);
564  write_uint32(trr->other_data + 2, current_time_low);
565  ods_log_debug("[%s] bad time", tsig_str);
566  return 0;
567  }
568  trr->algo = algorithm;
569  trr->key = key;
570  trr->response_count = 0;
571  trr->prior_mac_size = 0;
572  return 1;
573 }
574 
575 
580 void
582 {
583  ods_log_assert(trr->algo);
585  if (!trr->context) {
586  trr->context = trr->algo->hmac_create(trr->allocator);
587  trr->prior_mac_data = (uint8_t *) allocator_alloc(
588  trr->allocator, trr->algo->max_digest_size);
589  }
590  trr->algo->hmac_init(trr->context, trr->algo, trr->key);
591  if (trr->prior_mac_size > 0) {
592  uint16_t mac_size = htons(trr->prior_mac_size);
593  trr->algo->hmac_update(trr->context, &mac_size, sizeof(mac_size));
594  trr->algo->hmac_update(trr->context, trr->prior_mac_data,
595  trr->prior_mac_size);
596  }
597  trr->update_since_last_prepare = 0;
598  return;
599 }
600 
605 void
606 tsig_rr_update(tsig_rr_type* trr, buffer_type* buffer, size_t length)
607 {
608  uint16_t original_query_id = 0;
609  ods_log_assert(trr);
610  ods_log_assert(trr->algo);
611  ods_log_assert(trr->context);
612  ods_log_assert(buffer);
613  ods_log_assert(length <= buffer_limit(buffer));
614  original_query_id = htons(trr->original_query_id);
615  trr->algo->hmac_update(trr->context, &original_query_id,
616  sizeof(original_query_id));
617  trr->algo->hmac_update(trr->context,
618  buffer_at(buffer, sizeof(original_query_id)),
619  length - sizeof(original_query_id));
620  if (buffer_pkt_qr(buffer)) {
621  ++trr->response_count;
622  }
624  return;
625 }
626 
627 
632 static void
633 tsig_rr_digest_variables(tsig_rr_type* trr, int tsig_timers_only)
634 {
635  uint16_t klass = htons(LDNS_RR_CLASS_ANY);
636  uint32_t ttl = htonl(0);
637  uint16_t signed_time_high = htons(trr->signed_time_high);
638  uint32_t signed_time_low = htonl(trr->signed_time_low);
639  uint16_t signed_time_fudge = htons(trr->signed_time_fudge);
640  uint16_t error_code = htons(trr->error_code);
641  uint16_t other_size = htons(trr->other_size);
642  ods_log_assert(trr->context);
643  ods_log_assert(trr->algo);
644  ods_log_assert(trr->key_name);
645  if (!tsig_timers_only) {
646  ods_log_assert(trr->key_name);
648  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->key_name),
649  ldns_rdf_size(trr->key_name));
650  trr->algo->hmac_update(trr->context, &klass, sizeof(klass));
651  trr->algo->hmac_update(trr->context, &ttl, sizeof(ttl));
652  trr->algo->hmac_update(trr->context, ldns_rdf_data(trr->algo_name),
653  ldns_rdf_size(trr->algo_name));
654  }
655  trr->algo->hmac_update(trr->context, &signed_time_high,
656  sizeof(signed_time_high));
657  trr->algo->hmac_update(trr->context, &signed_time_low,
658  sizeof(signed_time_low));
659  trr->algo->hmac_update(trr->context, &signed_time_fudge,
660  sizeof(signed_time_fudge));
661  if (!tsig_timers_only) {
662  trr->algo->hmac_update(trr->context, &error_code,
663  sizeof(error_code));
664  trr->algo->hmac_update(trr->context, &other_size,
665  sizeof(other_size));
666  trr->algo->hmac_update(trr->context, trr->other_data,
667  trr->other_size);
668  }
669  return;
670 }
671 
672 
677 void
679 {
680  uint64_t current_time = (uint64_t) time_now();
681  ods_log_assert(trr);
682  ods_log_assert(trr->context);
683  trr->signed_time_high = (uint16_t) (current_time >> 32);
684  trr->signed_time_low = (uint32_t) current_time;
686  tsig_rr_digest_variables(trr, trr->response_count > 1);
687  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
688  &trr->prior_mac_size);
689  trr->mac_size = trr->prior_mac_size;
690  trr->mac_data = trr->prior_mac_data;
691  return;
692 }
693 
694 
699 int
701 {
702  ods_log_assert(trr);
703  ods_log_assert(trr->algo);
704  tsig_rr_digest_variables(trr, trr->response_count > 1);
705  trr->algo->hmac_final(trr->context, trr->prior_mac_data,
706  &trr->prior_mac_size);
707  if (trr->mac_size != trr->prior_mac_size ||
708  memcmp(trr->mac_data, trr->prior_mac_data, trr->mac_size) != 0) {
709  /* digest is incorrect, cannot authenticate. */
711  return 0;
712  }
713  return 1;
714 }
715 
716 
721 void
723 {
724  size_t rdlength_pos = 0;
725  if (!trr || !buffer) {
726  return;
727  }
728  /* [TODO] key name compression? */
729  if (trr->key_name) {
730  buffer_write_rdf(buffer, trr->key_name);
731  } else {
732  buffer_write_u8(buffer, 0);
733  }
734  buffer_write_u16(buffer, (uint16_t)LDNS_RR_TYPE_TSIG);
735  buffer_write_u16(buffer, (uint16_t)LDNS_RR_CLASS_ANY);
736  buffer_write_u32(buffer, 0); /* TTL */
737  rdlength_pos = buffer_position(buffer);
738  buffer_skip(buffer, sizeof(uint16_t));
739  if (trr->algo_name) {
740  buffer_write_rdf(buffer, trr->algo_name);
741  } else {
742  buffer_write_u8(buffer, 0);
743  }
744  buffer_write_u16(buffer, trr->signed_time_high);
745  buffer_write_u32(buffer, trr->signed_time_low);
746  buffer_write_u16(buffer, trr->signed_time_fudge);
747  buffer_write_u16(buffer, trr->mac_size);
748  buffer_write(buffer, trr->mac_data, trr->mac_size);
749  buffer_write_u16(buffer, trr->original_query_id);
750  buffer_write_u16(buffer, trr->error_code);
751  buffer_write_u16(buffer, trr->other_size);
752  buffer_write(buffer, trr->other_data, trr->other_size);
753  buffer_write_u16_at(buffer, rdlength_pos,
754  buffer_position(buffer) - rdlength_pos - sizeof(uint16_t));
755  return;
756 }
757 
758 
759 /*
760  * The amount of space to reserve in the response for the TSIG data.
761  *
762  */
763 size_t
765 {
766  if (!trr || trr->status == TSIG_NOT_PRESENT) {
767  return 0;
768  }
769  return (
770  (trr->key_name?ldns_rdf_size(trr->key_name):1)
771  + sizeof(uint16_t) /* Type */
772  + sizeof(uint16_t) /* Class */
773  + sizeof(uint32_t) /* TTL */
774  + sizeof(uint16_t) /* RDATA length */
775  + (trr->algo_name?ldns_rdf_size(trr->algo_name):1)
776  + sizeof(uint16_t) /* Signed time (high) */
777  + sizeof(uint32_t) /* Signed time (low) */
778  + sizeof(uint16_t) /* Signed time fudge */
779  + sizeof(uint16_t) /* MAC size */
780  + max_algo_digest_size /* MAC data */
781  + sizeof(uint16_t) /* Original query ID */
782  + sizeof(uint16_t) /* Error code */
783  + sizeof(uint16_t) /* Other size */
784  + trr->other_size); /* Other data */
785 }
786 
787 
792 void
794 {
795  if (!trr) {
796  return;
797  }
798  if (trr->mac_data) {
799  memset(trr->mac_data, 0, trr->mac_size);
800  }
801  trr->mac_size = 0;
802  return;
803 }
804 
805 
810 const char*
812 {
813  switch (status) {
814  case TSIG_NOT_PRESENT:
815  return "NOT PRESENT";
816  case TSIG_OK:
817  return "OK";
818  case TSIG_ERROR:
819  return "ERROR";
820  }
821  return "UNKNOWN";
822 }
823 
824 
829 const char*
830 tsig_strerror(uint16_t error)
831 {
832  static char message[1000];
833  switch (error) {
834  case 0:
835  return "No Error";
836  break;
837  case TSIG_ERROR_BADSIG:
838  return "Bad Signature";
839  break;
840  case TSIG_ERROR_BADKEY:
841  return "Bad Key";
842  break;
843  case TSIG_ERROR_BADTIME:
844  return "Bad Time";
845  break;
846  default:
847  if (error < 16) {
848  /* DNS rcodes */
849  return (const char*) ldns_pkt_rcode2str(error);
850  }
851  snprintf(message, sizeof(message), "Unknown Error %d", error);
852  break;
853  }
854  return message;
855 }
856 
857 
862 void
864 {
865  if (!trr || !trr->allocator) {
866  return;
867  }
868  ldns_rdf_deep_free(trr->key_name);
869  ldns_rdf_deep_free(trr->algo_name);
870  allocator_deallocate(trr->allocator, (void*) trr->mac_data);
871  allocator_deallocate(trr->allocator, (void*) trr->other_data);
872  trr->key_name = NULL;
873  trr->algo_name = NULL;
874  trr->mac_data = NULL;
875  trr->other_data = NULL;
876  return;
877 }
878 
879 
884 void
886 {
887  allocator_type* allocator = NULL;
888  if (!trr || !trr->allocator) {
889  return;
890  }
891  tsig_rr_free(trr);
892  allocator = trr->allocator;
893  allocator_deallocate(allocator, (void*) trr);
894  return;
895 }
896 
897 
902 void
904 {
905  if (!tsig || !allocator) {
906  return;
907  }
908  tsig_cleanup(tsig->next, allocator);
909  allocator_deallocate(allocator, (void*) tsig->name);
910  allocator_deallocate(allocator, (void*) tsig->algorithm);
911  allocator_deallocate(allocator, (void*) tsig->secret);
912  allocator_deallocate(allocator, (void*) tsig);
913  return;
914 }
void(* hmac_update)(void *context, const void *data, size_t size)
Definition: tsig.h:103
#define TSIG_ERROR_BADTIME
Definition: tsig.h:48
void tsig_rr_free(tsig_rr_type *trr)
Definition: tsig.c:863
tsig_algo_type * algo
Definition: tsig.h:133
void tsig_handler_cleanup(void)
Definition: tsig.c:157
void(* hmac_init)(void *context, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.h:100
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
Definition: tsig.c:606
tsig_status status
Definition: tsig.h:128
tsig_algo_table_type * next
Definition: tsig.c:64
allocator_type * allocator
Definition: tsig.h:127
size_t max_digest_size
Definition: tsig.h:95
uint16_t mac_size
Definition: tsig.h:143
tsig_algo_type * algorithm
Definition: tsig.c:65
uint16_t signed_time_high
Definition: tsig.h:140
#define TSIG_HMAC_SHA256
Definition: tsig.h:52
void ods_log_debug(const char *format,...)
Definition: log.c:272
int tsig_rr_parse(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:365
uint8_t * buffer_at(buffer_type *buffer, size_t at)
Definition: buffer.c:438
uint16_t buffer_pkt_arcount(buffer_type *buffer)
Definition: buffer.c:1106
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:44
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:68
uint16_t error_code
Definition: tsig.h:146
const char * tsig_strerror(uint16_t error)
Definition: tsig.c:830
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
Definition: buffer.c:1031
void buffer_skip(buffer_type *buffer, ssize_t count)
Definition: buffer.c:172
uint16_t buffer_read_u16(buffer_type *buffer)
Definition: buffer.c:767
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
Definition: buffer.c:366
#define TSIG_SIGNED_TIME_FUDGE
Definition: tsig.c:49
size_t util_b64_pton_calculate_size(size_t srcsize)
Definition: util.c:418
uint8_t * prior_mac_data
Definition: tsig.h:136
enum ods_enum_status ods_status
Definition: status.h:89
void buffer_write_u8(buffer_type *buffer, uint8_t data)
Definition: buffer.c:593
tsig_algo_type * tsig_lookup_algo(const char *name)
Definition: tsig.c:290
void ods_log_error(const char *format,...)
Definition: log.c:336
#define TSIG_HMAC_MD5
Definition: tsig.h:50
ldns_rdf * wf_name
Definition: tsig.h:94
int buffer_pkt_qr(buffer_type *buffer)
Definition: buffer.c:858
ods_status tsig_handler_init(allocator_type *allocator)
Definition: tsig.c:135
uint16_t signed_time_fudge
Definition: tsig.h:142
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
Definition: tsig.c:334
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:722
size_t update_since_last_prepare
Definition: tsig.h:131
void buffer_write(buffer_type *buffer, const void *data, size_t count)
Definition: buffer.c:578
uint8_t * other_data
Definition: tsig.h:148
uint8_t * buffer_current(buffer_type *buffer)
Definition: buffer.c:475
size_t prior_mac_size
Definition: tsig.h:135
const char * algorithm
Definition: tsig.h:116
size_t buffer_limit(buffer_type *buffer)
Definition: buffer.c:397
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1056
void tsig_rr_prepare(tsig_rr_type *trr)
Definition: tsig.c:581
tsig_key_type * key
Definition: tsig.h:118
void tsig_cleanup(tsig_type *tsig, allocator_type *allocator)
Definition: tsig.c:903
const char * tsig_status2str(tsig_status status)
Definition: tsig.c:811
ldns_rdf * key_name
Definition: tsig.h:138
tsig_type * next
Definition: tsig.h:114
void tsig_handler_add_key(tsig_key_type *key)
Definition: tsig.c:88
void *(* hmac_create)(allocator_type *allocator)
Definition: tsig.h:98
uint8_t * mac_data
Definition: tsig.h:144
Definition: tsig.h:60
void tsig_rr_cleanup(tsig_rr_type *trr)
Definition: tsig.c:885
int buffer_skip_dname(buffer_type *buffer)
Definition: buffer.c:334
char * allocator_strdup(allocator_type *allocator, const char *string)
Definition: allocator.c:123
size_t size
Definition: tsig.h:83
uint32_t buffer_read_u32(buffer_type *buffer)
Definition: buffer.c:782
tsig_key_type * key
Definition: tsig.h:134
int tsig_rr_verify(tsig_rr_type *trr)
Definition: tsig.c:700
uint32_t signed_time_low
Definition: tsig.h:141
void buffer_write_u16(buffer_type *buffer, uint16_t data)
Definition: buffer.c:607
ldns_rdf * dname
Definition: tsig.h:82
#define TSIG_HMAC_SHA1
Definition: tsig.h:51
void buffer_write_u32(buffer_type *buffer, uint32_t data)
Definition: buffer.c:621
#define TSIG_ERROR_BADSIG
Definition: tsig.h:46
tsig_rr_type * tsig_rr_create(allocator_type *allocator)
Definition: tsig.c:307
void tsig_rr_error(tsig_rr_type *trr)
Definition: tsig.c:793
const char * secret
Definition: tsig.h:117
uint16_t buffer_pkt_nscount(buffer_type *buffer)
Definition: buffer.c:1081
size_t position
Definition: tsig.h:129
void(* hmac_final)(void *context, uint8_t *digest, size_t *size)
Definition: tsig.h:105
tsig_type * tsig_create(allocator_type *allocator, char *name, char *algo, char *secret)
Definition: tsig.c:236
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
Definition: buffer.c:550
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:158
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
Definition: tsig.c:479
int buffer_available(buffer_type *buffer, size_t count)
Definition: buffer.c:524
uint16_t other_size
Definition: tsig.h:147
int tsig_rr_lookup(tsig_rr_type *trr)
Definition: tsig.c:512
#define TSIG_ERROR_BADKEY
Definition: tsig.h:47
void * context
Definition: tsig.h:132
tsig_lookup_table tsig_supported_algorithms[]
Definition: tsig.c:71
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
Definition: buffer.c:635
void tsig_rr_sign(tsig_rr_type *trr)
Definition: tsig.c:678
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:137
void * allocator_alloc_init(allocator_type *allocator, size_t size, const void *init)
Definition: allocator.c:107
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:146
ldns_rdf * algo_name
Definition: tsig.h:139
size_t response_count
Definition: tsig.h:130
tsig_key_type * tsig_key_create(allocator_type *allocator, tsig_type *tsig)
Definition: tsig.c:192
const uint8_t * data
Definition: tsig.h:84
tsig_key_table_type * next
Definition: tsig.c:57
int ods_strlowercmp(const char *str1, const char *str2)
Definition: file.c:334
tsig_key_type * key
Definition: tsig.c:58
const char * name
Definition: tsig.h:115
#define ods_log_assert(x)
Definition: log.h:156
const char * txt_name
Definition: tsig.h:93
enum tsig_status_enum tsig_status
Definition: tsig.h:63
uint16_t original_query_id
Definition: tsig.h:145
tsig_type * tsig_lookup_by_name(tsig_type *tsig, const char *name)
Definition: tsig.c:268
time_t time_now(void)
Definition: duration.c:507
void tsig_handler_add_algo(tsig_algo_type *algo)
Definition: tsig.c:110
size_t tsig_rr_reserved_space(tsig_rr_type *trr)
Definition: tsig.c:764