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