| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <errno.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #include "base/at_exit.h" |
| #include "net/base/dns_util.h" |
| #include "net/base/dnssec_chain_verifier.h" |
| |
| static int usage(const char* argv0) { |
| fprintf(stderr, "Usage: %s [--ignore-timestamps] <target domain> " |
| "<input file>\n", argv0); |
| return 1; |
| } |
| |
| int main(int argc, char** argv) { |
| base::AtExitManager at_exit_manager; |
| |
| if (argc < 3) |
| return usage(argv[0]); |
| |
| const char* target = NULL; |
| const char* infilename = NULL; |
| bool ignore_timestamps = false; |
| |
| for (int i = 1; i < argc; i++) { |
| if (strcmp(argv[i], "--ignore-timestamps") == 0) { |
| ignore_timestamps = true; |
| } else if (!target) { |
| target = argv[i]; |
| } else if (!infilename) { |
| infilename = argv[i]; |
| } else { |
| return usage(argv[0]); |
| } |
| } |
| |
| if (!target || !infilename) |
| return usage(argv[0]); |
| |
| FILE* infile = fopen(infilename, "r"); |
| if (!infile) { |
| perror("open"); |
| return usage(argv[0]); |
| } |
| |
| fseek(infile, 0, SEEK_END); |
| unsigned long inlen = ftell(infile); |
| fseek(infile, 0, SEEK_SET); |
| |
| char* const input = (char *) malloc(inlen); |
| if (fread(input, inlen, 1, infile) != 1) { |
| perror("read"); |
| return 1; |
| } |
| |
| std::string target_dns; |
| if (!net::DNSDomainFromDot(target, &target_dns)) { |
| fprintf(stderr, "Not a valid DNS name: %s\n", target); |
| return usage(argv[0]); |
| } |
| |
| net::DNSSECChainVerifier verifier(target_dns, |
| base::StringPiece(input, inlen)); |
| if (ignore_timestamps) |
| verifier.IgnoreTimestamps(); |
| net::DNSSECChainVerifier::Error err = verifier.Verify(); |
| const char* err_str; |
| switch (err) { |
| case net::DNSSECChainVerifier::BAD_DATA: |
| err_str = "Bad data"; |
| break; |
| case net::DNSSECChainVerifier::UNKNOWN_ROOT_KEY: |
| err_str = "Unknown root key"; |
| break; |
| case net::DNSSECChainVerifier::UNKNOWN_DIGEST: |
| err_str = "Unknown digest"; |
| break; |
| case net::DNSSECChainVerifier::UNKNOWN_TERMINAL_RRTYPE: |
| err_str = "Unknown terminal RR type"; |
| break; |
| case net::DNSSECChainVerifier::BAD_SIGNATURE: |
| err_str = "Bad signature"; |
| break; |
| case net::DNSSECChainVerifier::NO_DS_LINK: |
| err_str = "No DS link"; |
| break; |
| case net::DNSSECChainVerifier::OFF_COURSE: |
| err_str = "Off course"; |
| break; |
| case net::DNSSECChainVerifier::BAD_TARGET: |
| err_str = "Bad target"; |
| break; |
| default: |
| err_str = "Unknown"; |
| break; |
| } |
| |
| if (err != net::DNSSECChainVerifier::OK) { |
| fprintf(stderr, "Chain error: %s (%d)\n", err_str, (int) err); |
| return 1; |
| } |
| |
| fprintf(stderr, "Chain good: rrtype:%d\n", verifier.rrtype()); |
| return 0; |
| } |