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