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

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

Issue 1128153003: Reland "Don't use RSAPrivateKey in NSS integration code." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: various comments, fix test Created 5 years, 7 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::FindNSSKeyFromPublicKeyInfo(public_key_vector));
70 if (!rsa_key || rsa_key->key()->pkcs11Slot != slot) 71 if (!rsa_key || rsa_key->pkcs11Slot != slot ||
71 return scoped_ptr<crypto::RSAPrivateKey>(); 72 SECKEY_GetPrivateKeyType(rsa_key.get()) != rsaKey) {
73 return nullptr;
74 }
Ryan Sleevi 2015/05/08 00:11:52 Seems like there should be a TODO here - |slot| sh
davidben 2015/05/09 00:41:55 Done. It's kinda a silly TODO, but I don't want to
72 return rsa_key.Pass(); 75 return rsa_key.Pass();
73 } 76 }
74 77
75 // Signs |data| using a private key associated with |public_key| and stored in 78 // 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|. 79 // |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. 80 // In case of an error, the callback will be passed an empty string.
78 void SignDataOnWorkerThread( 81 void SignDataOnWorkerThread(
79 crypto::ScopedPK11Slot slot, 82 crypto::ScopedPK11Slot slot,
80 const std::string& public_key, 83 const std::string& public_key,
81 const std::string& data, 84 const std::string& data,
82 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, 85 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
83 const base::Callback<void(const std::string&)>& callback) { 86 const base::Callback<void(const std::string&)>& callback) {
84 scoped_ptr<crypto::RSAPrivateKey> private_key( 87 crypto::ScopedSECKEYPrivateKey private_key(
85 GetPrivateKeyOnWorkerThread(slot.get(), public_key)); 88 GetPrivateKeyOnWorkerThread(slot.get(), public_key));
86 if (!private_key) { 89 if (!private_key) {
87 LOG(ERROR) << "Private key for signing data not found"; 90 LOG(ERROR) << "Private key for signing data not found";
88 response_task_runner->PostTask(FROM_HERE, 91 response_task_runner->PostTask(FROM_HERE,
89 base::Bind(callback, std::string())); 92 base::Bind(callback, std::string()));
90 return; 93 return;
91 } 94 }
92 95
93 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0)); 96 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0));
94 if (SEC_SignData(sign_result.get(), 97 if (SEC_SignData(sign_result.get(),
95 reinterpret_cast<const unsigned char*>(data.data()), 98 reinterpret_cast<const unsigned char*>(data.data()),
96 data.size(), 99 data.size(), private_key.get(),
97 private_key->key(),
98 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION) != SECSuccess) { 100 SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION) != SECSuccess) {
99 LOG(ERROR) << "Failed to sign data"; 101 LOG(ERROR) << "Failed to sign data";
100 response_task_runner->PostTask(FROM_HERE, 102 response_task_runner->PostTask(FROM_HERE,
101 base::Bind(callback, std::string())); 103 base::Bind(callback, std::string()));
102 return; 104 return;
103 } 105 }
104 106
105 std::string signature(reinterpret_cast<const char*>(sign_result->data), 107 std::string signature(reinterpret_cast<const char*>(sign_result->data),
106 sign_result->len); 108 sign_result->len);
107 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, signature)); 109 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, signature));
108 } 110 }
109 111
110 // Creates a RSA key pair in |slot|. When done, it runs |callback| with the 112 // Creates a RSA key pair in |slot|. When done, it runs |callback| with the
111 // created public key on |response_task_runner|. 113 // created public key on |response_task_runner|.
112 // If |public_key| is not empty, a key pair will be created only if the private 114 // 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 115 // key associated with |public_key| does not exist in |slot|. Otherwise the
114 // callback will be run with |public_key|. 116 // callback will be run with |public_key|.
115 void CreateTpmKeyPairOnWorkerThread( 117 void CreateTpmKeyPairOnWorkerThread(
116 crypto::ScopedPK11Slot slot, 118 crypto::ScopedPK11Slot slot,
117 const std::string& public_key, 119 const std::string& public_key,
118 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner, 120 const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
119 const base::Callback<void(const std::string&)>& callback) { 121 const base::Callback<void(const std::string&)>& callback) {
120 if (!public_key.empty() && 122 if (!public_key.empty() &&
121 GetPrivateKeyOnWorkerThread(slot.get(), public_key)) { 123 GetPrivateKeyOnWorkerThread(slot.get(), public_key)) {
122 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, public_key)); 124 response_task_runner->PostTask(FROM_HERE, base::Bind(callback, public_key));
123 return; 125 return;
124 } 126 }
125 127
126 scoped_ptr<crypto::RSAPrivateKey> rsa_key( 128 crypto::ScopedSECKEYPublicKey public_key_obj;
127 crypto::RSAPrivateKey::CreateSensitive(slot.get(), kKeyModulusLength)); 129 crypto::ScopedSECKEYPrivateKey private_key_obj;
128 if (!rsa_key) { 130 if (!crypto::GenerateRSAKeyPairNSS(slot.get(), kKeyModulusLength,
131 true /* permanent */, &public_key_obj,
132 &private_key_obj)) {
129 LOG(ERROR) << "Failed to create an RSA key."; 133 LOG(ERROR) << "Failed to create an RSA key.";
130 response_task_runner->PostTask(FROM_HERE, 134 response_task_runner->PostTask(FROM_HERE,
131 base::Bind(callback, std::string())); 135 base::Bind(callback, std::string()));
132 return; 136 return;
133 } 137 }
134 138
135 std::vector<uint8> created_public_key; 139 crypto::ScopedSECItem public_key_der(
136 if (!rsa_key->ExportPublicKey(&created_public_key)) { 140 SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_obj.get()));
141 if (!public_key_der) {
137 LOG(ERROR) << "Failed to export public key."; 142 LOG(ERROR) << "Failed to export public key.";
138 response_task_runner->PostTask(FROM_HERE, 143 response_task_runner->PostTask(FROM_HERE,
139 base::Bind(callback, std::string())); 144 base::Bind(callback, std::string()));
140 return; 145 return;
141 } 146 }
142 147
143 response_task_runner->PostTask( 148 response_task_runner->PostTask(
144 FROM_HERE, 149 FROM_HERE, base::Bind(callback, std::string(reinterpret_cast<const char*>(
145 base::Bind(callback, 150 public_key_der->data),
146 std::string(created_public_key.begin(), 151 public_key_der->len)));
147 created_public_key.end())));
148 } 152 }
149 153
150 } // namespace 154 } // namespace
151 155
152 // static 156 // static
153 void EasyUnlockTpmKeyManager::RegisterLocalStatePrefs( 157 void EasyUnlockTpmKeyManager::RegisterLocalStatePrefs(
154 PrefRegistrySimple* registry) { 158 PrefRegistrySimple* registry) {
155 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateTpmKeys); 159 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateTpmKeys);
156 } 160 }
157 161
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 // If key creation failed, reset the state machine. 350 // If key creation failed, reset the state machine.
347 create_tpm_key_state_ = 351 create_tpm_key_state_ =
348 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE; 352 public_key.empty() ? CREATE_TPM_KEY_NOT_STARTED : CREATE_TPM_KEY_DONE;
349 } 353 }
350 354
351 void EasyUnlockTpmKeyManager::OnDataSigned( 355 void EasyUnlockTpmKeyManager::OnDataSigned(
352 const base::Callback<void(const std::string&)>& callback, 356 const base::Callback<void(const std::string&)>& callback,
353 const std::string& signature) { 357 const std::string& signature) {
354 callback.Run(signature); 358 callback.Run(signature);
355 } 359 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698