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

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

Issue 8662036: Support EC certs in OriginBoundCertService and OriginBoundCertStore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <limits> 8 #include <limits>
8 9
9 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
10 #include "base/location.h" 11 #include "base/location.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop.h" 15 #include "base/message_loop.h"
15 #include "base/rand_util.h" 16 #include "base/rand_util.h"
16 #include "base/stl_util.h" 17 #include "base/stl_util.h"
17 #include "base/threading/worker_pool.h" 18 #include "base/threading/worker_pool.h"
19 #include "crypto/ec_private_key.h"
18 #include "crypto/rsa_private_key.h" 20 #include "crypto/rsa_private_key.h"
19 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
20 #include "net/base/origin_bound_cert_store.h" 22 #include "net/base/origin_bound_cert_store.h"
21 #include "net/base/x509_certificate.h" 23 #include "net/base/x509_certificate.h"
22 #include "net/base/x509_util.h" 24 #include "net/base/x509_util.h"
23 25
24 #if defined(USE_NSS) 26 #if defined(USE_NSS)
25 #include <private/pprthred.h> // PR_DetachThread 27 #include <private/pprthred.h> // PR_DetachThread
26 #endif 28 #endif
27 29
28 namespace net { 30 namespace net {
29 31
30 namespace { 32 namespace {
31 33
32 const int kKeySizeInBits = 1024; 34 const int kKeySizeInBits = 1024;
33 const int kValidityPeriodInDays = 365; 35 const int kValidityPeriodInDays = 365;
34 36
35 } // namespace 37 } // namespace
36 38
39 // static
40 const char OriginBoundCertService::kEPKIPassword[] = "";
41
37 // Represents the output and result callback of a request. 42 // Represents the output and result callback of a request.
38 class OriginBoundCertServiceRequest { 43 class OriginBoundCertServiceRequest {
39 public: 44 public:
40 OriginBoundCertServiceRequest(const CompletionCallback& callback, 45 OriginBoundCertServiceRequest(const CompletionCallback& callback,
46 OriginBoundCertType* type,
41 std::string* private_key, 47 std::string* private_key,
42 std::string* cert) 48 std::string* cert)
43 : callback_(callback), 49 : callback_(callback),
50 type_(type),
44 private_key_(private_key), 51 private_key_(private_key),
45 cert_(cert) { 52 cert_(cert) {
46 } 53 }
47 54
48 // Ensures that the result callback will never be made. 55 // Ensures that the result callback will never be made.
49 void Cancel() { 56 void Cancel() {
50 callback_.Reset(); 57 callback_.Reset();
58 type_ = NULL;
51 private_key_ = NULL; 59 private_key_ = NULL;
52 cert_ = NULL; 60 cert_ = NULL;
53 } 61 }
54 62
55 // Copies the contents of |private_key| and |cert| to the caller's output 63 // Copies the contents of |private_key| and |cert| to the caller's output
56 // arguments and calls the callback. 64 // arguments and calls the callback.
57 void Post(int error, 65 void Post(int error,
66 OriginBoundCertType type,
58 const std::string& private_key, 67 const std::string& private_key,
59 const std::string& cert) { 68 const std::string& cert) {
60 if (!callback_.is_null()) { 69 if (!callback_.is_null()) {
70 *type_ = type;
61 *private_key_ = private_key; 71 *private_key_ = private_key;
62 *cert_ = cert; 72 *cert_ = cert;
63 callback_.Run(error); 73 callback_.Run(error);
64 } 74 }
65 delete this; 75 delete this;
66 } 76 }
67 77
68 bool canceled() const { return callback_.is_null(); } 78 bool canceled() const { return callback_.is_null(); }
69 79
70 private: 80 private:
71 CompletionCallback callback_; 81 CompletionCallback callback_;
82 OriginBoundCertType* type_;
72 std::string* private_key_; 83 std::string* private_key_;
73 std::string* cert_; 84 std::string* cert_;
74 }; 85 };
75 86
76 // OriginBoundCertServiceWorker runs on a worker thread and takes care of the 87 // OriginBoundCertServiceWorker runs on a worker thread and takes care of the
77 // blocking process of performing key generation. Deletes itself eventually 88 // blocking process of performing key generation. Deletes itself eventually
78 // if Start() succeeds. 89 // if Start() succeeds.
79 class OriginBoundCertServiceWorker { 90 class OriginBoundCertServiceWorker {
80 public: 91 public:
81 OriginBoundCertServiceWorker( 92 OriginBoundCertServiceWorker(
82 const std::string& origin, 93 const std::string& origin,
94 OriginBoundCertType type,
83 OriginBoundCertService* origin_bound_cert_service) 95 OriginBoundCertService* origin_bound_cert_service)
84 : origin_(origin), 96 : origin_(origin),
97 type_(type),
85 serial_number_(base::RandInt(0, std::numeric_limits<int>::max())), 98 serial_number_(base::RandInt(0, std::numeric_limits<int>::max())),
86 origin_loop_(MessageLoop::current()), 99 origin_loop_(MessageLoop::current()),
87 origin_bound_cert_service_(origin_bound_cert_service), 100 origin_bound_cert_service_(origin_bound_cert_service),
88 canceled_(false), 101 canceled_(false),
89 error_(ERR_FAILED) { 102 error_(ERR_FAILED) {
90 } 103 }
91 104
92 bool Start() { 105 bool Start() {
93 DCHECK_EQ(MessageLoop::current(), origin_loop_); 106 DCHECK_EQ(MessageLoop::current(), origin_loop_);
94 107
95 return base::WorkerPool::PostTask( 108 return base::WorkerPool::PostTask(
96 FROM_HERE, 109 FROM_HERE,
97 NewRunnableMethod(this, &OriginBoundCertServiceWorker::Run), 110 NewRunnableMethod(this, &OriginBoundCertServiceWorker::Run),
98 true /* task is slow */); 111 true /* task is slow */);
99 } 112 }
100 113
101 // Cancel is called from the origin loop when the OriginBoundCertService is 114 // Cancel is called from the origin loop when the OriginBoundCertService is
102 // getting deleted. 115 // getting deleted.
103 void Cancel() { 116 void Cancel() {
104 DCHECK_EQ(MessageLoop::current(), origin_loop_); 117 DCHECK_EQ(MessageLoop::current(), origin_loop_);
105 base::AutoLock locked(lock_); 118 base::AutoLock locked(lock_);
106 canceled_ = true; 119 canceled_ = true;
107 } 120 }
108 121
109 private: 122 private:
110 void Run() { 123 void Run() {
111 // Runs on a worker thread. 124 // Runs on a worker thread.
112 error_ = OriginBoundCertService::GenerateCert(origin_, 125 error_ = OriginBoundCertService::GenerateCert(origin_,
126 type_,
113 serial_number_, 127 serial_number_,
114 &private_key_, 128 &private_key_,
115 &cert_); 129 &cert_);
116 #if defined(USE_NSS) 130 #if defined(USE_NSS)
117 // Detach the thread from NSPR. 131 // Detach the thread from NSPR.
118 // Calling NSS functions attaches the thread to NSPR, which stores 132 // Calling NSS functions attaches the thread to NSPR, which stores
119 // the NSPR thread ID in thread-specific data. 133 // the NSPR thread ID in thread-specific data.
120 // The threads in our thread pool terminate after we have called 134 // The threads in our thread pool terminate after we have called
121 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets 135 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
122 // segfaults on shutdown when the threads' thread-specific data 136 // segfaults on shutdown when the threads' thread-specific data
123 // destructors run. 137 // destructors run.
124 PR_DetachThread(); 138 PR_DetachThread();
125 #endif 139 #endif
126 Finish(); 140 Finish();
127 } 141 }
128 142
129 // DoReply runs on the origin thread. 143 // DoReply runs on the origin thread.
130 void DoReply() { 144 void DoReply() {
131 DCHECK_EQ(MessageLoop::current(), origin_loop_); 145 DCHECK_EQ(MessageLoop::current(), origin_loop_);
132 { 146 {
133 // We lock here because the worker thread could still be in Finished, 147 // We lock here because the worker thread could still be in Finished,
134 // after the PostTask, but before unlocking |lock_|. If we do not lock in 148 // after the PostTask, but before unlocking |lock_|. If we do not lock in
135 // this case, we will end up deleting a locked Lock, which can lead to 149 // this case, we will end up deleting a locked Lock, which can lead to
136 // memory leaks or worse errors. 150 // memory leaks or worse errors.
137 base::AutoLock locked(lock_); 151 base::AutoLock locked(lock_);
138 if (!canceled_) { 152 if (!canceled_) {
139 origin_bound_cert_service_->HandleResult(origin_, error_, 153 origin_bound_cert_service_->HandleResult(origin_, error_, type_,
140 private_key_, cert_); 154 private_key_, cert_);
141 } 155 }
142 } 156 }
143 delete this; 157 delete this;
144 } 158 }
145 159
146 void Finish() { 160 void Finish() {
147 // Runs on the worker thread. 161 // Runs on the worker thread.
148 // We assume that the origin loop outlives the OriginBoundCertService. If 162 // We assume that the origin loop outlives the OriginBoundCertService. If
149 // the OriginBoundCertService is deleted, it will call Cancel on us. If it 163 // the OriginBoundCertService is deleted, it will call Cancel on us. If it
(...skipping 12 matching lines...) Expand all
162 origin_loop_->PostTask( 176 origin_loop_->PostTask(
163 FROM_HERE, 177 FROM_HERE,
164 NewRunnableMethod(this, &OriginBoundCertServiceWorker::DoReply)); 178 NewRunnableMethod(this, &OriginBoundCertServiceWorker::DoReply));
165 } 179 }
166 } 180 }
167 if (canceled) 181 if (canceled)
168 delete this; 182 delete this;
169 } 183 }
170 184
171 const std::string origin_; 185 const std::string origin_;
186 const OriginBoundCertType type_;
172 // Note that serial_number_ must be initialized on a non-worker thread 187 // Note that serial_number_ must be initialized on a non-worker thread
173 // (see documentation for OriginBoundCertService::GenerateCert). 188 // (see documentation for OriginBoundCertService::GenerateCert).
174 uint32 serial_number_; 189 uint32 serial_number_;
175 MessageLoop* const origin_loop_; 190 MessageLoop* const origin_loop_;
176 OriginBoundCertService* const origin_bound_cert_service_; 191 OriginBoundCertService* const origin_bound_cert_service_;
177 192
178 // lock_ protects canceled_. 193 // lock_ protects canceled_.
179 base::Lock lock_; 194 base::Lock lock_;
180 195
181 // If canceled_ is true, 196 // If canceled_ is true,
182 // * origin_loop_ cannot be accessed by the worker thread, 197 // * origin_loop_ cannot be accessed by the worker thread,
183 // * origin_bound_cert_service_ cannot be accessed by any thread. 198 // * origin_bound_cert_service_ cannot be accessed by any thread.
184 bool canceled_; 199 bool canceled_;
185 200
186 int error_; 201 int error_;
187 std::string private_key_; 202 std::string private_key_;
188 std::string cert_; 203 std::string cert_;
189 204
190 DISALLOW_COPY_AND_ASSIGN(OriginBoundCertServiceWorker); 205 DISALLOW_COPY_AND_ASSIGN(OriginBoundCertServiceWorker);
191 }; 206 };
192 207
193 // An OriginBoundCertServiceJob is a one-to-one counterpart of an 208 // An OriginBoundCertServiceJob is a one-to-one counterpart of an
194 // OriginBoundCertServiceWorker. It lives only on the OriginBoundCertService's 209 // OriginBoundCertServiceWorker. It lives only on the OriginBoundCertService's
195 // origin message loop. 210 // origin message loop.
196 class OriginBoundCertServiceJob { 211 class OriginBoundCertServiceJob {
197 public: 212 public:
198 explicit OriginBoundCertServiceJob(OriginBoundCertServiceWorker* worker) 213 explicit OriginBoundCertServiceJob(OriginBoundCertServiceWorker* worker,
199 : worker_(worker) { 214 OriginBoundCertType type)
Ryan Sleevi 2011/11/25 00:07:02 nit: Doesn't need to be explicit anymore
mattm 2011/12/02 01:55:59 Done.
215 : worker_(worker), type_(type) {
200 } 216 }
201 217
202 ~OriginBoundCertServiceJob() { 218 ~OriginBoundCertServiceJob() {
203 if (worker_) { 219 if (worker_) {
204 worker_->Cancel(); 220 worker_->Cancel();
205 DeleteAllCanceled(); 221 DeleteAllCanceled();
206 } 222 }
207 } 223 }
208 224
225 OriginBoundCertType type() const { return type_; }
226
227 void Abort() {
228 worker_->Cancel();
229 HandleResult(ERR_ABORTED, ORIGIN_BOUND_INVALID_CERT_TYPE, "", "");
230 }
231
209 void AddRequest(OriginBoundCertServiceRequest* request) { 232 void AddRequest(OriginBoundCertServiceRequest* request) {
210 requests_.push_back(request); 233 requests_.push_back(request);
211 } 234 }
212 235
213 void HandleResult(int error, 236 void HandleResult(int error,
237 OriginBoundCertType type,
214 const std::string& private_key, 238 const std::string& private_key,
215 const std::string& cert) { 239 const std::string& cert) {
216 worker_ = NULL; 240 worker_ = NULL;
217 PostAll(error, private_key, cert); 241 PostAll(error, type, private_key, cert);
218 } 242 }
219 243
220 private: 244 private:
221 void PostAll(int error, 245 void PostAll(int error,
246 OriginBoundCertType type,
222 const std::string& private_key, 247 const std::string& private_key,
223 const std::string& cert) { 248 const std::string& cert) {
224 std::vector<OriginBoundCertServiceRequest*> requests; 249 std::vector<OriginBoundCertServiceRequest*> requests;
225 requests_.swap(requests); 250 requests_.swap(requests);
226 251
227 for (std::vector<OriginBoundCertServiceRequest*>::iterator 252 for (std::vector<OriginBoundCertServiceRequest*>::iterator
228 i = requests.begin(); i != requests.end(); i++) { 253 i = requests.begin(); i != requests.end(); i++) {
229 (*i)->Post(error, private_key, cert); 254 (*i)->Post(error, type, private_key, cert);
230 // Post() causes the OriginBoundCertServiceRequest to delete itself. 255 // Post() causes the OriginBoundCertServiceRequest to delete itself.
231 } 256 }
232 } 257 }
233 258
234 void DeleteAllCanceled() { 259 void DeleteAllCanceled() {
235 for (std::vector<OriginBoundCertServiceRequest*>::iterator 260 for (std::vector<OriginBoundCertServiceRequest*>::iterator
236 i = requests_.begin(); i != requests_.end(); i++) { 261 i = requests_.begin(); i != requests_.end(); i++) {
237 if ((*i)->canceled()) { 262 if ((*i)->canceled()) {
238 delete *i; 263 delete *i;
239 } else { 264 } else {
240 LOG(DFATAL) << "OriginBoundCertServiceRequest leaked!"; 265 LOG(DFATAL) << "OriginBoundCertServiceRequest leaked!";
241 } 266 }
242 } 267 }
243 } 268 }
244 269
245 std::vector<OriginBoundCertServiceRequest*> requests_; 270 std::vector<OriginBoundCertServiceRequest*> requests_;
246 OriginBoundCertServiceWorker* worker_; 271 OriginBoundCertServiceWorker* worker_;
272 OriginBoundCertType type_;
247 }; 273 };
248 274
249 OriginBoundCertService::OriginBoundCertService( 275 OriginBoundCertService::OriginBoundCertService(
250 OriginBoundCertStore* origin_bound_cert_store) 276 OriginBoundCertStore* origin_bound_cert_store)
251 : origin_bound_cert_store_(origin_bound_cert_store), 277 : origin_bound_cert_store_(origin_bound_cert_store),
252 requests_(0), 278 requests_(0),
253 cert_store_hits_(0), 279 cert_store_hits_(0),
254 inflight_joins_(0) {} 280 inflight_joins_(0) {}
255 281
256 OriginBoundCertService::~OriginBoundCertService() { 282 OriginBoundCertService::~OriginBoundCertService() {
257 STLDeleteValues(&inflight_); 283 STLDeleteValues(&inflight_);
258 } 284 }
259 285
260 int OriginBoundCertService::GetOriginBoundCert( 286 int OriginBoundCertService::GetOriginBoundCert(
261 const std::string& origin, 287 const std::string& origin,
288 const std::vector<OriginBoundCertType>& requested_types,
289 OriginBoundCertType* type,
262 std::string* private_key, 290 std::string* private_key,
263 std::string* cert, 291 std::string* cert,
264 const CompletionCallback& callback, 292 const CompletionCallback& callback,
265 RequestHandle* out_req) { 293 RequestHandle* out_req) {
266 DCHECK(CalledOnValidThread()); 294 DCHECK(CalledOnValidThread());
267 295
268 if (callback.is_null() || !private_key || !cert || origin.empty()) { 296 if (callback.is_null() || requested_types.empty() || !private_key ||
297 !cert || origin.empty()) {
269 *out_req = NULL; 298 *out_req = NULL;
270 return ERR_INVALID_ARGUMENT; 299 return ERR_INVALID_ARGUMENT;
271 } 300 }
272 301
273 requests_++; 302 requests_++;
274 303
275 // Check if an origin bound cert already exists for this origin. 304 // Check if an origin bound cert of an acceptable type already exists for this
305 // origin.
276 if (origin_bound_cert_store_->GetOriginBoundCert(origin, 306 if (origin_bound_cert_store_->GetOriginBoundCert(origin,
307 type,
277 private_key, 308 private_key,
278 cert)) { 309 cert)) {
279 cert_store_hits_++; 310 if (std::find(requested_types.begin(), requested_types.end(), *type) !=
280 *out_req = NULL; 311 requested_types.end()) {
281 return OK; 312 cert_store_hits_++;
313 *out_req = NULL;
314 return OK;
315 }
316 DVLOG(1) << "Cert store had cert of wrong type " << *type << " for "
317 << origin;
282 } 318 }
283 319
284 // |origin_bound_cert_store_| has no cert for this origin. See if an 320 // |origin_bound_cert_store_| has no cert for this origin. See if an
285 // identical request is currently in flight. 321 // identical request is currently in flight.
286 OriginBoundCertServiceJob* job; 322 OriginBoundCertServiceJob* job = NULL;
287 std::map<std::string, OriginBoundCertServiceJob*>::const_iterator j; 323 std::map<std::string, OriginBoundCertServiceJob*>::iterator j;
288 j = inflight_.find(origin); 324 j = inflight_.find(origin);
289 if (j != inflight_.end()) { 325 if (j != inflight_.end()) {
290 // An identical request is in flight already. We'll just attach our 326 // An identical request is in flight already. We'll just attach our
291 // callback. 327 // callback.
292 inflight_joins_++; 328 inflight_joins_++;
293 job = j->second; 329 job = j->second;
294 } else { 330 // Check that the job is for an acceptable type of cert.
331 if (std::find(requested_types.begin(), requested_types.end(), job->type())
332 == requested_types.end()) {
333 DVLOG(1) << "Aborting inflight job of wrong type " << job->type()
334 << " for " << origin;
335 job->Abort();
336 job = NULL;
337 inflight_.erase(j);
338 }
339 }
340
341 if (!job) {
295 // Need to make a new request. 342 // Need to make a new request.
296 OriginBoundCertServiceWorker* worker = 343 OriginBoundCertServiceWorker* worker =
297 new OriginBoundCertServiceWorker(origin, this); 344 new OriginBoundCertServiceWorker(origin, requested_types[0], this);
298 job = new OriginBoundCertServiceJob(worker); 345 job = new OriginBoundCertServiceJob(worker, requested_types[0]);
wtc 2011/11/30 23:23:40 IMPORTANT: We should not blindly pick requested_ty
mattm 2011/12/01 00:06:27 My assumption was that the OriginBoundCertType enu
299 if (!worker->Start()) { 346 if (!worker->Start()) {
300 delete job; 347 delete job;
301 delete worker; 348 delete worker;
302 *out_req = NULL; 349 *out_req = NULL;
303 // TODO(rkn): Log to the NetLog. 350 // TODO(rkn): Log to the NetLog.
304 LOG(ERROR) << "OriginBoundCertServiceWorker couldn't be started."; 351 LOG(ERROR) << "OriginBoundCertServiceWorker couldn't be started.";
305 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. 352 return ERR_INSUFFICIENT_RESOURCES; // Just a guess.
306 } 353 }
307 inflight_[origin] = job; 354 inflight_[origin] = job;
308 } 355 }
309 356
310 OriginBoundCertServiceRequest* request = 357 OriginBoundCertServiceRequest* request =
311 new OriginBoundCertServiceRequest(callback, private_key, cert); 358 new OriginBoundCertServiceRequest(callback, type, private_key, cert);
312 job->AddRequest(request); 359 job->AddRequest(request);
313 *out_req = request; 360 *out_req = request;
314 return ERR_IO_PENDING; 361 return ERR_IO_PENDING;
315 } 362 }
316 363
317 // static 364 // static
318 int OriginBoundCertService::GenerateCert(const std::string& origin, 365 int OriginBoundCertService::GenerateCert(const std::string& origin,
366 OriginBoundCertType type,
319 uint32 serial_number, 367 uint32 serial_number,
320 std::string* private_key, 368 std::string* private_key,
321 std::string* cert) { 369 std::string* cert) {
322 scoped_ptr<crypto::RSAPrivateKey> key(
323 crypto::RSAPrivateKey::Create(kKeySizeInBits));
324 if (!key.get()) {
325 LOG(WARNING) << "Unable to create key pair for client";
326 return ERR_KEY_GENERATION_FAILED;
327 }
328 std::string der_cert; 370 std::string der_cert;
329 if (!x509_util::CreateOriginBoundCertRSA( 371 std::vector<uint8> private_key_info;
330 key.get(), 372 switch (type) {
331 origin, 373 case ORIGIN_BOUND_RSA_CERT:
wtc 2011/11/30 23:23:40 See the Style Guide for an example of how to forma
mattm 2011/12/02 01:55:59 Done.
332 serial_number, 374 {
333 base::TimeDelta::FromDays(kValidityPeriodInDays), 375 scoped_ptr<crypto::RSAPrivateKey> key(
334 &der_cert)) { 376 crypto::RSAPrivateKey::Create(kKeySizeInBits));
335 LOG(WARNING) << "Unable to create x509 cert for client"; 377 if (!key.get()) {
336 return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED; 378 DLOG(ERROR) << "Unable to create key pair for client";
379 return ERR_KEY_GENERATION_FAILED;
380 }
381 if (!x509_util::CreateOriginBoundCertRSA(
382 key.get(),
383 origin,
384 serial_number,
385 base::TimeDelta::FromDays(kValidityPeriodInDays),
386 &der_cert)) {
387 DLOG(ERROR) << "Unable to create x509 cert for client";
388 return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED;
389 }
390
391 if (!key->ExportPrivateKey(&private_key_info)) {
392 DLOG(ERROR) << "Unable to export private key";
393 return ERR_PRIVATE_KEY_EXPORT_FAILED;
394 }
395 }
396 break;
397 case ORIGIN_BOUND_EC_CERT:
398 {
399 scoped_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create());
400 if (!key.get()) {
401 DLOG(ERROR) << "Unable to create key pair for client";
402 return ERR_KEY_GENERATION_FAILED;
403 }
404 if (!x509_util::CreateOriginBoundCertEC(
405 key.get(),
406 origin,
407 serial_number,
408 base::TimeDelta::FromDays(kValidityPeriodInDays),
409 &der_cert)) {
410 DLOG(ERROR) << "Unable to create x509 cert for client";
411 return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED;
412 }
413
414 if (!key->ExportEncryptedPrivateKey(
415 kEPKIPassword, 1, &private_key_info)) {
416 DLOG(ERROR) << "Unable to export private key";
417 return ERR_PRIVATE_KEY_EXPORT_FAILED;
418 }
419 }
420 break;
421 default:
422 NOTREACHED();
423 return ERR_INVALID_ARGUMENT;
337 } 424 }
338 425
339 std::vector<uint8> private_key_info;
340 if (!key->ExportPrivateKey(&private_key_info)) {
341 LOG(WARNING) << "Unable to export private key";
342 return ERR_PRIVATE_KEY_EXPORT_FAILED;
343 }
344 // TODO(rkn): Perhaps ExportPrivateKey should be changed to output a 426 // TODO(rkn): Perhaps ExportPrivateKey should be changed to output a
345 // std::string* to prevent this copying. 427 // std::string* to prevent this copying.
346 std::string key_out(private_key_info.begin(), private_key_info.end()); 428 std::string key_out(private_key_info.begin(), private_key_info.end());
347 429
348 private_key->swap(key_out); 430 private_key->swap(key_out);
349 cert->swap(der_cert); 431 cert->swap(der_cert);
350 return OK; 432 return OK;
351 } 433 }
352 434
353 void OriginBoundCertService::CancelRequest(RequestHandle req) { 435 void OriginBoundCertService::CancelRequest(RequestHandle req) {
354 DCHECK(CalledOnValidThread()); 436 DCHECK(CalledOnValidThread());
355 OriginBoundCertServiceRequest* request = 437 OriginBoundCertServiceRequest* request =
356 reinterpret_cast<OriginBoundCertServiceRequest*>(req); 438 reinterpret_cast<OriginBoundCertServiceRequest*>(req);
357 request->Cancel(); 439 request->Cancel();
358 } 440 }
359 441
360 // HandleResult is called by OriginBoundCertServiceWorker on the origin message 442 // HandleResult is called by OriginBoundCertServiceWorker on the origin message
361 // loop. It deletes OriginBoundCertServiceJob. 443 // loop. It deletes OriginBoundCertServiceJob.
362 void OriginBoundCertService::HandleResult(const std::string& origin, 444 void OriginBoundCertService::HandleResult(const std::string& origin,
363 int error, 445 int error,
364 const std::string& private_key, 446 OriginBoundCertType type,
365 const std::string& cert) { 447 const std::string& private_key,
448 const std::string& cert) {
366 DCHECK(CalledOnValidThread()); 449 DCHECK(CalledOnValidThread());
367 450
368 origin_bound_cert_store_->SetOriginBoundCert(origin, private_key, cert); 451 origin_bound_cert_store_->SetOriginBoundCert(origin, type, private_key, cert);
369 452
370 std::map<std::string, OriginBoundCertServiceJob*>::iterator j; 453 std::map<std::string, OriginBoundCertServiceJob*>::iterator j;
371 j = inflight_.find(origin); 454 j = inflight_.find(origin);
372 if (j == inflight_.end()) { 455 if (j == inflight_.end()) {
373 NOTREACHED(); 456 NOTREACHED();
374 return; 457 return;
375 } 458 }
376 OriginBoundCertServiceJob* job = j->second; 459 OriginBoundCertServiceJob* job = j->second;
377 inflight_.erase(j); 460 inflight_.erase(j);
378 461
379 job->HandleResult(error, private_key, cert); 462 job->HandleResult(error, type, private_key, cert);
380 delete job; 463 delete job;
381 } 464 }
382 465
383 int OriginBoundCertService::cert_count() { 466 int OriginBoundCertService::cert_count() {
384 return origin_bound_cert_store_->GetCertCount(); 467 return origin_bound_cert_store_->GetCertCount();
385 } 468 }
386 469
387 } // namespace net 470 } // namespace net
388 471
389 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::OriginBoundCertServiceWorker); 472 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::OriginBoundCertServiceWorker);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698