summaryrefslogtreecommitdiff
path: root/tools/dnssec/validatechain.c
blob: 62fca09d0460a41b3c64dbe8d63155096a958286 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>
#include "common.h"

static int debug = 0;

static void
print_tree(const getdns_list *tree, const char *name)
{
  if (name)
    printf("* %s\n", name);

    char *s = getdns_pretty_print_list(tree);
    puts(s);
    free(s);
}

static getdns_return_t
validate(const uint8_t *records_buf, size_t records_len,
         const uint8_t *support_buf, size_t support_len,
         const uint8_t *trust_anchors_buf, size_t trust_anchors_len,
         time_t validation_time, uint32_t skew)
{
  getdns_return_t r = GETDNS_DNSSEC_INDETERMINATE;

  getdns_list *to_validate = NULL;
  if ((r = wire_rrs2list(records_buf, records_len, &to_validate)))
    goto out;

  getdns_list *support_records = NULL;
  if ((r = wire_rrs2list(support_buf, support_len, &support_records)))
    goto out;

  getdns_list *trust_anchors = NULL;
  if ((r = wire_rrs2list(trust_anchors_buf, trust_anchors_len, &trust_anchors)))
    goto out;

  /*
    to_validate: The DS and an RRSIG for that DS.

    support_records: DS's and DNSKEY's with accompanying RRSIG's.

    trust_anchors: DNSKEY's (and possibly DS's?).
   */

  r = getdns_validate_dnssec2(to_validate,
                              support_records,
                              trust_anchors,
                              validation_time,
                              skew);

  if (debug) {
    print_tree(to_validate, "to_validate");
    print_tree(support_records, "support_records");
    print_tree(trust_anchors, "trust_anchors");
  }
out:
  if (to_validate)
    getdns_list_destroy(to_validate);
  if (support_records)
    getdns_list_destroy(support_records);
  if (trust_anchors)
    getdns_list_destroy(trust_anchors);

  return r;
}

static void
usage()
{
  fprintf(stderr, "usage: dns-validatechain to-validate-file "
          "support-records-file [trust-anchors-file]\n");
}

static int
read_file(const char *filename, uint8_t **out, size_t *out_len)
{
  FILE *fp = fopen(filename, "r");

  if (fp == NULL)
    return errno;
  *out_len = read_buffer(fp, out, *out_len);
  if (fclose(fp)) assert(0);

  return 0;
}

int
main(int argc, char *argv[])
{
  if (argc < 4) {
    usage();
    exit(1);
  }

  uint8_t *tv = NULL;
  size_t tv_len = 8 * 1024;
  if (read_file(argv[1], &tv, &tv_len))
    assert(0);

  uint8_t *sup = NULL;
  size_t sup_len = 64 * 1024;
  if (read_file(argv[2], &sup, &sup_len))
    assert(0);

  uint8_t *ta = NULL;
  size_t ta_len = 4 * 1024;
  if (read_file(argv[3], &ta, &ta_len))
    assert(0);

  getdns_return_t r = 0;
  if ((r = validate(tv, tv_len,
                    sup, sup_len,
                    ta, ta_len,
                    time(NULL), 5)) != GETDNS_DNSSEC_SECURE) {
    fprintf(stderr, "validation failed: %d (%s)\n",
            r, getdns_get_errorstr_by_id(r));
    return r;
  }

  printf("OK\n");
  return 0;
}