1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 #include "base/at_exit.h"
10 #include "net/base/dns_util.h"
11 #include "net/base/dnssec_chain_verifier.h"
12
usage(const char * argv0)13 static int usage(const char* argv0) {
14 fprintf(stderr, "Usage: %s [--ignore-timestamps] <target domain> "
15 "<input file>\n", argv0);
16 return 1;
17 }
18
main(int argc,char ** argv)19 int main(int argc, char** argv) {
20 base::AtExitManager at_exit_manager;
21
22 if (argc < 3)
23 return usage(argv[0]);
24
25 const char* target = NULL;
26 const char* infilename = NULL;
27 bool ignore_timestamps = false;
28
29 for (int i = 1; i < argc; i++) {
30 if (strcmp(argv[i], "--ignore-timestamps") == 0) {
31 ignore_timestamps = true;
32 } else if (!target) {
33 target = argv[i];
34 } else if (!infilename) {
35 infilename = argv[i];
36 } else {
37 return usage(argv[0]);
38 }
39 }
40
41 if (!target || !infilename)
42 return usage(argv[0]);
43
44 FILE* infile = fopen(infilename, "r");
45 if (!infile) {
46 perror("open");
47 return usage(argv[0]);
48 }
49
50 fseek(infile, 0, SEEK_END);
51 unsigned long inlen = ftell(infile);
52 fseek(infile, 0, SEEK_SET);
53
54 char* const input = (char *) malloc(inlen);
55 if (fread(input, inlen, 1, infile) != 1) {
56 perror("read");
57 return 1;
58 }
59
60 std::string target_dns;
61 if (!net::DNSDomainFromDot(target, &target_dns)) {
62 fprintf(stderr, "Not a valid DNS name: %s\n", target);
63 return usage(argv[0]);
64 }
65
66 net::DNSSECChainVerifier verifier(target_dns,
67 base::StringPiece(input, inlen));
68 if (ignore_timestamps)
69 verifier.IgnoreTimestamps();
70 net::DNSSECChainVerifier::Error err = verifier.Verify();
71 const char* err_str;
72 switch (err) {
73 case net::DNSSECChainVerifier::BAD_DATA:
74 err_str = "Bad data";
75 break;
76 case net::DNSSECChainVerifier::UNKNOWN_ROOT_KEY:
77 err_str = "Unknown root key";
78 break;
79 case net::DNSSECChainVerifier::UNKNOWN_DIGEST:
80 err_str = "Unknown digest";
81 break;
82 case net::DNSSECChainVerifier::UNKNOWN_TERMINAL_RRTYPE:
83 err_str = "Unknown terminal RR type";
84 break;
85 case net::DNSSECChainVerifier::BAD_SIGNATURE:
86 err_str = "Bad signature";
87 break;
88 case net::DNSSECChainVerifier::NO_DS_LINK:
89 err_str = "No DS link";
90 break;
91 case net::DNSSECChainVerifier::OFF_COURSE:
92 err_str = "Off course";
93 break;
94 case net::DNSSECChainVerifier::BAD_TARGET:
95 err_str = "Bad target";
96 break;
97 default:
98 err_str = "Unknown";
99 break;
100 }
101
102 if (err != net::DNSSECChainVerifier::OK) {
103 fprintf(stderr, "Chain error: %s (%d)\n", err_str, (int) err);
104 return 1;
105 }
106
107 fprintf(stderr, "Chain good: rrtype:%d\n", verifier.rrtype());
108 return 0;
109 }
110