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

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

Powered by Google App Engine
This is Rietveld 408576698