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 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 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