Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iostream> | 5 #include <iostream> |
| 6 | 6 |
| 7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
| 12 #include "net/tools/cert_verify_tool/cert_verify_tool_util.h" | 12 #include "net/tools/cert_verify_tool/cert_verify_tool_util.h" |
| 13 #include "net/tools/cert_verify_tool/verify_using_cert_verify_proc.h" | 13 #include "net/tools/cert_verify_tool/verify_using_cert_verify_proc.h" |
| 14 #include "net/tools/cert_verify_tool/verify_using_path_builder.h" | |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 | 17 |
| 17 void PrintUsage(const char* argv0) { | 18 void PrintUsage(const char* argv0) { |
| 18 std::cerr << "Usage: " << argv0 << " [flags] <target/chain>\n"; | 19 std::cerr << "Usage: " << argv0 << " [flags] <target/chain>\n"; |
| 19 std::cerr << " <target/chain> should be a file containing a single DER cert " | 20 std::cerr << " <target/chain> should be a file containing a single DER cert " |
| 20 "or a PEM certificate chain (target first).\n"; | 21 "or a PEM certificate chain (target first).\n"; |
| 21 std::cerr << "Flags:\n"; | 22 std::cerr << "Flags:\n"; |
| 22 std::cerr << " --hostname=<hostname>\n"; | 23 std::cerr << " --hostname=<hostname>\n"; |
| 23 std::cerr << " --roots=<certs path>\n"; | 24 std::cerr << " --roots=<certs path>\n"; |
| 24 std::cerr << " --intermediates=<certs path>\n"; | 25 std::cerr << " --intermediates=<certs path>\n"; |
| 25 std::cerr << " <certs path> should be a file containing a single DER cert or " | 26 std::cerr << " <certs path> should be a file containing a single DER cert or " |
| 26 "one or more PEM CERTIFICATE blocks.\n"; | 27 "one or more PEM CERTIFICATE blocks.\n"; |
| 28 std::cerr << " --time=<localtime>\n"; | |
| 29 std::cerr << " Use <localtime> instead of the current system time.\n"; | |
|
eroman
2016/07/07 00:07:19
can you add an explanation of what the format is?
mattm
2016/07/07 00:49:55
Done.
| |
| 30 std::cerr << " --utctime=<utctime>\n"; | |
| 31 std::cerr << " Use <utctime> instead of the current system time.\n"; | |
|
eroman
2016/07/07 00:07:19
I would say that --time is sufficient, since it ca
mattm
2016/07/07 00:49:55
I switched to just having one flag since it simpli
| |
| 27 std::cerr << " --dump=<file prefix>\n"; | 32 std::cerr << " --dump=<file prefix>\n"; |
| 28 std::cerr << " Dumps the verified chain to PEM files starting with <file " | 33 std::cerr << " Dumps the verified chain to PEM files starting with <file " |
| 29 "prefix>.\n"; | 34 "prefix>.\n"; |
| 30 // TODO(mattm): allow <certs path> to be a directory containing DER/PEM files? | 35 // TODO(mattm): allow <certs path> to be a directory containing DER/PEM files? |
| 31 // TODO(mattm): allow target to specify an HTTPS URL to check the cert of? | 36 // TODO(mattm): allow target to specify an HTTPS URL to check the cert of? |
| 32 // TODO(mattm): allow target to be a verify_certificate_chain_unittest PEM | 37 // TODO(mattm): allow target to be a verify_certificate_chain_unittest PEM |
| 33 // file? | 38 // file? |
| 34 } | 39 } |
| 35 | 40 |
| 36 } // namespace | 41 } // namespace |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 52 PrintUsage(argv[0]); | 57 PrintUsage(argv[0]); |
| 53 return 1; | 58 return 1; |
| 54 } | 59 } |
| 55 | 60 |
| 56 std::string hostname = command_line.GetSwitchValueASCII("hostname"); | 61 std::string hostname = command_line.GetSwitchValueASCII("hostname"); |
| 57 if (hostname.empty()) { | 62 if (hostname.empty()) { |
| 58 std::cerr << "ERROR: --hostname is required\n"; | 63 std::cerr << "ERROR: --hostname is required\n"; |
| 59 return 1; | 64 return 1; |
| 60 } | 65 } |
| 61 | 66 |
| 67 base::Time verify_time; | |
| 68 std::string time_flag = command_line.GetSwitchValueASCII("time"); | |
| 69 std::string utctime_flag = command_line.GetSwitchValueASCII("utctime"); | |
| 70 if (!time_flag.empty() && !utctime_flag.empty()) { | |
| 71 std::cerr << "ERROR: Only one of --time and --utctime may be specified.\n"; | |
| 72 return 1; | |
| 73 } | |
| 74 if (!time_flag.empty()) { | |
| 75 if (!base::Time::FromString(time_flag.c_str(), &verify_time)) { | |
| 76 std::cerr << "Error parsing --time flag\n"; | |
| 77 return 1; | |
| 78 } | |
| 79 } else if (!utctime_flag.empty()) { | |
| 80 if (!base::Time::FromUTCString(utctime_flag.c_str(), &verify_time)) { | |
| 81 std::cerr << "Error parsing --utctime flag\n"; | |
| 82 return 1; | |
| 83 } | |
| 84 } else { | |
| 85 verify_time = base::Time::Now(); | |
| 86 } | |
| 87 | |
| 62 base::FilePath roots_path = command_line.GetSwitchValuePath("roots"); | 88 base::FilePath roots_path = command_line.GetSwitchValuePath("roots"); |
| 63 base::FilePath intermediates_path = | 89 base::FilePath intermediates_path = |
| 64 command_line.GetSwitchValuePath("intermediates"); | 90 command_line.GetSwitchValuePath("intermediates"); |
| 65 base::FilePath target_path = base::FilePath(args[0]); | 91 base::FilePath target_path = base::FilePath(args[0]); |
| 66 | 92 |
| 67 base::FilePath dump_prefix_path = command_line.GetSwitchValuePath("dump"); | 93 base::FilePath dump_prefix_path = command_line.GetSwitchValuePath("dump"); |
| 68 | 94 |
| 69 std::vector<CertInput> root_der_certs; | 95 std::vector<CertInput> root_der_certs; |
| 70 std::vector<CertInput> intermediate_der_certs; | 96 std::vector<CertInput> intermediate_der_certs; |
| 71 CertInput target_der_cert; | 97 CertInput target_der_cert; |
| 72 | 98 |
| 73 if (!roots_path.empty()) | 99 if (!roots_path.empty()) |
| 74 ReadCertificatesFromFile(roots_path, &root_der_certs); | 100 ReadCertificatesFromFile(roots_path, &root_der_certs); |
| 75 if (!intermediates_path.empty()) | 101 if (!intermediates_path.empty()) |
| 76 ReadCertificatesFromFile(intermediates_path, &intermediate_der_certs); | 102 ReadCertificatesFromFile(intermediates_path, &intermediate_der_certs); |
| 77 ReadChainFromFile(target_path, &target_der_cert, &intermediate_der_certs); | 103 ReadChainFromFile(target_path, &target_der_cert, &intermediate_der_certs); |
| 78 | 104 |
| 79 if (target_der_cert.der_cert.empty()) { | 105 if (target_der_cert.der_cert.empty()) { |
| 80 std::cerr << "ERROR: no target cert\n"; | 106 std::cerr << "ERROR: no target cert\n"; |
| 81 return 1; | 107 return 1; |
| 82 } | 108 } |
| 83 | 109 |
| 84 std::cout << "CertVerifyProc:\n"; | 110 std::cout << "CertVerifyProc:\n"; |
| 85 bool verify_ok = VerifyUsingCertVerifyProc(target_der_cert, hostname, | 111 bool cert_verify_proc_ok = true; |
| 86 intermediate_der_certs, | 112 if (!time_flag.empty() || !utctime_flag.empty()) { |
|
eroman
2016/07/07 00:07:19
nit: would !verify_time.is_null() be more concise?
mattm
2016/07/07 00:49:55
If the flags aren't present, verify_time is still
eroman
2016/07/07 01:21:44
acknowledged
| |
| 87 root_der_certs, dump_prefix_path); | 113 std::cerr << "ERROR: --time/--utctime is not supported with " |
| 114 "CertVerifyProc, skipping.\n"; | |
| 115 } else { | |
| 116 cert_verify_proc_ok = VerifyUsingCertVerifyProc( | |
| 117 target_der_cert, hostname, intermediate_der_certs, root_der_certs, | |
| 118 dump_prefix_path); | |
| 119 } | |
| 88 | 120 |
| 89 return verify_ok ? 0 : 1; | 121 std::cout << "\nCertPathBuilder:\n"; |
| 122 bool path_builder_ok = | |
| 123 VerifyUsingPathBuilder(target_der_cert, intermediate_der_certs, | |
| 124 root_der_certs, verify_time, dump_prefix_path); | |
| 125 | |
| 126 return (cert_verify_proc_ok && path_builder_ok) ? 0 : 1; | |
| 90 } | 127 } |
| OLD | NEW |