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

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

Powered by Google App Engine
This is Rietveld 408576698