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