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

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