summaryrefslogtreecommitdiff
path: root/c_src/dnssec.c
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2016-03-27 19:27:30 +0200
committerLinus Nordberg <linus@nordu.net>2016-03-27 19:44:25 +0200
commit56d70baa79ae5907b11445364bbea9b31ee4cd20 (patch)
treeef0403255a04de75736da82385d282a0198c52c2 /c_src/dnssec.c
parent9f723f6f1d79c1be460ece10555945346045b175 (diff)
WIP
Diffstat (limited to 'c_src/dnssec.c')
-rw-r--r--c_src/dnssec.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/c_src/dnssec.c b/c_src/dnssec.c
new file mode 100644
index 0000000..693d645
--- /dev/null
+++ b/c_src/dnssec.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016, NORDUnet A/S.
+ * See LICENSE for licensing information.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <getopt.h>
+#include <getdns/getdns.h>
+#include "erlport.h"
+#include "dnssec_test.h"
+
+static char *testmode = NULL;
+
+/* getdns/src/convert.c */
+getdns_return_t getdns_wire2rr_dict(const uint8_t *wire, size_t wire_len,
+ getdns_dict **rr_dict);
+
+#if !defined(TEST)
+static getdns_return_t
+validate(const unsigned char *records,
+ size_t records_len,
+ getdns_list *trust_anchors)
+{
+ getdns_return_t r = GETDNS_DNSSEC_INDETERMINATE;
+ getdns_list *to_validate = getdns_list_create();
+ getdns_list *support_records = getdns_list_create();
+ getdns_dict *records_dict = NULL;
+
+ if (to_validate == NULL || support_records == NULL)
+ {
+ r = GETDNS_RETURN_MEMORY_ERROR;
+ goto out;
+ }
+
+ /* TODO: figure out if we get _all_ RRs in records here bc i have
+ the feeling that we're not supposed to mix RR types in the same
+ dict; maybe this will help some:
+ https://getdnsapi.net/pipermail/users/2015-May/000032.html
+ */
+ r = getdns_wire2rr_dict(records, records_len, &records_dict);
+ if (r)
+ goto out;
+
+ /*
+ to_validate: one dict with the DS and one with a RRSIG for that DS
+ support_records: DS and DNSKEY dicts with accompanying RRSIG's
+ trust_anchors: DNSKEY (or DS)
+ */
+ r = getdns_list_set_dict(to_validate, i, records_dict);
+ if (r)
+ goto out;
+
+ r = getdns_validate_dnssec(to_validate,
+ support_records,
+ trust_anchors);
+
+out:
+ if (to_validate)
+ getdns_list_destroy(to_validate);
+ if (support_records)
+ getdns_list_destroy(support_records);
+
+ return r;
+}
+#endif /* !TEST */
+
+static void
+loop(getdns_list *trust_anchors)
+{
+ getdns_return_t r = GETDNS_RETURN_GENERIC_ERROR;
+ unsigned char buf[65536];
+ ssize_t len;
+
+ while ((len = read_command(buf, sizeof(buf), 4)) > 0)
+ {
+ unsigned char *reply = NULL;
+
+#if !defined(TEST)
+ r = validate(buf, len, trust_anchors);
+#else
+ r = test_validate(buf, len, trust_anchors, testmode);
+#endif
+
+ switch (r)
+ {
+ case GETDNS_RETURN_GOOD:
+ reply = (unsigned char *) "valid";
+ break;
+ default:
+ fprintf(stderr, "error %d\n", r); /* DEBUG */
+ reply = (unsigned char *) "err";
+ }
+
+ write_reply(reply, strlen((const char *) reply), 4);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ getdns_list *trust_anchors = NULL;
+ time_t trust_anchor_date;
+
+ while (1) {
+ static struct option long_options[] = {
+ {"testmode", required_argument, NULL, 't'},
+ {0, 0, 0, 0}};
+
+ c = getopt_long(argc, argv, "", long_options, NULL);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+#if defined(TEST)
+ case 't':
+ testmode = optarg;
+ break;
+#endif
+ default:
+ fprintf(stderr, "dnssecport: bad option: %s", argv[optind]);
+ return -1;
+ }
+ }
+
+ if (optind < argc) /* Using getdns trust anchor. */
+ {
+ trust_anchors = getdns_root_trust_anchor(&trust_anchor_date);
+ }
+
+ loop(trust_anchors);
+
+ return 0;
+}