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

Side by Side Diff: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc

Issue 884073002: Implement chrome.platformKeys.getKeyPair(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert_impl2
Patch Set: Updated histogram. Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/chromeos/platform_keys/platform_keys.h" 5 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
6 6
7 #include <cert.h>
7 #include <cryptohi.h> 8 #include <cryptohi.h>
9 #include <keyhi.h>
10 #include <secder.h>
8 11
9 #include "base/bind.h" 12 #include "base/bind.h"
10 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
11 #include "base/callback.h" 14 #include "base/callback.h"
12 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
13 #include "base/location.h" 16 #include "base/location.h"
14 #include "base/logging.h" 17 #include "base/logging.h"
15 #include "base/macros.h" 18 #include "base/macros.h"
16 #include "base/single_thread_task_runner.h" 19 #include "base/single_thread_task_runner.h"
20 #include "base/stl_util.h"
17 #include "base/thread_task_runner_handle.h" 21 #include "base/thread_task_runner_handle.h"
18 #include "base/threading/worker_pool.h" 22 #include "base/threading/worker_pool.h"
19 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/browser_process_platform_part_chromeos.h" 24 #include "chrome/browser/browser_process_platform_part_chromeos.h"
21 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" 25 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h"
22 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
23 #include "chrome/browser/chromeos/profiles/profile_helper.h" 27 #include "chrome/browser/chromeos/profiles/profile_helper.h"
24 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat form_keys_api.h" 28 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat form_keys_api.h"
25 #include "chrome/browser/net/nss_context.h" 29 #include "chrome/browser/net/nss_context.h"
26 #include "chrome/browser/profiles/profile.h" 30 #include "chrome/browser/profiles/profile.h"
27 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 31 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
28 #include "content/public/browser/browser_context.h" 32 #include "content/public/browser/browser_context.h"
29 #include "content/public/browser/browser_thread.h" 33 #include "content/public/browser/browser_thread.h"
30 #include "crypto/rsa_private_key.h" 34 #include "crypto/rsa_private_key.h"
31 #include "net/base/crypto_module.h" 35 #include "net/base/crypto_module.h"
32 #include "net/base/net_errors.h" 36 #include "net/base/net_errors.h"
33 #include "net/cert/cert_database.h" 37 #include "net/cert/cert_database.h"
34 #include "net/cert/nss_cert_database.h" 38 #include "net/cert/nss_cert_database.h"
35 #include "net/cert/x509_certificate.h" 39 #include "net/cert/x509_certificate.h"
40 #include "net/cert/x509_util_nss.h"
36 #include "net/ssl/client_cert_store_chromeos.h" 41 #include "net/ssl/client_cert_store_chromeos.h"
37 #include "net/ssl/ssl_cert_request_info.h" 42 #include "net/ssl/ssl_cert_request_info.h"
38 43
39 using content::BrowserContext; 44 using content::BrowserContext;
40 using content::BrowserThread; 45 using content::BrowserThread;
41 46
42 namespace { 47 namespace {
43 const char kErrorInternal[] = "Internal Error."; 48 const char kErrorInternal[] = "Internal Error.";
44 const char kErrorKeyNotFound[] = "Key not found."; 49 const char kErrorKeyNotFound[] = "Key not found.";
45 const char kErrorCertificateNotFound[] = "Certificate could not be found."; 50 const char kErrorCertificateNotFound[] = "Certificate could not be found.";
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 from, base::Bind(callback_, public_key_spki_der, error_message)); 166 from, base::Bind(callback_, public_key_spki_der, error_message));
162 } 167 }
163 168
164 const unsigned int modulus_length_bits_; 169 const unsigned int modulus_length_bits_;
165 170
166 private: 171 private:
167 // Must be called on origin thread, therefore use CallBack(). 172 // Must be called on origin thread, therefore use CallBack().
168 subtle::GenerateKeyCallback callback_; 173 subtle::GenerateKeyCallback callback_;
169 }; 174 };
170 175
171 class SignState : public NSSOperationState { 176 class SignRSAState : public NSSOperationState {
172 public: 177 public:
173 SignState(const std::string& public_key, 178 SignRSAState(const std::string& data,
174 HashAlgorithm hash_algorithm, 179 const std::string& public_key,
175 const std::string& data, 180 bool sign_direct_pkcs_padded,
176 const subtle::SignCallback& callback); 181 HashAlgorithm hash_algorithm,
177 ~SignState() override {} 182 const subtle::SignCallback& callback);
183 ~SignRSAState() override {}
178 184
179 void OnError(const tracked_objects::Location& from, 185 void OnError(const tracked_objects::Location& from,
180 const std::string& error_message) override { 186 const std::string& error_message) override {
181 CallBack(from, std::string() /* no signature */, error_message); 187 CallBack(from, std::string() /* no signature */, error_message);
182 } 188 }
183 189
184 void CallBack(const tracked_objects::Location& from, 190 void CallBack(const tracked_objects::Location& from,
185 const std::string& signature, 191 const std::string& signature,
186 const std::string& error_message) { 192 const std::string& error_message) {
187 origin_task_runner_->PostTask( 193 origin_task_runner_->PostTask(
188 from, base::Bind(callback_, signature, error_message)); 194 from, base::Bind(callback_, signature, error_message));
189 } 195 }
190 196
197 // The data that will be signed.
198 const std::string data_;
199
200 // Must be the DER encoding of a SubjectPublicKeyInfo.
191 const std::string public_key_; 201 const std::string public_key_;
192 HashAlgorithm hash_algorithm_; 202
193 const std::string data_; 203 // If true, |data_| will not be hashed before signing. Only PKCS#1 v1.5
204 // padding will be applied before signing.
205 // If false, |hash_algorithm_| must be set to a value != NONE.
206 const bool sign_direct_pkcs_padded_;
207
208 // Determines the hash algorithm that is used to digest |data| before signing.
209 // Ignored if |sign_direct_pkcs_padded_| is true.
210 const HashAlgorithm hash_algorithm_;
194 211
195 private: 212 private:
196 // Must be called on origin thread, therefore use CallBack(). 213 // Must be called on origin thread, therefore use CallBack().
197 subtle::SignCallback callback_; 214 subtle::SignCallback callback_;
198 }; 215 };
199 216
200 class SelectCertificatesState : public NSSOperationState { 217 class SelectCertificatesState : public NSSOperationState {
201 public: 218 public:
202 explicit SelectCertificatesState( 219 explicit SelectCertificatesState(
203 const std::string& username_hash, 220 const std::string& username_hash,
204 const bool use_system_key_slot, 221 const bool use_system_key_slot,
205 scoped_refptr<net::SSLCertRequestInfo> request, 222 const scoped_refptr<net::SSLCertRequestInfo>& request,
206 const subtle::SelectCertificatesCallback& callback); 223 const subtle::SelectCertificatesCallback& callback);
207 ~SelectCertificatesState() override {} 224 ~SelectCertificatesState() override {}
208 225
209 void OnError(const tracked_objects::Location& from, 226 void OnError(const tracked_objects::Location& from,
210 const std::string& error_message) override { 227 const std::string& error_message) override {
211 CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */, 228 CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */,
212 error_message); 229 error_message);
213 } 230 }
214 231
215 void CallBack(const tracked_objects::Location& from, 232 void CallBack(const tracked_objects::Location& from,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 268
252 scoped_ptr<net::CertificateList> certs_; 269 scoped_ptr<net::CertificateList> certs_;
253 270
254 private: 271 private:
255 // Must be called on origin thread, therefore use CallBack(). 272 // Must be called on origin thread, therefore use CallBack().
256 GetCertificatesCallback callback_; 273 GetCertificatesCallback callback_;
257 }; 274 };
258 275
259 class ImportCertificateState : public NSSOperationState { 276 class ImportCertificateState : public NSSOperationState {
260 public: 277 public:
261 ImportCertificateState(scoped_refptr<net::X509Certificate> certificate, 278 ImportCertificateState(const scoped_refptr<net::X509Certificate>& certificate,
262 const ImportCertificateCallback& callback); 279 const ImportCertificateCallback& callback);
263 ~ImportCertificateState() override {} 280 ~ImportCertificateState() override {}
264 281
265 void OnError(const tracked_objects::Location& from, 282 void OnError(const tracked_objects::Location& from,
266 const std::string& error_message) override { 283 const std::string& error_message) override {
267 CallBack(from, error_message); 284 CallBack(from, error_message);
268 } 285 }
269 286
270 void CallBack(const tracked_objects::Location& from, 287 void CallBack(const tracked_objects::Location& from,
271 const std::string& error_message) { 288 const std::string& error_message) {
272 origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); 289 origin_task_runner_->PostTask(from, base::Bind(callback_, error_message));
273 } 290 }
274 291
275 scoped_refptr<net::X509Certificate> certificate_; 292 scoped_refptr<net::X509Certificate> certificate_;
276 293
277 private: 294 private:
278 // Must be called on origin thread, therefore use CallBack(). 295 // Must be called on origin thread, therefore use CallBack().
279 ImportCertificateCallback callback_; 296 ImportCertificateCallback callback_;
280 }; 297 };
281 298
282 class RemoveCertificateState : public NSSOperationState { 299 class RemoveCertificateState : public NSSOperationState {
283 public: 300 public:
284 RemoveCertificateState(scoped_refptr<net::X509Certificate> certificate, 301 RemoveCertificateState(const scoped_refptr<net::X509Certificate>& certificate,
285 const RemoveCertificateCallback& callback); 302 const RemoveCertificateCallback& callback);
286 ~RemoveCertificateState() override {} 303 ~RemoveCertificateState() override {}
287 304
288 void OnError(const tracked_objects::Location& from, 305 void OnError(const tracked_objects::Location& from,
289 const std::string& error_message) override { 306 const std::string& error_message) override {
290 CallBack(from, error_message); 307 CallBack(from, error_message);
291 } 308 }
292 309
293 void CallBack(const tracked_objects::Location& from, 310 void CallBack(const tracked_objects::Location& from,
294 const std::string& error_message) { 311 const std::string& error_message) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 NSSOperationState::NSSOperationState() 346 NSSOperationState::NSSOperationState()
330 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 347 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
331 } 348 }
332 349
333 GenerateRSAKeyState::GenerateRSAKeyState( 350 GenerateRSAKeyState::GenerateRSAKeyState(
334 unsigned int modulus_length_bits, 351 unsigned int modulus_length_bits,
335 const subtle::GenerateKeyCallback& callback) 352 const subtle::GenerateKeyCallback& callback)
336 : modulus_length_bits_(modulus_length_bits), callback_(callback) { 353 : modulus_length_bits_(modulus_length_bits), callback_(callback) {
337 } 354 }
338 355
339 SignState::SignState(const std::string& public_key, 356 SignRSAState::SignRSAState(const std::string& data,
340 HashAlgorithm hash_algorithm, 357 const std::string& public_key,
341 const std::string& data, 358 bool sign_direct_pkcs_padded,
342 const subtle::SignCallback& callback) 359 HashAlgorithm hash_algorithm,
343 : public_key_(public_key), 360 const subtle::SignCallback& callback)
361 : data_(data),
362 public_key_(public_key),
363 sign_direct_pkcs_padded_(sign_direct_pkcs_padded),
344 hash_algorithm_(hash_algorithm), 364 hash_algorithm_(hash_algorithm),
345 data_(data),
346 callback_(callback) { 365 callback_(callback) {
347 } 366 }
348 367
349 SelectCertificatesState::SelectCertificatesState( 368 SelectCertificatesState::SelectCertificatesState(
350 const std::string& username_hash, 369 const std::string& username_hash,
351 const bool use_system_key_slot, 370 const bool use_system_key_slot,
352 scoped_refptr<net::SSLCertRequestInfo> cert_request_info, 371 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info,
353 const subtle::SelectCertificatesCallback& callback) 372 const subtle::SelectCertificatesCallback& callback)
354 : username_hash_(username_hash), 373 : username_hash_(username_hash),
355 use_system_key_slot_(use_system_key_slot), 374 use_system_key_slot_(use_system_key_slot),
356 cert_request_info_(cert_request_info), 375 cert_request_info_(cert_request_info),
357 callback_(callback) { 376 callback_(callback) {
358 } 377 }
359 378
360 GetCertificatesState::GetCertificatesState( 379 GetCertificatesState::GetCertificatesState(
361 const GetCertificatesCallback& callback) 380 const GetCertificatesCallback& callback)
362 : callback_(callback) { 381 : callback_(callback) {
363 } 382 }
364 383
365 ImportCertificateState::ImportCertificateState( 384 ImportCertificateState::ImportCertificateState(
366 scoped_refptr<net::X509Certificate> certificate, 385 const scoped_refptr<net::X509Certificate>& certificate,
367 const ImportCertificateCallback& callback) 386 const ImportCertificateCallback& callback)
368 : certificate_(certificate), callback_(callback) { 387 : certificate_(certificate), callback_(callback) {
369 } 388 }
370 389
371 RemoveCertificateState::RemoveCertificateState( 390 RemoveCertificateState::RemoveCertificateState(
372 scoped_refptr<net::X509Certificate> certificate, 391 const scoped_refptr<net::X509Certificate>& certificate,
373 const RemoveCertificateCallback& callback) 392 const RemoveCertificateCallback& callback)
374 : certificate_(certificate), callback_(callback) { 393 : certificate_(certificate), callback_(callback) {
375 } 394 }
376 395
377 GetTokensState::GetTokensState(const GetTokensCallback& callback) 396 GetTokensState::GetTokensState(const GetTokensCallback& callback)
378 : callback_(callback) { 397 : callback_(callback) {
379 } 398 }
380 399
381 // Does the actual key generation on a worker thread. Used by 400 // Does the actual key generation on a worker thread. Used by
382 // GenerateRSAKeyWithDB(). 401 // GenerateRSAKeyWithDB().
(...skipping 25 matching lines...) Expand all
408 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, 427 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state,
409 net::NSSCertDatabase* cert_db) { 428 net::NSSCertDatabase* cert_db) {
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
411 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 430 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|.
412 base::WorkerPool::PostTask( 431 base::WorkerPool::PostTask(
413 FROM_HERE, 432 FROM_HERE,
414 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), 433 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)),
415 true /*task is slow*/); 434 true /*task is slow*/);
416 } 435 }
417 436
418 // Does the actual signing on a worker thread. Used by RSASignWithDB(). 437 // Does the actual signing on a worker thread. Used by SignRSAWithDB().
419 void RSASignOnWorkerThread(scoped_ptr<SignState> state) { 438 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
420 const uint8* public_key_uint8 = 439 const uint8* public_key_uint8 =
421 reinterpret_cast<const uint8*>(state->public_key_.data()); 440 reinterpret_cast<const uint8*>(state->public_key_.data());
422 std::vector<uint8> public_key_vector( 441 std::vector<uint8> public_key_vector(
423 public_key_uint8, public_key_uint8 + state->public_key_.size()); 442 public_key_uint8, public_key_uint8 + state->public_key_.size());
424 443
425 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. 444 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|.
426 scoped_ptr<crypto::RSAPrivateKey> rsa_key( 445 scoped_ptr<crypto::RSAPrivateKey> rsa_key(
427 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); 446 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector));
428 if (!rsa_key || rsa_key->key()->pkcs11Slot != state->slot_) { 447
448 // Fail if the key was not found. If a specific slot was requested, also fail
449 // if the key was found in the wrong slot.
450 if (!rsa_key ||
451 (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) {
429 state->OnError(FROM_HERE, kErrorKeyNotFound); 452 state->OnError(FROM_HERE, kErrorKeyNotFound);
430 return; 453 return;
431 } 454 }
432 455
433 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; 456 std::string signature_str;
434 switch (state->hash_algorithm_) { 457 if (state->sign_direct_pkcs_padded_) {
435 case HASH_ALGORITHM_SHA1: 458 static_assert(
436 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 459 sizeof(*state->data_.data()) == sizeof(char),
437 break; 460 "Can't reinterpret data if it's characters are not 8 bit large.");
Ryan Sleevi 2015/02/13 03:24:28 C++03, Section 5.3.3, p1 sizeof(char), sizeof(sig
pneubeck (no reviews) 2015/02/13 05:52:20 This check was meant to trigger in case someone ch
438 case HASH_ALGORITHM_SHA256: 461 SECItem input = {siBuffer,
439 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 462 reinterpret_cast<unsigned char*>(
440 break; 463 const_cast<char*>(state->data_.data())),
441 case HASH_ALGORITHM_SHA384: 464 state->data_.size()};
442 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 465
443 break; 466 // Compute signature of hash.
444 case HASH_ALGORITHM_SHA512: 467 int signature_len = PK11_SignatureLen(rsa_key->key());
445 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 468 if (signature_len <= 0) {
446 break; 469 state->OnError(FROM_HERE, kErrorInternal);
470 return;
471 }
472
473 std::vector<unsigned char> signature(signature_len);
474 SECItem signature_output = {
475 siBuffer, vector_as_array(&signature), signature.size()};
476 if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess)
477 signature_str.assign(signature.begin(), signature.end());
478 } else {
479 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN;
480 switch (state->hash_algorithm_) {
481 case HASH_ALGORITHM_SHA1:
482 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
483 break;
484 case HASH_ALGORITHM_SHA256:
485 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
486 break;
487 case HASH_ALGORITHM_SHA384:
488 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
489 break;
490 case HASH_ALGORITHM_SHA512:
491 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
492 break;
493 case HASH_ALGORITHM_NONE:
494 NOTREACHED();
495 break;
496 }
497
498 SECItem sign_result = {siBuffer, nullptr, 0};
499 if (SEC_SignData(
500 &sign_result,
501 reinterpret_cast<const unsigned char*>(state->data_.data()),
502 state->data_.size(), rsa_key->key(), sign_alg_tag) == SECSuccess) {
503 signature_str.assign(sign_result.data,
504 sign_result.data + sign_result.len);
505 }
447 } 506 }
448 507
449 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0)); 508 if (signature_str.empty()) {
450 if (SEC_SignData(sign_result.get(),
451 reinterpret_cast<const unsigned char*>(state->data_.data()),
452 state->data_.size(),
453 rsa_key->key(),
454 sign_alg_tag) != SECSuccess) {
455 LOG(ERROR) << "Couldn't sign."; 509 LOG(ERROR) << "Couldn't sign.";
456 state->OnError(FROM_HERE, kErrorInternal); 510 state->OnError(FROM_HERE, kErrorInternal);
457 return; 511 return;
458 } 512 }
459 513
460 std::string signature(reinterpret_cast<const char*>(sign_result->data), 514 state->CallBack(FROM_HERE, signature_str, std::string() /* no error */);
461 sign_result->len);
462 state->CallBack(FROM_HERE, signature, std::string() /* no error */);
463 } 515 }
464 516
465 // Continues signing with the obtained NSSCertDatabase. Used by Sign(). 517 // Continues signing with the obtained NSSCertDatabase. Used by Sign().
466 void RSASignWithDB(scoped_ptr<SignState> state, net::NSSCertDatabase* cert_db) { 518 void SignRSAWithDB(scoped_ptr<SignRSAState> state,
519 net::NSSCertDatabase* cert_db) {
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
468 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 521 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|.
469 base::WorkerPool::PostTask( 522 base::WorkerPool::PostTask(
470 FROM_HERE, 523 FROM_HERE, base::Bind(&SignRSAOnWorkerThread, base::Passed(&state)),
471 base::Bind(&RSASignOnWorkerThread, base::Passed(&state)),
472 true /*task is slow*/); 524 true /*task is slow*/);
473 } 525 }
474 526
475 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list 527 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list
476 // of net::CertificateList and calls back. Used by 528 // of net::CertificateList and calls back. Used by
477 // SelectCertificatesOnIOThread(). 529 // SelectCertificatesOnIOThread().
478 void DidSelectCertificatesOnIOThread( 530 void DidSelectCertificatesOnIOThread(
479 scoped_ptr<SelectCertificatesState> state) { 531 scoped_ptr<SelectCertificatesState> state) {
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
481 state->CallBack(FROM_HERE, state->certs_.Pass(), 533 state->CallBack(FROM_HERE, state->certs_.Pass(),
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 700 }
649 701
650 // Get the pointer to |state| before base::Passed releases |state|. 702 // Get the pointer to |state| before base::Passed releases |state|.
651 NSSOperationState* state_ptr = state.get(); 703 NSSOperationState* state_ptr = state.get();
652 GetCertDatabase(token_id, 704 GetCertDatabase(token_id,
653 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), 705 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)),
654 browser_context, 706 browser_context,
655 state_ptr); 707 state_ptr);
656 } 708 }
657 709
658 void Sign(const std::string& token_id, 710 void SignRSAPKCS1Digest(const std::string& token_id,
659 const std::string& public_key, 711 const std::string& data,
660 HashAlgorithm hash_algorithm, 712 const std::string& public_key,
661 const std::string& data, 713 HashAlgorithm hash_algorithm,
662 const SignCallback& callback, 714 const SignCallback& callback,
663 BrowserContext* browser_context) { 715 content::BrowserContext* browser_context) {
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
665 scoped_ptr<SignState> state( 717 scoped_ptr<SignRSAState> state(
666 new SignState(public_key, hash_algorithm, data, callback)); 718 new SignRSAState(data, public_key, false /* digest before signing */,
719 hash_algorithm, callback));
667 // Get the pointer to |state| before base::Passed releases |state|. 720 // Get the pointer to |state| before base::Passed releases |state|.
668 NSSOperationState* state_ptr = state.get(); 721 NSSOperationState* state_ptr = state.get();
669 722
670 // The NSSCertDatabase object is not required. But in case it's not available 723 // The NSSCertDatabase object is not required. But in case it's not available
671 // we would get more informative error messages and we can double check that 724 // we would get more informative error messages and we can double check that
672 // we use a key of the correct token. 725 // we use a key of the correct token.
673 GetCertDatabase(token_id, 726 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)),
674 base::Bind(&RSASignWithDB, base::Passed(&state)), 727 browser_context, state_ptr);
675 browser_context, 728 }
676 state_ptr); 729
730 void SignRSAPKCS1Raw(const std::string& token_id,
731 const std::string& data,
732 const std::string& public_key,
733 const SignCallback& callback,
734 content::BrowserContext* browser_context) {
735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
736 scoped_ptr<SignRSAState> state(new SignRSAState(
737 data, public_key, true /* sign directly without hashing */,
738 HASH_ALGORITHM_NONE, callback));
739 // Get the pointer to |state| before base::Passed releases |state|.
740 NSSOperationState* state_ptr = state.get();
741
742 // The NSSCertDatabase object is not required. But in case it's not available
743 // we would get more informative error messages and we can double check that
744 // we use a key of the correct token.
745 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)),
746 browser_context, state_ptr);
677 } 747 }
678 748
679 void SelectClientCertificates(const ClientCertificateRequest& request, 749 void SelectClientCertificates(const ClientCertificateRequest& request,
680 const SelectCertificatesCallback& callback, 750 const SelectCertificatesCallback& callback,
681 content::BrowserContext* browser_context) { 751 content::BrowserContext* browser_context) {
682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
683 753
684 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( 754 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
685 new net::SSLCertRequestInfo); 755 new net::SSLCertRequestInfo);
686 cert_request_info->cert_key_types = request.certificate_key_types; 756 cert_request_info->cert_key_types = request.certificate_key_types;
(...skipping 12 matching lines...) Expand all
699 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( 769 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState(
700 user->username_hash(), use_system_key_slot, cert_request_info, callback)); 770 user->username_hash(), use_system_key_slot, cert_request_info, callback));
701 771
702 BrowserThread::PostTask( 772 BrowserThread::PostTask(
703 BrowserThread::IO, FROM_HERE, 773 BrowserThread::IO, FROM_HERE,
704 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); 774 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state)));
705 } 775 }
706 776
707 } // namespace subtle 777 } // namespace subtle
708 778
779 bool GetPublicKey(const scoped_refptr<net::X509Certificate>& certificate,
780 std::string* public_key_spki_der,
781 net::X509Certificate::PublicKeyType* key_type,
782 size_t* key_size_bits) {
783 CHECK(public_key_spki_der);
784 CHECK(key_type);
785 CHECK(key_size_bits);
Ryan Sleevi 2015/02/13 03:24:28 jschuh has advised me in the past to explicitly re
pneubeck (no reviews) 2015/02/14 13:25:14 Done.
786 const SECItem& spki_der = certificate->os_cert_handle()->derPublicKey;
787
788 net::X509Certificate::PublicKeyType key_type_tmp =
789 net::X509Certificate::kPublicKeyTypeUnknown;
790 size_t key_size_bits_tmp = 0;
791 net::X509Certificate::GetPublicKeyInfo(certificate->os_cert_handle(),
792 &key_size_bits_tmp, &key_type_tmp);
793
794 if (key_type_tmp == net::X509Certificate::kPublicKeyTypeUnknown) {
795 LOG(WARNING) << "Could not extract public key of certificate.";
796 return false;
797 }
798 if (key_type_tmp != net::X509Certificate::kPublicKeyTypeRSA) {
799 LOG(WARNING) << "Keys of other type than RSA are not supported.";
800 return false;
801 }
802
803 crypto::ScopedSECKEYPublicKey public_key(
804 CERT_ExtractPublicKey(certificate->os_cert_handle()));
805 if (!public_key) {
806 LOG(WARNING) << "Could not extract public key of certificate.";
807 return false;
808 }
809 long public_exponent = DER_GetInteger(&public_key->u.rsa.publicExponent);
810 if (public_exponent != 65537L) {
811 LOG(ERROR) << "Rejecting RSA public exponent that is unequal 65537.";
812 return false;
813 }
814
815 public_key_spki_der->assign(spki_der.data, spki_der.data + spki_der.len);
816 *key_type = key_type_tmp;
817 *key_size_bits = key_size_bits_tmp;
818
819 return true;
820 }
821
709 void GetCertificates(const std::string& token_id, 822 void GetCertificates(const std::string& token_id,
710 const GetCertificatesCallback& callback, 823 const GetCertificatesCallback& callback,
711 BrowserContext* browser_context) { 824 BrowserContext* browser_context) {
712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 825 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
713 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); 826 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback));
714 // Get the pointer to |state| before base::Passed releases |state|. 827 // Get the pointer to |state| before base::Passed releases |state|.
715 NSSOperationState* state_ptr = state.get(); 828 NSSOperationState* state_ptr = state.get();
716 GetCertDatabase(token_id, 829 GetCertDatabase(token_id,
717 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), 830 base::Bind(&GetCertificatesWithDB, base::Passed(&state)),
718 browser_context, 831 browser_context,
719 state_ptr); 832 state_ptr);
720 } 833 }
721 834
722 void ImportCertificate(const std::string& token_id, 835 void ImportCertificate(const std::string& token_id,
723 scoped_refptr<net::X509Certificate> certificate, 836 const scoped_refptr<net::X509Certificate>& certificate,
724 const ImportCertificateCallback& callback, 837 const ImportCertificateCallback& callback,
725 BrowserContext* browser_context) { 838 BrowserContext* browser_context) {
726 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 839 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
727 scoped_ptr<ImportCertificateState> state( 840 scoped_ptr<ImportCertificateState> state(
728 new ImportCertificateState(certificate, callback)); 841 new ImportCertificateState(certificate, callback));
729 // Get the pointer to |state| before base::Passed releases |state|. 842 // Get the pointer to |state| before base::Passed releases |state|.
730 NSSOperationState* state_ptr = state.get(); 843 NSSOperationState* state_ptr = state.get();
731 844
732 // The NSSCertDatabase object is not required. But in case it's not available 845 // The NSSCertDatabase object is not required. But in case it's not available
733 // we would get more informative error messages and we can double check that 846 // we would get more informative error messages and we can double check that
734 // we use a key of the correct token. 847 // we use a key of the correct token.
735 GetCertDatabase(token_id, 848 GetCertDatabase(token_id,
736 base::Bind(&ImportCertificateWithDB, base::Passed(&state)), 849 base::Bind(&ImportCertificateWithDB, base::Passed(&state)),
737 browser_context, 850 browser_context,
738 state_ptr); 851 state_ptr);
739 } 852 }
740 853
741 void RemoveCertificate(const std::string& token_id, 854 void RemoveCertificate(const std::string& token_id,
742 scoped_refptr<net::X509Certificate> certificate, 855 const scoped_refptr<net::X509Certificate>& certificate,
743 const RemoveCertificateCallback& callback, 856 const RemoveCertificateCallback& callback,
744 BrowserContext* browser_context) { 857 BrowserContext* browser_context) {
745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
746 scoped_ptr<RemoveCertificateState> state( 859 scoped_ptr<RemoveCertificateState> state(
747 new RemoveCertificateState(certificate, callback)); 860 new RemoveCertificateState(certificate, callback));
748 // Get the pointer to |state| before base::Passed releases |state|. 861 // Get the pointer to |state| before base::Passed releases |state|.
749 NSSOperationState* state_ptr = state.get(); 862 NSSOperationState* state_ptr = state.get();
750 863
751 // The NSSCertDatabase object is not required. But in case it's not available 864 // The NSSCertDatabase object is not required. But in case it's not available
752 // we would get more informative error messages. 865 // we would get more informative error messages.
(...skipping 11 matching lines...) Expand all
764 NSSOperationState* state_ptr = state.get(); 877 NSSOperationState* state_ptr = state.get();
765 GetCertDatabase(std::string() /* don't get any specific slot */, 878 GetCertDatabase(std::string() /* don't get any specific slot */,
766 base::Bind(&GetTokensWithDB, base::Passed(&state)), 879 base::Bind(&GetTokensWithDB, base::Passed(&state)),
767 browser_context, 880 browser_context,
768 state_ptr); 881 state_ptr);
769 } 882 }
770 883
771 } // namespace platform_keys 884 } // namespace platform_keys
772 885
773 } // namespace chromeos 886 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/platform_keys/platform_keys.h ('k') | chrome/browser/chromeos/platform_keys/platform_keys_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698