OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/extensions/api/gcd_private/privet_v3_context_getter.h" | 5 #include "chrome/browser/extensions/api/gcd_private/privet_v3_context_getter.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "chrome/common/chrome_content_client.h" | 8 #include "chrome/common/chrome_content_client.h" |
9 #include "chrome/common/chrome_switches.h" | 9 #include "chrome/common/chrome_switches.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "net/cert/cert_verifier.h" | 11 #include "net/cert/cert_verifier.h" |
12 #include "net/cert/cert_verify_result.h" | 12 #include "net/cert/cert_verify_result.h" |
13 #include "net/cert/x509_certificate.h" | 13 #include "net/cert/x509_certificate.h" |
14 #include "net/url_request/url_request_context.h" | 14 #include "net/url_request/url_request_context.h" |
15 #include "net/url_request/url_request_context_builder.h" | 15 #include "net/url_request/url_request_context_builder.h" |
16 | 16 |
17 namespace extensions { | 17 namespace extensions { |
18 | 18 |
19 // Class verifies certificate by its fingerprint received using different | 19 // Class verifies certificate by its fingerprint received using different |
20 // channel. It's the only know information about device with self-signed | 20 // channel. It's the only know information about device with self-signed |
21 // certificate. | 21 // certificate. |
22 class FingerprintVerifier : public net::CertVerifier { | 22 class PrivetV3ContextGetter::CertVerifier : public net::CertVerifier { |
23 public: | 23 public: |
24 explicit FingerprintVerifier( | 24 CertVerifier() {} |
25 const net::SHA256HashValue& certificate_fingerprint) | |
26 : certificate_fingerprint_(certificate_fingerprint) {} | |
27 | 25 |
28 int Verify(net::X509Certificate* cert, | 26 int Verify(net::X509Certificate* cert, |
29 const std::string& hostname, | 27 const std::string& hostname, |
30 const std::string& ocsp_response, | 28 const std::string& ocsp_response, |
31 int flags, | 29 int flags, |
32 net::CRLSet* crl_set, | 30 net::CRLSet* crl_set, |
33 net::CertVerifyResult* verify_result, | 31 net::CertVerifyResult* verify_result, |
34 const net::CompletionCallback& callback, | 32 const net::CompletionCallback& callback, |
35 scoped_ptr<Request>* out_req, | 33 scoped_ptr<Request>* out_req, |
36 const net::BoundNetLog& net_log) override { | 34 const net::BoundNetLog& net_log) override { |
37 // Mark certificate as invalid as we didn't check it. | 35 // Mark certificate as invalid as we didn't check it. |
38 verify_result->Reset(); | 36 verify_result->Reset(); |
39 verify_result->verified_cert = cert; | 37 verify_result->verified_cert = cert; |
40 verify_result->cert_status = net::CERT_STATUS_INVALID; | 38 verify_result->cert_status = net::CERT_STATUS_INVALID; |
41 | 39 |
| 40 auto it = fingerprints_.find(hostname); |
| 41 if (it == fingerprints_.end()) |
| 42 return net::ERR_CERT_INVALID; |
| 43 |
42 auto fingerprint = | 44 auto fingerprint = |
43 net::X509Certificate::CalculateFingerprint256(cert->os_cert_handle()); | 45 net::X509Certificate::CalculateFingerprint256(cert->os_cert_handle()); |
| 46 return it->second.Equals(fingerprint) ? net::OK : net::ERR_CERT_INVALID; |
| 47 } |
44 | 48 |
45 return certificate_fingerprint_.Equals(fingerprint) ? net::OK | 49 void AddPairedHost(const std::string& host, |
46 : net::ERR_CERT_INVALID; | 50 const net::SHA256HashValue& certificate_fingerprint) { |
| 51 fingerprints_[host] = certificate_fingerprint; |
47 } | 52 } |
48 | 53 |
49 private: | 54 private: |
50 net::SHA256HashValue certificate_fingerprint_; | 55 std::map<std::string, net::SHA256HashValue> fingerprints_; |
51 | 56 |
52 DISALLOW_COPY_AND_ASSIGN(FingerprintVerifier); | 57 DISALLOW_COPY_AND_ASSIGN(CertVerifier); |
53 }; | 58 }; |
54 | 59 |
55 PrivetV3ContextGetter::PrivetV3ContextGetter( | 60 PrivetV3ContextGetter::PrivetV3ContextGetter( |
56 const scoped_refptr<base::SingleThreadTaskRunner>& net_task_runner, | 61 const scoped_refptr<base::SingleThreadTaskRunner>& net_task_runner) |
57 const net::SHA256HashValue& certificate_fingerprint) | 62 : net_task_runner_(net_task_runner), weak_ptr_factory_(this) { |
58 : verifier_(new FingerprintVerifier(certificate_fingerprint)), | |
59 net_task_runner_(net_task_runner) { | |
60 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 63 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
61 switches::kEnablePrivetV3)); | 64 switches::kEnablePrivetV3)); |
62 } | 65 } |
63 | 66 |
64 net::URLRequestContext* PrivetV3ContextGetter::GetURLRequestContext() { | 67 net::URLRequestContext* PrivetV3ContextGetter::GetURLRequestContext() { |
65 DCHECK(net_task_runner_->BelongsToCurrentThread()); | 68 InitOnNetThread(); |
66 if (!context_) { | |
67 net::URLRequestContextBuilder builder; | |
68 builder.set_proxy_service(net::ProxyService::CreateDirect()); | |
69 builder.SetSpdyAndQuicEnabled(false, false); | |
70 builder.DisableHttpCache(); | |
71 builder.SetCertVerifier(verifier_.Pass()); | |
72 builder.set_user_agent(::GetUserAgent()); | |
73 context_ = builder.Build(); | |
74 } | |
75 return context_.get(); | 69 return context_.get(); |
76 } | 70 } |
77 | 71 |
78 scoped_refptr<base::SingleThreadTaskRunner> | 72 scoped_refptr<base::SingleThreadTaskRunner> |
79 PrivetV3ContextGetter::GetNetworkTaskRunner() const { | 73 PrivetV3ContextGetter::GetNetworkTaskRunner() const { |
80 return net_task_runner_; | 74 return net_task_runner_; |
81 } | 75 } |
82 | 76 |
| 77 void PrivetV3ContextGetter::InitOnNetThread() { |
| 78 DCHECK(net_task_runner_->BelongsToCurrentThread()); |
| 79 if (!context_) { |
| 80 net::URLRequestContextBuilder builder; |
| 81 builder.set_proxy_service(net::ProxyService::CreateDirect()); |
| 82 builder.SetSpdyAndQuicEnabled(false, false); |
| 83 builder.DisableHttpCache(); |
| 84 cert_verifier_ = new CertVerifier(); |
| 85 builder.SetCertVerifier(make_scoped_ptr(cert_verifier_)); |
| 86 builder.set_user_agent(::GetUserAgent()); |
| 87 context_ = builder.Build(); |
| 88 } |
| 89 } |
| 90 |
| 91 void PrivetV3ContextGetter::AddPairedHost( |
| 92 const std::string& host, |
| 93 const net::SHA256HashValue& certificate_fingerprint, |
| 94 const base::Closure& callback) { |
| 95 net_task_runner_->PostTaskAndReply( |
| 96 FROM_HERE, |
| 97 base::Bind(&PrivetV3ContextGetter::AddPairedHostOnNetThread, |
| 98 weak_ptr_factory_.GetWeakPtr(), host, certificate_fingerprint), |
| 99 callback); |
| 100 } |
| 101 |
| 102 void PrivetV3ContextGetter::AddPairedHostOnNetThread( |
| 103 const std::string& host, |
| 104 const net::SHA256HashValue& certificate_fingerprint) { |
| 105 InitOnNetThread(); |
| 106 cert_verifier_->AddPairedHost(host, certificate_fingerprint); |
| 107 } |
| 108 |
83 PrivetV3ContextGetter::~PrivetV3ContextGetter() { | 109 PrivetV3ContextGetter::~PrivetV3ContextGetter() { |
84 DCHECK(net_task_runner_->BelongsToCurrentThread()); | 110 DCHECK(net_task_runner_->BelongsToCurrentThread()); |
85 } | 111 } |
86 | 112 |
87 } // namespace extensions | 113 } // namespace extensions |
OLD | NEW |