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

Side by Side Diff: content/browser/cert_store_impl.cc

Issue 71633002: Convert SignedCertificateClass to be ref_counted, and add an SCTStore in which to store them. Add S… Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: few lint fixes Created 7 years, 1 month 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
« no previous file with comments | « content/browser/cert_store_impl.h ('k') | content/browser/loader/resource_loader.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/cert_store_impl.h" 5 #include "content/browser/cert_store_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h" 12 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h" 13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/notification_service.h" 15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/notification_types.h" 16 #include "content/public/browser/notification_types.h"
17 17
18 template <typename T>
19 struct MatchSecond {
20 explicit MatchSecond(const T& t) : value(t) {}
21
22 template<typename Pair>
23 bool operator()(const Pair& p) const {
24 return (value == p.second);
25 }
26 T value;
27 };
28
29 namespace content { 18 namespace content {
30 19
31 // static 20 // static
32 CertStore* CertStore::GetInstance() { 21 CertStore* CertStore::GetInstance() { return CertStoreImpl::GetInstance(); }
33 return CertStoreImpl::GetInstance();
34 }
35 22
36 // static 23 // static
37 CertStoreImpl* CertStoreImpl::GetInstance() { 24 CertStoreImpl* CertStoreImpl::GetInstance() {
38 return Singleton<CertStoreImpl>::get(); 25 return Singleton<CertStoreImpl>::get();
39 } 26 }
40 27
41 CertStoreImpl::CertStoreImpl() : next_cert_id_(1) { 28 CertStoreImpl::CertStoreImpl() : store_() {}
42 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
43 RegisterForNotification();
44 } else {
45 BrowserThread::PostTask(
46 BrowserThread::UI, FROM_HERE,
47 base::Bind(&CertStoreImpl::RegisterForNotification,
48 base::Unretained(this)));
49 }
50 }
51 29
52 CertStoreImpl::~CertStoreImpl() { 30 CertStoreImpl::~CertStoreImpl() {}
53 }
54
55 void CertStoreImpl::RegisterForNotification() {
56 // We watch for RenderProcess termination, as this is how we clear
57 // certificates for now.
58 // TODO(jcampan): we should be listening to events such as resource cached/
59 // removed from cache, and remove the cert when we know it
60 // is not used anymore.
61
62 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
63 NotificationService::AllBrowserContextsAndSources());
64 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED,
65 NotificationService::AllBrowserContextsAndSources());
66 }
67 31
68 int CertStoreImpl::StoreCert(net::X509Certificate* cert, int process_id) { 32 int CertStoreImpl::StoreCert(net::X509Certificate* cert, int process_id) {
69 DCHECK(cert); 33 return store_.Store(cert, process_id);
70 base::AutoLock auto_lock(cert_lock_);
71
72 int cert_id;
73
74 // Do we already know this cert?
75 ReverseCertMap::iterator cert_iter = cert_to_id_.find(cert);
76 if (cert_iter == cert_to_id_.end()) {
77 cert_id = next_cert_id_++;
78 // We use 0 as an invalid cert_id value. In the unlikely event that
79 // next_cert_id_ wraps around, we reset it to 1.
80 if (next_cert_id_ == 0)
81 next_cert_id_ = 1;
82 cert->AddRef();
83 id_to_cert_[cert_id] = cert;
84 cert_to_id_[cert] = cert_id;
85 } else {
86 cert_id = cert_iter->second;
87 }
88
89 // Let's update process_id_to_cert_id_.
90 std::pair<IDMap::iterator, IDMap::iterator> process_ids =
91 process_id_to_cert_id_.equal_range(process_id);
92 if (std::find_if(process_ids.first, process_ids.second,
93 MatchSecond<int>(cert_id)) == process_ids.second) {
94 process_id_to_cert_id_.insert(std::make_pair(process_id, cert_id));
95 }
96
97 // And cert_id_to_process_id_.
98 std::pair<IDMap::iterator, IDMap::iterator> cert_ids =
99 cert_id_to_process_id_.equal_range(cert_id);
100 if (std::find_if(cert_ids.first, cert_ids.second,
101 MatchSecond<int>(process_id)) == cert_ids.second) {
102 cert_id_to_process_id_.insert(std::make_pair(cert_id, process_id));
103 }
104
105 return cert_id;
106 } 34 }
107 35
108 bool CertStoreImpl::RetrieveCert(int cert_id, 36 bool CertStoreImpl::RetrieveCert(int cert_id,
109 scoped_refptr<net::X509Certificate>* cert) { 37 scoped_refptr<net::X509Certificate>* cert) {
110 base::AutoLock auto_lock(cert_lock_); 38 return store_.Retrieve(cert_id, cert);
111
112 CertMap::iterator iter = id_to_cert_.find(cert_id);
113 if (iter == id_to_cert_.end())
114 return false;
115 if (cert)
116 *cert = iter->second;
117 return true;
118 }
119
120 void CertStoreImpl::RemoveCertInternal(int cert_id) {
121 CertMap::iterator cert_iter = id_to_cert_.find(cert_id);
122 DCHECK(cert_iter != id_to_cert_.end());
123
124 ReverseCertMap::iterator id_iter = cert_to_id_.find(cert_iter->second.get());
125 DCHECK(id_iter != cert_to_id_.end());
126 cert_to_id_.erase(id_iter);
127
128 cert_iter->second->Release();
129 id_to_cert_.erase(cert_iter);
130 }
131
132 void CertStoreImpl::RemoveCertsForRenderProcesHost(int process_id) {
133 base::AutoLock auto_lock(cert_lock_);
134
135 // We iterate through all the cert ids for that process.
136 std::pair<IDMap::iterator, IDMap::iterator> process_ids =
137 process_id_to_cert_id_.equal_range(process_id);
138 for (IDMap::iterator ids_iter = process_ids.first;
139 ids_iter != process_ids.second; ++ids_iter) {
140 int cert_id = ids_iter->second;
141 // Find all the processes referring to this cert id in
142 // cert_id_to_process_id_, then locate the process being removed within
143 // that range.
144 std::pair<IDMap::iterator, IDMap::iterator> cert_ids =
145 cert_id_to_process_id_.equal_range(cert_id);
146 IDMap::iterator proc_iter =
147 std::find_if(cert_ids.first, cert_ids.second,
148 MatchSecond<int>(process_id));
149 DCHECK(proc_iter != cert_ids.second);
150
151 // Before removing, determine if no other processes refer to the current
152 // cert id. If |proc_iter| (the current process) is the lower bound of
153 // processes containing the current cert id and if |next_proc_iter| is the
154 // upper bound (the first process that does not), then only one process,
155 // the one being removed, refers to the cert id.
156 IDMap::iterator next_proc_iter = proc_iter;
157 ++next_proc_iter;
158 bool last_process_for_cert_id =
159 (proc_iter == cert_ids.first && next_proc_iter == cert_ids.second);
160 cert_id_to_process_id_.erase(proc_iter);
161
162 if (last_process_for_cert_id) {
163 // The current cert id is not referenced by any other processes, so
164 // remove it from id_to_cert_ and cert_to_id_.
165 RemoveCertInternal(cert_id);
166 }
167 }
168 if (process_ids.first != process_ids.second)
169 process_id_to_cert_id_.erase(process_ids.first, process_ids.second);
170 }
171
172 void CertStoreImpl::Observe(int type,
173 const NotificationSource& source,
174 const NotificationDetails& details) {
175 DCHECK(type == NOTIFICATION_RENDERER_PROCESS_TERMINATED ||
176 type == NOTIFICATION_RENDERER_PROCESS_CLOSED);
177 RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
178 DCHECK(rph);
179 RemoveCertsForRenderProcesHost(rph->GetID());
180 } 39 }
181 40
182 } // namespace content 41 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/cert_store_impl.h ('k') | content/browser/loader/resource_loader.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698