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

Side by Side Diff: chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.cc

Issue 1106103003: Don't use RSAPrivateKey in NSS integration code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ocsp-refactor
Patch Set: avoid exposing NSS through net headers (unnecessary) Created 5 years, 8 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/login/easy_unlock/easy_unlock_tpm_key_manager. h" 5 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager. h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <keyhi.h>
8 9
9 #include "base/base64.h" 10 #include "base/base64.h"
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/location.h" 12 #include "base/location.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
14 #include "base/prefs/pref_registry_simple.h" 15 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/pref_service.h" 16 #include "base/prefs/pref_service.h"
16 #include "base/prefs/scoped_user_pref_update.h" 17 #include "base/prefs/scoped_user_pref_update.h"
17 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
18 #include "base/thread_task_runner_handle.h" 19 #include "base/thread_task_runner_handle.h"
19 #include "base/threading/worker_pool.h" 20 #include "base/threading/worker_pool.h"
20 #include "base/time/time.h" 21 #include "base/time/time.h"
21 #include "base/values.h" 22 #include "base/values.h"
22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
23 #include "chrome/common/pref_names.h" 24 #include "chrome/common/pref_names.h"
24 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "crypto/nss_key_util.h"
25 #include "crypto/nss_util_internal.h" 27 #include "crypto/nss_util_internal.h"
26 #include "crypto/rsa_private_key.h"
27 #include "crypto/scoped_nss_types.h" 28 #include "crypto/scoped_nss_types.h"
28 29
29 namespace { 30 namespace {
30 31
31 // The modulus length for RSA keys used by easy sign-in. 32 // The modulus length for RSA keys used by easy sign-in.
32 const int kKeyModulusLength = 2048; 33 const int kKeyModulusLength = 2048;
33 34
34 // Relays |GetSystemSlotOnIOThread| callback to |response_task_runner|. 35 // Relays |GetSystemSlotOnIOThread| callback to |response_task_runner|.
35 void RunCallbackOnThreadRunner( 36 void RunCallbackOnThreadRunner(
36 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, 37 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
(...skipping 13 matching lines...) Expand all
50 51
51 crypto::ScopedPK11Slot system_slot = 52 crypto::ScopedPK11Slot system_slot =
52 crypto::GetSystemNSSKeySlot(callback_on_origin_thread); 53 crypto::GetSystemNSSKeySlot(callback_on_origin_thread);
53 if (system_slot) 54 if (system_slot)
54 callback_on_origin_thread.Run(system_slot.Pass()); 55 callback_on_origin_thread.Run(system_slot.Pass());
55 } 56 }
56 57
57 // Checks if a private RSA key associated with |public_key| can be found in 58 // Checks if a private RSA key associated with |public_key| can be found in
58 // |slot|. 59 // |slot|.
59 // Must be called on a worker thread. 60 // Must be called on a worker thread.
60 scoped_ptr<crypto::RSAPrivateKey> GetPrivateKeyOnWorkerThread( 61 crypto::ScopedSECKEYPrivateKey GetPrivateKeyOnWorkerThread(
61 PK11SlotInfo* slot, 62 PK11SlotInfo* slot,
62 const std::string& public_key) { 63 const std::string& public_key) {
63 const uint8* public_key_uint8 = 64 const uint8* public_key_uint8 =
64 reinterpret_cast<const uint8*>(public_key.data()); 65 reinterpret_cast<const uint8*>(public_key.data());
65 std::vector<uint8> public_key_vector( 66 std::vector<uint8> public_key_vector(
66 public_key_uint8, public_key_uint8 + public_key.size()); 67 public_key_uint8, public_key_uint8 + public_key.size());
67 68
68 scoped_ptr<crypto::RSAPrivateKey> rsa_key( 69 crypto::ScopedSECKEYPrivateKey rsa_key(
69 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); 70 crypto::FindNSSKeyFromPublicKeyInfoInSlot(public_key_vector, slot));
70 if (!rsa_key || rsa_key->key()->pkcs11Slot != slot) 71 if (!rsa_key || SECKEY_GetPrivateKeyType(rsa_key.get()) != rsaKey)
71 return scoped_ptr<crypto::RSAPrivateKey>(); 72 return nullptr;
72 return rsa_key.Pass(); 73 return rsa_key.Pass();
73 } 74 }
74 75
75 // Signs |data| using a private key associated with |public_key| and stored in 76 // Signs |data| using a private key associated with |public_key| and stored in
76 // |slot|. Once the data is signed, callback is run on |response_task_runner|. 77 // |slot|. Once the data is signed, callback is run on |response_task_runner|.
77 // In case of an error, the callback will be passed an empty string. 78 // In case of an error, the callback will be passed an empty string.
78 void SignDataOnWorkerThread( 79 void SignDataOnWorkerThread(
79 crypto::ScopedPK11Slot slot, 80 crypto::ScopedPK11Slot slot,
80 const std::string& public_key, 81 const std::string& public_key,
81 const std::string& data, 82 const std::string& data,
82 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, 83 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
83 const base::Callback<void(const std::string&)>& callback) { 84 const base::Callback<void(const std::string&)>& callback) {
84 scoped_ptr<crypto::RSAPrivateKey> private_key( 85 crypto::ScopedSECKEYPrivateKey private_key(
85 GetPrivateKeyOnWorkerThread(slot.get(), public_key)); 86 GetPrivateKeyOnWorkerThread(slot.get(), public_key));
86 if (!private_key) { 87 if (!private_key) {
87 LOG(ERROR) << "Private key for signing data not found"; 88 LOG(ERROR) << "Private key for signing data not found";
88 response_task_runner->PostTask(FROM_HERE, 89 response_task_runner->PostTask(FROM_HERE,
89 base::Bind(callback, std::string())); 90 base::Bind(callback, std::string()));
90 return; 91 return;
91 } 92 }
92 93
93 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0)); 94 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0));
94 if (SEC_SignData(sign_result.get(), 95 if (SEC_SignData(sign_result.get(),
95 reinterpret_cast<const unsigned char*>(data.data()), 96 reinterpret_cast<const unsigned char*>(data.data()),
96 data.size(), 97 data.size(), private_key.get(),
97 private_key->key(),
98 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION) != SECSuccess) { 98 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION) != SECSuccess) {
99 LOG(ERROR) << "Failed to sign data"; 99 LOG(ERROR) << "Failed to sign data";
100 response_task_runner->PostTask(FROM_HERE, 100 response_task_runner->PostTask(FROM_HERE,
101 base::Bind(callback, std::string())); 101 base::Bind(callback, std::string()));
102 return; 102 return;
103 } 103 }
104 104
105 std::string signature(reinterpret_cast<const char*>(sign_result->data), 105 std::string signature(reinterpret_cast<const char*>(sign_result->data),
106 sign_result->len); 106 sign_result->len);
107 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, signature)); 107 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, signature));
108 } 108 }
109 109
110 // Creates a RSA key pair in |slot|. When done, it runs |callback| with the 110 // Creates a RSA key pair in |slot|. When done, it runs |callback| with the
111 // created public key on |response_task_runner|. 111 // created public key on |response_task_runner|.
112 // If |public_key| is not empty, a key pair will be created only if the private 112 // If |public_key| is not empty, a key pair will be created only if the private
113 // key associated with |public_key| does not exist in |slot|. Otherwise the 113 // key associated with |public_key| does not exist in |slot|. Otherwise the
114 // callback will be run with |public_key|. 114 // callback will be run with |public_key|.
115 void CreateTpmKeyPairOnWorkerThread( 115 void CreateTpmKeyPairOnWorkerThread(
116 crypto::ScopedPK11Slot slot, 116 crypto::ScopedPK11Slot slot,
117 const std::string& public_key, 117 const std::string& public_key,
118 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, 118 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
119 const base::Callback<void(const std::string&)>& callback) { 119 const base::Callback<void(const std::string&)>& callback) {
120 if (!public_key.empty() && 120 if (!public_key.empty() &&
121 GetPrivateKeyOnWorkerThread(slot.get(), public_key)) { 121 GetPrivateKeyOnWorkerThread(slot.get(), public_key)) {
122 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, public_key)); 122 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, public_key));
123 return; 123 return;
124 } 124 }
125 125
126 scoped_ptr<crypto::RSAPrivateKey> rsa_key( 126 crypto::ScopedSECKEYPublicKey public_key_obj;
127 crypto::RSAPrivateKey::CreateSensitive(slot.get(), kKeyModulusLength)); 127 crypto::ScopedSECKEYPrivateKey private_key;
Ryan Sleevi 2015/04/27 19:11:26 Why the different naming? public_key_obj vs privat
davidben 2015/04/27 19:53:44 Done.
128 if (!rsa_key) { 128 if (!crypto::GenerateRSAKeyPairNSS(slot.get(), kKeyModulusLength,
129 true /* permanent */, &public_key_obj,
130 &private_key)) {
129 LOG(ERROR) << "Failed to create an RSA key."; 131 LOG(ERROR) << "Failed to create an RSA key.";
130 response_task_runner->PostTask(FROM_HERE, 132 response_task_runner->PostTask(FROM_HERE,
131 base::Bind(callback, std::string())); 133 base::Bind(callback, std::string()));
132 return; 134 return;
133 } 135 }
134 136
135 std::vector<uint8> created_public_key; 137 crypto::ScopedSECItem created_public_key(
Ryan Sleevi 2015/04/27 19:11:26 seems like this should be named like public_key_de
davidben 2015/04/27 19:53:44 Done.
136 if (!rsa_key->ExportPublicKey(&created_public_key)) { 138 SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_obj.get()));
139 if (!created_public_key) {
137 LOG(ERROR) << "Failed to export public key."; 140 LOG(ERROR) << "Failed to export public key.";
138 response_task_runner->PostTask(FROM_HERE, 141 response_task_runner->PostTask(FROM_HERE,
139 base::Bind(callback, std::string())); 142 base::Bind(callback, std::string()));
140 return; 143 return;
141 } 144 }
142 145
143 response_task_runner->PostTask( 146 response_task_runner->PostTask(
144 FROM_HERE, 147 FROM_HERE, base::Bind(callback, std::string(reinterpret_cast<const char*>(
145 base::Bind(callback, 148 created_public_key->data),
146 std::string(created_public_key.begin(), 149 created_public_key->len)));
147 created_public_key.end())));
148 } 150 }
149 151
150 } // namespace 152 } // namespace
151 153
152 // static 154 // static
153 void EasyUnlockTpmKeyManager::RegisterLocalStatePrefs( 155 void EasyUnlockTpmKeyManager::RegisterLocalStatePrefs(
154 PrefRegistrySimple* registry) { 156 PrefRegistrySimple* registry) {
155 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateTpmKeys); 157 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateTpmKeys);
156 } 158 }
157 159
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // If key creation failed, reset the state machine. 348 // If key creation failed, reset the state machine.
347 create_tpm_key_state_ = 349 create_tpm_key_state_ =
348 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE; 350 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE;
349 } 351 }
350 352
351 void EasyUnlockTpmKeyManager::OnDataSigned( 353 void EasyUnlockTpmKeyManager::OnDataSigned(
352 const base::Callback<void(const std::string&)>& callback, 354 const base::Callback<void(const std::string&)>& callback,
353 const std::string& signature) { 355 const std::string& signature) {
354 callback.Run(signature); 356 callback.Run(signature);
355 } 357 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698