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

Side by Side Diff: net/base/origin_bound_cert_service.cc

Issue 9617039: Change Origin bound certs -> Domain bound certs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/base/origin_bound_cert_service.h ('k') | net/base/origin_bound_cert_service_unittest.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 "net/base/origin_bound_cert_service.h" 5 #include "net/base/origin_bound_cert_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #include "base/rand_util.h" 18 #include "base/rand_util.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/threading/worker_pool.h" 20 #include "base/threading/worker_pool.h"
21 #include "crypto/ec_private_key.h" 21 #include "crypto/ec_private_key.h"
22 #include "googleurl/src/gurl.h"
22 #include "net/base/net_errors.h" 23 #include "net/base/net_errors.h"
23 #include "net/base/origin_bound_cert_store.h" 24 #include "net/base/origin_bound_cert_store.h"
24 #include "net/base/registry_controlled_domain.h" 25 #include "net/base/registry_controlled_domain.h"
25 #include "net/base/x509_certificate.h" 26 #include "net/base/x509_certificate.h"
26 #include "net/base/x509_util.h" 27 #include "net/base/x509_util.h"
27 28
28 #if defined(USE_NSS) 29 #if defined(USE_NSS)
29 #include <private/pprthred.h> // PR_DetachThread 30 #include <private/pprthred.h> // PR_DetachThread
30 #endif 31 #endif
31 32
32 namespace net { 33 namespace net {
33 34
34 namespace { 35 namespace {
35 36
36 const int kKeySizeInBits = 1024; 37 const int kKeySizeInBits = 1024;
37 const int kValidityPeriodInDays = 365; 38 const int kValidityPeriodInDays = 365;
38 39
39 bool IsSupportedCertType(uint8 type) { 40 bool IsSupportedCertType(uint8 type) {
40 switch(type) { 41 switch(type) {
41 case CLIENT_CERT_ECDSA_SIGN: 42 case CLIENT_CERT_ECDSA_SIGN:
42 return true; 43 return true;
43 default: 44 default:
44 return false; 45 return false;
45 } 46 }
46 } 47 }
47 48
48 } // namespace 49 } // namespace
49 50
50 // Represents the output and result callback of a request. 51 // Represents the output and result callback of a request.
51 class OriginBoundCertServiceRequest { 52 class ServerBoundCertServiceRequest {
52 public: 53 public:
53 OriginBoundCertServiceRequest(const CompletionCallback& callback, 54 ServerBoundCertServiceRequest(const CompletionCallback& callback,
54 SSLClientCertType* type, 55 SSLClientCertType* type,
55 std::string* private_key, 56 std::string* private_key,
56 std::string* cert) 57 std::string* cert)
57 : callback_(callback), 58 : callback_(callback),
58 type_(type), 59 type_(type),
59 private_key_(private_key), 60 private_key_(private_key),
60 cert_(cert) { 61 cert_(cert) {
61 } 62 }
62 63
63 // Ensures that the result callback will never be made. 64 // Ensures that the result callback will never be made.
(...skipping 21 matching lines...) Expand all
85 86
86 bool canceled() const { return callback_.is_null(); } 87 bool canceled() const { return callback_.is_null(); }
87 88
88 private: 89 private:
89 CompletionCallback callback_; 90 CompletionCallback callback_;
90 SSLClientCertType* type_; 91 SSLClientCertType* type_;
91 std::string* private_key_; 92 std::string* private_key_;
92 std::string* cert_; 93 std::string* cert_;
93 }; 94 };
94 95
95 // OriginBoundCertServiceWorker runs on a worker thread and takes care of the 96 // ServerBoundCertServiceWorker runs on a worker thread and takes care of the
96 // blocking process of performing key generation. Deletes itself eventually 97 // blocking process of performing key generation. Deletes itself eventually
97 // if Start() succeeds. 98 // if Start() succeeds.
98 class OriginBoundCertServiceWorker { 99 class ServerBoundCertServiceWorker {
99 public: 100 public:
100 OriginBoundCertServiceWorker( 101 ServerBoundCertServiceWorker(
101 const std::string& origin, 102 const std::string& server_identifier,
102 SSLClientCertType type, 103 SSLClientCertType type,
103 OriginBoundCertService* origin_bound_cert_service) 104 ServerBoundCertService* server_bound_cert_service)
104 : origin_(origin), 105 : server_identifier_(server_identifier),
105 type_(type), 106 type_(type),
106 serial_number_(base::RandInt(0, std::numeric_limits<int>::max())), 107 serial_number_(base::RandInt(0, std::numeric_limits<int>::max())),
107 origin_loop_(MessageLoop::current()), 108 origin_loop_(MessageLoop::current()),
108 origin_bound_cert_service_(origin_bound_cert_service), 109 server_bound_cert_service_(server_bound_cert_service),
109 canceled_(false), 110 canceled_(false),
110 error_(ERR_FAILED) { 111 error_(ERR_FAILED) {
111 } 112 }
112 113
113 bool Start() { 114 bool Start() {
114 DCHECK_EQ(MessageLoop::current(), origin_loop_); 115 DCHECK_EQ(MessageLoop::current(), origin_loop_);
115 116
116 return base::WorkerPool::PostTask( 117 return base::WorkerPool::PostTask(
117 FROM_HERE, 118 FROM_HERE,
118 base::Bind(&OriginBoundCertServiceWorker::Run, base::Unretained(this)), 119 base::Bind(&ServerBoundCertServiceWorker::Run, base::Unretained(this)),
119 true /* task is slow */); 120 true /* task is slow */);
120 } 121 }
121 122
122 // Cancel is called from the origin loop when the OriginBoundCertService is 123 // Cancel is called from the origin loop when the ServerBoundCertService is
123 // getting deleted. 124 // getting deleted.
124 void Cancel() { 125 void Cancel() {
125 DCHECK_EQ(MessageLoop::current(), origin_loop_); 126 DCHECK_EQ(MessageLoop::current(), origin_loop_);
126 base::AutoLock locked(lock_); 127 base::AutoLock locked(lock_);
127 canceled_ = true; 128 canceled_ = true;
128 } 129 }
129 130
130 private: 131 private:
131 void Run() { 132 void Run() {
132 // Runs on a worker thread. 133 // Runs on a worker thread.
133 error_ = OriginBoundCertService::GenerateCert(origin_, 134 error_ = ServerBoundCertService::GenerateCert(server_identifier_,
134 type_, 135 type_,
135 serial_number_, 136 serial_number_,
136 &creation_time_, 137 &creation_time_,
137 &expiration_time_, 138 &expiration_time_,
138 &private_key_, 139 &private_key_,
139 &cert_); 140 &cert_);
140 #if defined(USE_NSS) 141 #if defined(USE_NSS)
141 // Detach the thread from NSPR. 142 // Detach the thread from NSPR.
142 // Calling NSS functions attaches the thread to NSPR, which stores 143 // Calling NSS functions attaches the thread to NSPR, which stores
143 // the NSPR thread ID in thread-specific data. 144 // the NSPR thread ID in thread-specific data.
144 // The threads in our thread pool terminate after we have called 145 // The threads in our thread pool terminate after we have called
145 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets 146 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
146 // segfaults on shutdown when the threads' thread-specific data 147 // segfaults on shutdown when the threads' thread-specific data
147 // destructors run. 148 // destructors run.
148 PR_DetachThread(); 149 PR_DetachThread();
149 #endif 150 #endif
150 Finish(); 151 Finish();
151 } 152 }
152 153
153 // DoReply runs on the origin thread. 154 // DoReply runs on the origin thread.
154 void DoReply() { 155 void DoReply() {
155 DCHECK_EQ(MessageLoop::current(), origin_loop_); 156 DCHECK_EQ(MessageLoop::current(), origin_loop_);
156 { 157 {
157 // We lock here because the worker thread could still be in Finished, 158 // We lock here because the worker thread could still be in Finished,
158 // after the PostTask, but before unlocking |lock_|. If we do not lock in 159 // after the PostTask, but before unlocking |lock_|. If we do not lock in
159 // this case, we will end up deleting a locked Lock, which can lead to 160 // this case, we will end up deleting a locked Lock, which can lead to
160 // memory leaks or worse errors. 161 // memory leaks or worse errors.
161 base::AutoLock locked(lock_); 162 base::AutoLock locked(lock_);
162 if (!canceled_) { 163 if (!canceled_) {
163 origin_bound_cert_service_->HandleResult( 164 server_bound_cert_service_->HandleResult(
164 origin_, error_, type_, creation_time_, expiration_time_, 165 server_identifier_, error_, type_, creation_time_, expiration_time_,
165 private_key_, cert_); 166 private_key_, cert_);
166 } 167 }
167 } 168 }
168 delete this; 169 delete this;
169 } 170 }
170 171
171 void Finish() { 172 void Finish() {
172 // Runs on the worker thread. 173 // Runs on the worker thread.
173 // We assume that the origin loop outlives the OriginBoundCertService. If 174 // We assume that the origin loop outlives the ServerBoundCertService. If
174 // the OriginBoundCertService is deleted, it will call Cancel on us. If it 175 // the ServerBoundCertService is deleted, it will call Cancel on us. If it
175 // does so before the Acquire, we'll delete ourselves and return. If it's 176 // does so before the Acquire, we'll delete ourselves and return. If it's
176 // trying to do so concurrently, then it'll block on the lock and we'll 177 // trying to do so concurrently, then it'll block on the lock and we'll
177 // call PostTask while the OriginBoundCertService (and therefore the 178 // call PostTask while the ServerBoundCertService (and therefore the
178 // MessageLoop) is still alive. If it does so after this function, we 179 // MessageLoop) is still alive. If it does so after this function, we
179 // assume that the MessageLoop will process pending tasks. In which case 180 // assume that the MessageLoop will process pending tasks. In which case
180 // we'll notice the |canceled_| flag in DoReply. 181 // we'll notice the |canceled_| flag in DoReply.
181 182
182 bool canceled; 183 bool canceled;
183 { 184 {
184 base::AutoLock locked(lock_); 185 base::AutoLock locked(lock_);
185 canceled = canceled_; 186 canceled = canceled_;
186 if (!canceled) { 187 if (!canceled) {
187 origin_loop_->PostTask( 188 origin_loop_->PostTask(
188 FROM_HERE, base::Bind(&OriginBoundCertServiceWorker::DoReply, 189 FROM_HERE, base::Bind(&ServerBoundCertServiceWorker::DoReply,
189 base::Unretained(this))); 190 base::Unretained(this)));
190 } 191 }
191 } 192 }
192 if (canceled) 193 if (canceled)
193 delete this; 194 delete this;
194 } 195 }
195 196
196 const std::string origin_; 197 const std::string server_identifier_;
197 const SSLClientCertType type_; 198 const SSLClientCertType type_;
198 // Note that serial_number_ must be initialized on a non-worker thread 199 // Note that serial_number_ must be initialized on a non-worker thread
199 // (see documentation for OriginBoundCertService::GenerateCert). 200 // (see documentation for ServerBoundCertService::GenerateCert).
200 uint32 serial_number_; 201 uint32 serial_number_;
201 MessageLoop* const origin_loop_; 202 MessageLoop* const origin_loop_;
202 OriginBoundCertService* const origin_bound_cert_service_; 203 ServerBoundCertService* const server_bound_cert_service_;
203 204
204 // lock_ protects canceled_. 205 // lock_ protects canceled_.
205 base::Lock lock_; 206 base::Lock lock_;
206 207
207 // If canceled_ is true, 208 // If canceled_ is true,
208 // * origin_loop_ cannot be accessed by the worker thread, 209 // * origin_loop_ cannot be accessed by the worker thread,
209 // * origin_bound_cert_service_ cannot be accessed by any thread. 210 // * server_bound_cert_service_ cannot be accessed by any thread.
210 bool canceled_; 211 bool canceled_;
211 212
212 int error_; 213 int error_;
213 base::Time creation_time_; 214 base::Time creation_time_;
214 base::Time expiration_time_; 215 base::Time expiration_time_;
215 std::string private_key_; 216 std::string private_key_;
216 std::string cert_; 217 std::string cert_;
217 218
218 DISALLOW_COPY_AND_ASSIGN(OriginBoundCertServiceWorker); 219 DISALLOW_COPY_AND_ASSIGN(ServerBoundCertServiceWorker);
219 }; 220 };
220 221
221 // An OriginBoundCertServiceJob is a one-to-one counterpart of an 222 // A ServerBoundCertServiceJob is a one-to-one counterpart of an
222 // OriginBoundCertServiceWorker. It lives only on the OriginBoundCertService's 223 // ServerBoundCertServiceWorker. It lives only on the ServerBoundCertService's
223 // origin message loop. 224 // origin message loop.
224 class OriginBoundCertServiceJob { 225 class ServerBoundCertServiceJob {
225 public: 226 public:
226 OriginBoundCertServiceJob(OriginBoundCertServiceWorker* worker, 227 ServerBoundCertServiceJob(ServerBoundCertServiceWorker* worker,
227 SSLClientCertType type) 228 SSLClientCertType type)
228 : worker_(worker), type_(type) { 229 : worker_(worker), type_(type) {
229 } 230 }
230 231
231 ~OriginBoundCertServiceJob() { 232 ~ServerBoundCertServiceJob() {
232 if (worker_) { 233 if (worker_) {
233 worker_->Cancel(); 234 worker_->Cancel();
234 DeleteAllCanceled(); 235 DeleteAllCanceled();
235 } 236 }
236 } 237 }
237 238
238 SSLClientCertType type() const { return type_; } 239 SSLClientCertType type() const { return type_; }
239 240
240 void AddRequest(OriginBoundCertServiceRequest* request) { 241 void AddRequest(ServerBoundCertServiceRequest* request) {
241 requests_.push_back(request); 242 requests_.push_back(request);
242 } 243 }
243 244
244 void HandleResult(int error, 245 void HandleResult(int error,
245 SSLClientCertType type, 246 SSLClientCertType type,
246 const std::string& private_key, 247 const std::string& private_key,
247 const std::string& cert) { 248 const std::string& cert) {
248 worker_ = NULL; 249 worker_ = NULL;
249 PostAll(error, type, private_key, cert); 250 PostAll(error, type, private_key, cert);
250 } 251 }
251 252
252 private: 253 private:
253 void PostAll(int error, 254 void PostAll(int error,
254 SSLClientCertType type, 255 SSLClientCertType type,
255 const std::string& private_key, 256 const std::string& private_key,
256 const std::string& cert) { 257 const std::string& cert) {
257 std::vector<OriginBoundCertServiceRequest*> requests; 258 std::vector<ServerBoundCertServiceRequest*> requests;
258 requests_.swap(requests); 259 requests_.swap(requests);
259 260
260 for (std::vector<OriginBoundCertServiceRequest*>::iterator 261 for (std::vector<ServerBoundCertServiceRequest*>::iterator
261 i = requests.begin(); i != requests.end(); i++) { 262 i = requests.begin(); i != requests.end(); i++) {
262 (*i)->Post(error, type, private_key, cert); 263 (*i)->Post(error, type, private_key, cert);
263 // Post() causes the OriginBoundCertServiceRequest to delete itself. 264 // Post() causes the ServerBoundCertServiceRequest to delete itself.
264 } 265 }
265 } 266 }
266 267
267 void DeleteAllCanceled() { 268 void DeleteAllCanceled() {
268 for (std::vector<OriginBoundCertServiceRequest*>::iterator 269 for (std::vector<ServerBoundCertServiceRequest*>::iterator
269 i = requests_.begin(); i != requests_.end(); i++) { 270 i = requests_.begin(); i != requests_.end(); i++) {
270 if ((*i)->canceled()) { 271 if ((*i)->canceled()) {
271 delete *i; 272 delete *i;
272 } else { 273 } else {
273 LOG(DFATAL) << "OriginBoundCertServiceRequest leaked!"; 274 LOG(DFATAL) << "ServerBoundCertServiceRequest leaked!";
274 } 275 }
275 } 276 }
276 } 277 }
277 278
278 std::vector<OriginBoundCertServiceRequest*> requests_; 279 std::vector<ServerBoundCertServiceRequest*> requests_;
279 OriginBoundCertServiceWorker* worker_; 280 ServerBoundCertServiceWorker* worker_;
280 SSLClientCertType type_; 281 SSLClientCertType type_;
281 }; 282 };
282 283
283 // static 284 // static
284 const char OriginBoundCertService::kEPKIPassword[] = ""; 285 const char ServerBoundCertService::kEPKIPassword[] = "";
285 286
286 OriginBoundCertService::OriginBoundCertService( 287 ServerBoundCertService::ServerBoundCertService(
287 OriginBoundCertStore* origin_bound_cert_store) 288 ServerBoundCertStore* server_bound_cert_store)
288 : origin_bound_cert_store_(origin_bound_cert_store), 289 : server_bound_cert_store_(server_bound_cert_store),
289 requests_(0), 290 requests_(0),
290 cert_store_hits_(0), 291 cert_store_hits_(0),
291 inflight_joins_(0) {} 292 inflight_joins_(0) {}
292 293
293 OriginBoundCertService::~OriginBoundCertService() { 294 ServerBoundCertService::~ServerBoundCertService() {
294 STLDeleteValues(&inflight_); 295 STLDeleteValues(&inflight_);
295 } 296 }
296 297
297 //static 298 //static
298 std::string OriginBoundCertService::GetDomainForHost(const std::string& host) { 299 std::string ServerBoundCertService::GetDomainForHost(const std::string& host) {
299 std::string domain = 300 std::string domain =
300 RegistryControlledDomainService::GetDomainAndRegistry(host); 301 RegistryControlledDomainService::GetDomainAndRegistry(host);
301 if (domain.empty()) 302 if (domain.empty())
302 return host; 303 return host;
303 return domain; 304 return domain;
304 } 305 }
305 306
306 int OriginBoundCertService::GetOriginBoundCert( 307 int ServerBoundCertService::GetDomainBoundCert(
307 const std::string& origin, 308 const std::string& origin,
308 const std::vector<uint8>& requested_types, 309 const std::vector<uint8>& requested_types,
309 SSLClientCertType* type, 310 SSLClientCertType* type,
310 std::string* private_key, 311 std::string* private_key,
311 std::string* cert, 312 std::string* cert,
312 const CompletionCallback& callback, 313 const CompletionCallback& callback,
313 RequestHandle* out_req) { 314 RequestHandle* out_req) {
314 DCHECK(CalledOnValidThread()); 315 DCHECK(CalledOnValidThread());
315 316
316 *out_req = NULL; 317 *out_req = NULL;
317 318
318 if (callback.is_null() || !private_key || !cert || origin.empty() || 319 if (callback.is_null() || !private_key || !cert || origin.empty() ||
319 requested_types.empty()) { 320 requested_types.empty()) {
320 return ERR_INVALID_ARGUMENT; 321 return ERR_INVALID_ARGUMENT;
321 } 322 }
322 323
324 std::string domain = GetDomainForHost(GURL(origin).host());
325 if (domain.empty())
326 return ERR_INVALID_ARGUMENT;
327
323 SSLClientCertType preferred_type = CLIENT_CERT_INVALID_TYPE; 328 SSLClientCertType preferred_type = CLIENT_CERT_INVALID_TYPE;
324 for (size_t i = 0; i < requested_types.size(); ++i) { 329 for (size_t i = 0; i < requested_types.size(); ++i) {
325 if (IsSupportedCertType(requested_types[i])) { 330 if (IsSupportedCertType(requested_types[i])) {
326 preferred_type = static_cast<SSLClientCertType>(requested_types[i]); 331 preferred_type = static_cast<SSLClientCertType>(requested_types[i]);
327 break; 332 break;
328 } 333 }
329 } 334 }
330 if (preferred_type == CLIENT_CERT_INVALID_TYPE) { 335 if (preferred_type == CLIENT_CERT_INVALID_TYPE) {
331 // None of the requested types are supported. 336 // None of the requested types are supported.
332 return ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED; 337 return ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED;
333 } 338 }
334 339
335 requests_++; 340 requests_++;
336 341
337 // Check if an origin bound cert of an acceptable type already exists for this 342 // Check if a domain bound cert of an acceptable type already exists for this
338 // origin, and that it has not expired. 343 // domain, and that it has not expired.
339 base::Time now = base::Time::Now(); 344 base::Time now = base::Time::Now();
340 base::Time creation_time; 345 base::Time creation_time;
341 base::Time expiration_time; 346 base::Time expiration_time;
342 if (origin_bound_cert_store_->GetOriginBoundCert(origin, 347 if (server_bound_cert_store_->GetServerBoundCert(domain,
343 type, 348 type,
344 &creation_time, 349 &creation_time,
345 &expiration_time, 350 &expiration_time,
346 private_key, 351 private_key,
347 cert)) { 352 cert)) {
348 if (expiration_time < now) { 353 if (expiration_time < now) {
349 DVLOG(1) << "Cert store had expired cert for " << origin; 354 DVLOG(1) << "Cert store had expired cert for " << domain;
350 } else if (!IsSupportedCertType(*type) || 355 } else if (!IsSupportedCertType(*type) ||
351 std::find(requested_types.begin(), requested_types.end(), 356 std::find(requested_types.begin(), requested_types.end(),
352 *type) == requested_types.end()) { 357 *type) == requested_types.end()) {
353 DVLOG(1) << "Cert store had cert of wrong type " << *type << " for " 358 DVLOG(1) << "Cert store had cert of wrong type " << *type << " for "
354 << origin; 359 << domain;
355 } else { 360 } else {
356 cert_store_hits_++; 361 cert_store_hits_++;
357 return OK; 362 return OK;
358 } 363 }
359 } 364 }
360 365
361 // |origin_bound_cert_store_| has no cert for this origin. See if an 366 // |server_bound_cert_store_| has no cert for this domain. See if an
362 // identical request is currently in flight. 367 // identical request is currently in flight.
363 OriginBoundCertServiceJob* job = NULL; 368 ServerBoundCertServiceJob* job = NULL;
364 std::map<std::string, OriginBoundCertServiceJob*>::const_iterator j; 369 std::map<std::string, ServerBoundCertServiceJob*>::const_iterator j;
365 j = inflight_.find(origin); 370 j = inflight_.find(domain);
366 if (j != inflight_.end()) { 371 if (j != inflight_.end()) {
367 // An identical request is in flight already. We'll just attach our 372 // An identical request is in flight already. We'll just attach our
368 // callback. 373 // callback.
369 job = j->second; 374 job = j->second;
370 // Check that the job is for an acceptable type of cert. 375 // Check that the job is for an acceptable type of cert.
371 if (std::find(requested_types.begin(), requested_types.end(), job->type()) 376 if (std::find(requested_types.begin(), requested_types.end(), job->type())
372 == requested_types.end()) { 377 == requested_types.end()) {
373 DVLOG(1) << "Found inflight job of wrong type " << job->type() 378 DVLOG(1) << "Found inflight job of wrong type " << job->type()
374 << " for " << origin; 379 << " for " << domain;
375 // If we get here, the server is asking for different types of certs in 380 // If we get here, the server is asking for different types of certs in
376 // short succession. This probably means the server is broken or 381 // short succession. This probably means the server is broken or
377 // misconfigured. Since we only store one type of cert per origin, we 382 // misconfigured. Since we only store one type of cert per domain, we
378 // are unable to handle this well. Just return an error and let the first 383 // are unable to handle this well. Just return an error and let the first
379 // job finish. 384 // job finish.
380 return ERR_ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH; 385 return ERR_ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH;
381 } 386 }
382 inflight_joins_++; 387 inflight_joins_++;
383 } else { 388 } else {
384 // Need to make a new request. 389 // Need to make a new request.
385 OriginBoundCertServiceWorker* worker = new OriginBoundCertServiceWorker( 390 ServerBoundCertServiceWorker* worker = new ServerBoundCertServiceWorker(
386 origin, 391 domain,
387 preferred_type, 392 preferred_type,
388 this); 393 this);
389 job = new OriginBoundCertServiceJob(worker, preferred_type); 394 job = new ServerBoundCertServiceJob(worker, preferred_type);
390 if (!worker->Start()) { 395 if (!worker->Start()) {
391 delete job; 396 delete job;
392 delete worker; 397 delete worker;
393 // TODO(rkn): Log to the NetLog. 398 // TODO(rkn): Log to the NetLog.
394 LOG(ERROR) << "OriginBoundCertServiceWorker couldn't be started."; 399 LOG(ERROR) << "ServerBoundCertServiceWorker couldn't be started.";
395 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. 400 return ERR_INSUFFICIENT_RESOURCES; // Just a guess.
396 } 401 }
397 inflight_[origin] = job; 402 inflight_[domain] = job;
398 } 403 }
399 404
400 OriginBoundCertServiceRequest* request = 405 ServerBoundCertServiceRequest* request =
401 new OriginBoundCertServiceRequest(callback, type, private_key, cert); 406 new ServerBoundCertServiceRequest(callback, type, private_key, cert);
402 job->AddRequest(request); 407 job->AddRequest(request);
403 *out_req = request; 408 *out_req = request;
404 return ERR_IO_PENDING; 409 return ERR_IO_PENDING;
405 } 410 }
406 411
407 OriginBoundCertStore* OriginBoundCertService::GetCertStore() { 412 ServerBoundCertStore* ServerBoundCertService::GetCertStore() {
408 return origin_bound_cert_store_.get(); 413 return server_bound_cert_store_.get();
409 } 414 }
410 415
411 // static 416 // static
412 int OriginBoundCertService::GenerateCert(const std::string& origin, 417 int ServerBoundCertService::GenerateCert(const std::string& server_identifier,
413 SSLClientCertType type, 418 SSLClientCertType type,
414 uint32 serial_number, 419 uint32 serial_number,
415 base::Time* creation_time, 420 base::Time* creation_time,
416 base::Time* expiration_time, 421 base::Time* expiration_time,
417 std::string* private_key, 422 std::string* private_key,
418 std::string* cert) { 423 std::string* cert) {
419 base::Time now = base::Time::Now(); 424 base::Time now = base::Time::Now();
420 base::Time not_valid_after = 425 base::Time not_valid_after =
421 now + base::TimeDelta::FromDays(kValidityPeriodInDays); 426 now + base::TimeDelta::FromDays(kValidityPeriodInDays);
422 std::string der_cert; 427 std::string der_cert;
423 std::vector<uint8> private_key_info; 428 std::vector<uint8> private_key_info;
424 switch (type) { 429 switch (type) {
425 case CLIENT_CERT_ECDSA_SIGN: { 430 case CLIENT_CERT_ECDSA_SIGN: {
426 scoped_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create()); 431 scoped_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create());
427 if (!key.get()) { 432 if (!key.get()) {
428 DLOG(ERROR) << "Unable to create key pair for client"; 433 DLOG(ERROR) << "Unable to create key pair for client";
429 return ERR_KEY_GENERATION_FAILED; 434 return ERR_KEY_GENERATION_FAILED;
430 } 435 }
431 if (!x509_util::CreateOriginBoundCertEC( 436 if (!x509_util::CreateDomainBoundCertEC(
432 key.get(), 437 key.get(),
433 origin, 438 server_identifier,
434 serial_number, 439 serial_number,
435 now, 440 now,
436 not_valid_after, 441 not_valid_after,
437 &der_cert)) { 442 &der_cert)) {
438 DLOG(ERROR) << "Unable to create x509 cert for client"; 443 DLOG(ERROR) << "Unable to create x509 cert for client";
439 return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED; 444 return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED;
440 } 445 }
441 446
442 if (!key->ExportEncryptedPrivateKey( 447 if (!key->ExportEncryptedPrivateKey(
443 kEPKIPassword, 1, &private_key_info)) { 448 kEPKIPassword, 1, &private_key_info)) {
(...skipping 11 matching lines...) Expand all
455 // std::string* to prevent this copying. 460 // std::string* to prevent this copying.
456 std::string key_out(private_key_info.begin(), private_key_info.end()); 461 std::string key_out(private_key_info.begin(), private_key_info.end());
457 462
458 private_key->swap(key_out); 463 private_key->swap(key_out);
459 cert->swap(der_cert); 464 cert->swap(der_cert);
460 *creation_time = now; 465 *creation_time = now;
461 *expiration_time = not_valid_after; 466 *expiration_time = not_valid_after;
462 return OK; 467 return OK;
463 } 468 }
464 469
465 void OriginBoundCertService::CancelRequest(RequestHandle req) { 470 void ServerBoundCertService::CancelRequest(RequestHandle req) {
466 DCHECK(CalledOnValidThread()); 471 DCHECK(CalledOnValidThread());
467 OriginBoundCertServiceRequest* request = 472 ServerBoundCertServiceRequest* request =
468 reinterpret_cast<OriginBoundCertServiceRequest*>(req); 473 reinterpret_cast<ServerBoundCertServiceRequest*>(req);
469 request->Cancel(); 474 request->Cancel();
470 } 475 }
471 476
472 // HandleResult is called by OriginBoundCertServiceWorker on the origin message 477 // HandleResult is called by ServerBoundCertServiceWorker on the origin message
473 // loop. It deletes OriginBoundCertServiceJob. 478 // loop. It deletes ServerBoundCertServiceJob.
474 void OriginBoundCertService::HandleResult(const std::string& origin, 479 void ServerBoundCertService::HandleResult(const std::string& server_identifier,
475 int error, 480 int error,
476 SSLClientCertType type, 481 SSLClientCertType type,
477 base::Time creation_time, 482 base::Time creation_time,
478 base::Time expiration_time, 483 base::Time expiration_time,
479 const std::string& private_key, 484 const std::string& private_key,
480 const std::string& cert) { 485 const std::string& cert) {
481 DCHECK(CalledOnValidThread()); 486 DCHECK(CalledOnValidThread());
482 487
483 origin_bound_cert_store_->SetOriginBoundCert( 488 server_bound_cert_store_->SetServerBoundCert(
484 origin, type, creation_time, expiration_time, private_key, cert); 489 server_identifier, type, creation_time, expiration_time, private_key,
490 cert);
485 491
486 std::map<std::string, OriginBoundCertServiceJob*>::iterator j; 492 std::map<std::string, ServerBoundCertServiceJob*>::iterator j;
487 j = inflight_.find(origin); 493 j = inflight_.find(server_identifier);
488 if (j == inflight_.end()) { 494 if (j == inflight_.end()) {
489 NOTREACHED(); 495 NOTREACHED();
490 return; 496 return;
491 } 497 }
492 OriginBoundCertServiceJob* job = j->second; 498 ServerBoundCertServiceJob* job = j->second;
493 inflight_.erase(j); 499 inflight_.erase(j);
494 500
495 job->HandleResult(error, type, private_key, cert); 501 job->HandleResult(error, type, private_key, cert);
496 delete job; 502 delete job;
497 } 503 }
498 504
499 int OriginBoundCertService::cert_count() { 505 int ServerBoundCertService::cert_count() {
500 return origin_bound_cert_store_->GetCertCount(); 506 return server_bound_cert_store_->GetCertCount();
501 } 507 }
502 508
503 } // namespace net 509 } // namespace net
OLDNEW
« no previous file with comments | « net/base/origin_bound_cert_service.h ('k') | net/base/origin_bound_cert_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698