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 "net/tools/cert_verify_tool/verify_using_path_builder.h" | 5 #include "net/tools/cert_verify_tool/verify_using_path_builder.h" |
6 | 6 |
7 #include <iostream> | 7 #include <iostream> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 | 67 |
68 // Dumps a chain of ParsedCertificate objects to a PEM file. | 68 // Dumps a chain of ParsedCertificate objects to a PEM file. |
69 bool DumpParsedCertificateChain(const base::FilePath& file_path, | 69 bool DumpParsedCertificateChain(const base::FilePath& file_path, |
70 const net::CertPath& chain) { | 70 const net::CertPath& chain) { |
71 std::vector<std::string> pem_encoded_chain; | 71 std::vector<std::string> pem_encoded_chain; |
72 for (const auto& cert : chain.certs) { | 72 for (const auto& cert : chain.certs) { |
73 if (!AddPemEncodedCert(cert.get(), &pem_encoded_chain)) | 73 if (!AddPemEncodedCert(cert.get(), &pem_encoded_chain)) |
74 return false; | 74 return false; |
75 } | 75 } |
76 | 76 |
77 if (chain.trust_anchor && chain.trust_anchor->cert()) { | |
78 if (!AddPemEncodedCert(chain.trust_anchor->cert().get(), | |
79 &pem_encoded_chain)) | |
80 return false; | |
81 } | |
82 | |
83 return WriteToFile(file_path, base::JoinString(pem_encoded_chain, "")); | 77 return WriteToFile(file_path, base::JoinString(pem_encoded_chain, "")); |
84 } | 78 } |
85 | 79 |
86 // Returns a hex-encoded sha256 of the DER-encoding of |cert|. | 80 // Returns a hex-encoded sha256 of the DER-encoding of |cert|. |
87 std::string FingerPrintParsedCertificate(const net::ParsedCertificate* cert) { | 81 std::string FingerPrintParsedCertificate(const net::ParsedCertificate* cert) { |
88 std::string hash = crypto::SHA256HashString(cert->der_cert().AsStringPiece()); | 82 std::string hash = crypto::SHA256HashString(cert->der_cert().AsStringPiece()); |
89 return base::HexEncode(hash.data(), hash.size()); | 83 return base::HexEncode(hash.data(), hash.size()); |
90 } | 84 } |
91 | 85 |
92 std::string SubjectToString(const net::RDNSequence& parsed_subject) { | 86 std::string SubjectToString(const net::RDNSequence& parsed_subject) { |
93 std::string subject_str; | 87 std::string subject_str; |
94 if (!net::ConvertToRFC2253(parsed_subject, &subject_str)) | 88 if (!net::ConvertToRFC2253(parsed_subject, &subject_str)) |
95 return std::string(); | 89 return std::string(); |
96 return subject_str; | 90 return subject_str; |
97 } | 91 } |
98 | 92 |
99 // Returns a textual representation of the Subject of |cert|. | 93 // Returns a textual representation of the Subject of |cert|. |
100 std::string SubjectFromParsedCertificate(const net::ParsedCertificate* cert) { | 94 std::string SubjectFromParsedCertificate(const net::ParsedCertificate* cert) { |
101 net::RDNSequence parsed_subject; | 95 net::RDNSequence parsed_subject; |
102 if (!net::ParseName(cert->tbs().subject_tlv, &parsed_subject)) | 96 if (!net::ParseName(cert->tbs().subject_tlv, &parsed_subject)) |
103 return std::string(); | 97 return std::string(); |
104 return SubjectToString(parsed_subject); | 98 return SubjectToString(parsed_subject); |
105 } | 99 } |
106 | 100 |
107 // Returns a textual representation of the Subject of |trust_anchor|. | |
108 std::string SubjectFromTrustAnchor(const net::TrustAnchor* trust_anchor) { | |
109 // If the cert is present, display the original subject from that rather than | |
110 // the normalized subject. | |
111 if (trust_anchor->cert()) | |
112 return SubjectFromParsedCertificate(trust_anchor->cert().get()); | |
113 | |
114 net::RDNSequence parsed_subject; | |
115 if (!net::ParseNameValue(trust_anchor->normalized_subject(), &parsed_subject)) | |
116 return std::string(); | |
117 return SubjectToString(parsed_subject); | |
118 } | |
119 | |
120 // Dumps a ResultPath to std::cout. | 101 // Dumps a ResultPath to std::cout. |
121 void PrintResultPath(const net::CertPathBuilder::ResultPath* result_path, | 102 void PrintResultPath(const net::CertPathBuilder::ResultPath* result_path, |
122 size_t index, | 103 size_t index, |
123 bool is_best) { | 104 bool is_best) { |
124 std::cout << "path " << index << " " | 105 std::cout << "path " << index << " " |
125 << (result_path->IsValid() ? "valid" : "invalid") | 106 << (result_path->IsValid() ? "valid" : "invalid") |
126 << (is_best ? " (best)" : "") << "\n"; | 107 << (is_best ? " (best)" : "") << "\n"; |
127 | 108 |
128 // Print the certificate chain. | 109 // Print the certificate chain. |
129 for (const auto& cert : result_path->path.certs) { | 110 for (const auto& cert : result_path->path.certs) { |
130 std::cout << " " << FingerPrintParsedCertificate(cert.get()) << " " | 111 std::cout << " " << FingerPrintParsedCertificate(cert.get()) << " " |
131 << SubjectFromParsedCertificate(cert.get()) << "\n"; | 112 << SubjectFromParsedCertificate(cert.get()) << "\n"; |
132 } | 113 } |
133 | 114 |
134 // Print the trust anchor (if there was one). | |
135 const auto& trust_anchor = result_path->path.trust_anchor; | |
136 if (trust_anchor) { | |
137 std::string trust_anchor_cert_fingerprint = "<no cert>"; | |
138 if (trust_anchor->cert()) { | |
139 trust_anchor_cert_fingerprint = | |
140 FingerPrintParsedCertificate(trust_anchor->cert().get()); | |
141 } | |
142 std::cout << " " << trust_anchor_cert_fingerprint << " " | |
143 << SubjectFromTrustAnchor(trust_anchor.get()) << "\n"; | |
144 } | |
145 | |
146 // Print the errors/warnings if there were any. | 115 // Print the errors/warnings if there were any. |
147 std::string errors_str = | 116 std::string errors_str = |
148 result_path->errors.ToDebugString(result_path->path.certs); | 117 result_path->errors.ToDebugString(result_path->path.certs); |
149 if (!errors_str.empty()) { | 118 if (!errors_str.empty()) { |
150 std::cout << "Errors:\n"; | 119 std::cout << "Errors:\n"; |
151 std::cout << errors_str << "\n"; | 120 std::cout << errors_str << "\n"; |
152 } | 121 } |
153 } | 122 } |
154 | 123 |
155 scoped_refptr<net::ParsedCertificate> ParseCertificate(const CertInput& input) { | 124 scoped_refptr<net::ParsedCertificate> ParseCertificate(const CertInput& input) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 base::Time::Exploded exploded_time; | 177 base::Time::Exploded exploded_time; |
209 at_time.UTCExplode(&exploded_time); | 178 at_time.UTCExplode(&exploded_time); |
210 net::der::GeneralizedTime time = ConvertExplodedTime(exploded_time); | 179 net::der::GeneralizedTime time = ConvertExplodedTime(exploded_time); |
211 | 180 |
212 std::unique_ptr<net::SystemTrustStore> ssl_trust_store = | 181 std::unique_ptr<net::SystemTrustStore> ssl_trust_store = |
213 net::CreateSslSystemTrustStore(); | 182 net::CreateSslSystemTrustStore(); |
214 | 183 |
215 for (const auto& der_cert : root_der_certs) { | 184 for (const auto& der_cert : root_der_certs) { |
216 scoped_refptr<net::ParsedCertificate> cert = ParseCertificate(der_cert); | 185 scoped_refptr<net::ParsedCertificate> cert = ParseCertificate(der_cert); |
217 if (cert) { | 186 if (cert) { |
218 ssl_trust_store->AddTrustAnchor( | 187 ssl_trust_store->AddTrustAnchor(cert); |
219 net::TrustAnchor::CreateFromCertificateNoConstraints(cert)); | |
220 } | 188 } |
221 } | 189 } |
222 | 190 |
223 if (!ssl_trust_store->UsesSystemTrustStore() && root_der_certs.empty()) { | 191 if (!ssl_trust_store->UsesSystemTrustStore() && root_der_certs.empty()) { |
224 std::cerr << "NOTE: CertPathBuilder does not currently use OS trust " | 192 std::cerr << "NOTE: CertPathBuilder does not currently use OS trust " |
225 "settings (--roots must be specified).\n"; | 193 "settings (--roots must be specified).\n"; |
226 } | 194 } |
227 net::CertIssuerSourceStatic intermediate_cert_issuer_source; | 195 net::CertIssuerSourceStatic intermediate_cert_issuer_source; |
228 for (const auto& der_cert : intermediate_der_certs) { | 196 for (const auto& der_cert : intermediate_der_certs) { |
229 scoped_refptr<net::ParsedCertificate> cert = ParseCertificate(der_cert); | 197 scoped_refptr<net::ParsedCertificate> cert = ParseCertificate(der_cert); |
230 if (cert) | 198 if (cert) |
231 intermediate_cert_issuer_source.AddCert(cert); | 199 intermediate_cert_issuer_source.AddCert(cert); |
232 } | 200 } |
233 | 201 |
234 scoped_refptr<net::ParsedCertificate> target_cert = | 202 scoped_refptr<net::ParsedCertificate> target_cert = |
235 ParseCertificate(target_der_cert); | 203 ParseCertificate(target_der_cert); |
236 if (!target_cert) | 204 if (!target_cert) |
237 return false; | 205 return false; |
238 | 206 |
239 // Verify the chain. | 207 // Verify the chain. |
240 net::SimpleSignaturePolicy signature_policy(2048); | 208 net::SimpleSignaturePolicy signature_policy(2048); |
241 net::CertPathBuilder::Result result; | 209 net::CertPathBuilder::Result result; |
242 net::CertPathBuilder path_builder( | 210 net::CertPathBuilder path_builder( |
243 target_cert, ssl_trust_store->GetTrustStore(), &signature_policy, time, | 211 target_cert, ssl_trust_store->GetTrustStore(), &signature_policy, time, |
244 net::KeyPurpose::SERVER_AUTH, &result); | 212 net::KeyPurpose::SERVER_AUTH, &result); |
245 path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); | 213 path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); |
246 | 214 |
247 if (ssl_trust_store->GetCertIssuerSource()) | |
248 path_builder.AddCertIssuerSource(ssl_trust_store->GetCertIssuerSource()); | |
249 | |
250 // Create a network thread to be used for AIA fetches, and wait for a | 215 // Create a network thread to be used for AIA fetches, and wait for a |
251 // CertNetFetcher to be constructed on that thread. | 216 // CertNetFetcher to be constructed on that thread. |
252 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); | 217 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); |
253 base::Thread thread("network_thread"); | 218 base::Thread thread("network_thread"); |
254 CHECK(thread.StartWithOptions(options)); | 219 CHECK(thread.StartWithOptions(options)); |
255 // Owned by this thread, but initialized, used, and shutdown on the network | 220 // Owned by this thread, but initialized, used, and shutdown on the network |
256 // thread. | 221 // thread. |
257 std::unique_ptr<net::URLRequestContext> context; | 222 std::unique_ptr<net::URLRequestContext> context; |
258 scoped_refptr<net::CertNetFetcher> cert_net_fetcher; | 223 scoped_refptr<net::CertNetFetcher> cert_net_fetcher; |
259 base::WaitableEvent initialization_complete_event( | 224 base::WaitableEvent initialization_complete_event( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 if (!DumpParsedCertificateChain( | 259 if (!DumpParsedCertificateChain( |
295 dump_prefix_path.AddExtension( | 260 dump_prefix_path.AddExtension( |
296 FILE_PATH_LITERAL(".CertPathBuilder.pem")), | 261 FILE_PATH_LITERAL(".CertPathBuilder.pem")), |
297 result.paths[result.best_result_index]->path)) { | 262 result.paths[result.best_result_index]->path)) { |
298 return false; | 263 return false; |
299 } | 264 } |
300 } | 265 } |
301 | 266 |
302 return result.HasValidPath(); | 267 return result.HasValidPath(); |
303 } | 268 } |
OLD | NEW |