Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2017 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 "chrome/browser/ssl/ignore_errors_cert_verifier.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/base64.h" | |
| 10 #include "base/memory/ref_counted.h" | |
| 11 #include "base/strings/string_piece.h" | |
| 12 #include "crypto/sha2.h" | |
| 13 #include "net/base/completion_callback.h" | |
| 14 #include "net/base/hash_value.h" | |
| 15 #include "net/base/net_errors.h" | |
| 16 #include "net/base/net_export.h" | |
| 17 #include "net/cert/asn1_util.h" | |
| 18 #include "net/cert/cert_verify_result.h" | |
| 19 #include "net/cert/x509_certificate.h" | |
| 20 | |
| 21 using ::net::CertVerifier; | |
| 22 using ::net::CompletionCallback; | |
| 23 using ::net::HashValue; | |
| 24 using ::net::SHA256HashValue; | |
| 25 using ::net::SHA256HashValueLessThan; | |
| 26 using ::net::X509Certificate; | |
| 27 | |
| 28 // static | |
| 29 IgnoreErrorsCertVerifier::SPKIHashSet IgnoreErrorsCertVerifier::MakeWhitelist( | |
| 30 const std::vector<std::string>& fingerprints) { | |
| 31 IgnoreErrorsCertVerifier::SPKIHashSet whitelist; | |
| 32 for (const std::string& fingerprint : fingerprints) { | |
| 33 HashValue hash; | |
| 34 if (!hash.FromString("sha256/" + fingerprint)) { | |
| 35 LOG(ERROR) << "Invalid SPKI: " << fingerprint; | |
| 36 continue; | |
| 37 } | |
| 38 SHA256HashValue sha256; | |
| 39 DCHECK_EQ(hash.size(), sizeof(sha256)); | |
| 40 memcpy(&sha256, hash.data(), sizeof(sha256)); | |
| 41 whitelist.insert(sha256); | |
| 42 } | |
| 43 return whitelist; | |
| 44 } | |
| 45 | |
| 46 IgnoreErrorsCertVerifier::IgnoreErrorsCertVerifier( | |
| 47 std::unique_ptr<CertVerifier> verifier, | |
| 48 IgnoreErrorsCertVerifier::SPKIHashSet whitelist) | |
| 49 : verifier_(std::move(verifier)), whitelist_(std::move(whitelist)) {} | |
| 50 | |
| 51 IgnoreErrorsCertVerifier::~IgnoreErrorsCertVerifier() {} | |
| 52 | |
| 53 int IgnoreErrorsCertVerifier::Verify(const RequestParams& params, | |
| 54 net::CRLSet* crl_set, | |
| 55 net::CertVerifyResult* verify_result, | |
| 56 const net::CompletionCallback& callback, | |
| 57 std::unique_ptr<Request>* out_req, | |
| 58 const net::NetLogWithSource& net_log) { | |
| 59 SPKIHashSet spki_fingerprints; | |
| 60 std::string cert_der; | |
| 61 base::StringPiece cert_spki; | |
| 62 SHA256HashValue hash; | |
| 63 if (X509Certificate::GetDEREncoded(params.certificate()->os_cert_handle(), | |
| 64 &cert_der) && | |
| 65 net::asn1::ExtractSPKIFromDERCert(cert_der, &cert_spki)) { | |
| 66 crypto::SHA256HashString(cert_spki, &hash, sizeof(SHA256HashValue)); | |
| 67 spki_fingerprints.insert(hash); | |
| 68 } | |
| 69 for (const X509Certificate::OSCertHandle& intermediate : | |
| 70 params.certificate()->GetIntermediateCertificates()) { | |
| 71 if (X509Certificate::GetDEREncoded(intermediate, &cert_der) && | |
| 72 net::asn1::ExtractSPKIFromDERCert(cert_der, &cert_spki)) { | |
| 73 crypto::SHA256HashString(cert_spki, &hash, sizeof(SHA256HashValue)); | |
| 74 spki_fingerprints.insert(hash); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 // Intersect SPKI hashes from the chain with the whitelist. | |
| 79 auto whitelist_begin = whitelist_.begin(); | |
| 80 auto whitelist_end = whitelist_.end(); | |
| 81 auto fingerprints_begin = spki_fingerprints.begin(); | |
| 82 auto fingerprints_end = spki_fingerprints.end(); | |
| 83 static const SHA256HashValueLessThan sha256_lt; | |
| 84 bool ignore_errors = false; | |
| 85 while (whitelist_begin != whitelist_end && | |
| 86 fingerprints_begin != fingerprints_end) { | |
| 87 if (sha256_lt(*whitelist_begin, *fingerprints_begin)) { | |
| 88 ++whitelist_begin; | |
| 89 } else if (sha256_lt(*fingerprints_begin, *whitelist_begin)) { | |
| 90 ++fingerprints_begin; | |
| 91 } else { | |
| 92 ignore_errors = true; | |
| 93 break; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 if (ignore_errors) { | |
| 98 verify_result->Reset(); | |
| 99 verify_result->verified_cert = params.certificate(); | |
| 100 std::transform(spki_fingerprints.begin(), spki_fingerprints.end(), | |
| 101 std::back_inserter(verify_result->public_key_hashes), | |
| 102 [](const SHA256HashValue v) { return HashValue(v); }); | |
|
Ryan Sleevi
2017/04/25 18:07:09
this should be "const SHA256HashValue& v", right?
martinkr
2017/04/25 19:48:37
Done.
| |
| 103 return net::OK; | |
| 104 } | |
| 105 | |
| 106 return verifier_->Verify(params, crl_set, verify_result, callback, out_req, | |
| 107 net_log); | |
| 108 } | |
| OLD | NEW |