Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: net/tools/cert_verify_tool/verify_using_path_builder.cc

Issue 2832703002: Allow the TrustStore interface to return matching intermediates, and identify distrusted certs. (Closed)
Patch Set: address comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698