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

Side by Side Diff: chromeos/cryptohome/cryptohome_library.cc

Issue 14179007: Move cryptohome_library to src/chromeos (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/cros/cryptohome_library.h" 5 #include "chromeos/cryptohome/cryptohome_library.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/chromeos/chromeos_version.h"
10 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
11 #include "base/string_util.h" 12 #include "base/string_util.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "chromeos/dbus/cryptohome_client.h" 14 #include "chromeos/dbus/cryptohome_client.h"
14 #include "chromeos/dbus/dbus_thread_manager.h" 15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "crypto/encryptor.h"
17 #include "crypto/nss_util.h"
18 #include "crypto/sha2.h"
19 #include "crypto/symmetric_key.h"
15 20
16 namespace chromeos { 21 namespace chromeos {
17 22
18 namespace { 23 namespace {
19 24
20 const char kStubSystemSalt[] = "stub_system_salt"; 25 const char kStubSystemSalt[] = "stub_system_salt";
26 const size_t kKeySize = 16;
21 27
22 // Does nothing. Used as a Cryptohome::VoidMethodCallback. 28 // Does nothing. Used as a Cryptohome::VoidMethodCallback.
23 void DoNothing(DBusMethodCallStatus call_status) {} 29 void DoNothing(DBusMethodCallStatus call_status) {}
24 30
25 } // namespace 31 } // namespace
26 32
27 // This class handles the interaction with the ChromeOS cryptohome library APIs. 33 // This class handles the interaction with the ChromeOS cryptohome library APIs.
28 class CryptohomeLibraryImpl : public CryptohomeLibrary { 34 class CryptohomeLibraryImpl : public CryptohomeLibrary {
29 public: 35 public:
30 CryptohomeLibraryImpl() : weak_ptr_factory_(this) { 36 CryptohomeLibraryImpl() : weak_ptr_factory_(this) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 return result; 115 return result;
110 } 116 }
111 117
112 virtual std::string GetSystemSalt() OVERRIDE { 118 virtual std::string GetSystemSalt() OVERRIDE {
113 LoadSystemSalt(); // no-op if it's already loaded. 119 LoadSystemSalt(); // no-op if it's already loaded.
114 return StringToLowerASCII(base::HexEncode( 120 return StringToLowerASCII(base::HexEncode(
115 reinterpret_cast<const void*>(system_salt_.data()), 121 reinterpret_cast<const void*>(system_salt_.data()),
116 system_salt_.size())); 122 system_salt_.size()));
117 } 123 }
118 124
125 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE {
126 // Don't care about token encryption while debugging.
127 if (!base::chromeos::IsRunningOnChromeOS())
128 return token;
129
130 if (!LoadSystemSaltKey()) {
131 LOG(WARNING) << "System salt key is not available for encrypt.";
132 return std::string();
133 }
134 return EncryptTokenWithKey(system_salt_key_.get(),
135 GetSystemSalt(),
136 token);
137 }
138
139 virtual std::string DecryptWithSystemSalt(
140 const std::string& encrypted_token_hex) OVERRIDE {
141 // Don't care about token encryption while debugging.
142 if (!base::chromeos::IsRunningOnChromeOS())
143 return encrypted_token_hex;
144
145 if (!LoadSystemSaltKey()) {
146 LOG(WARNING) << "System salt key is not available for decrypt.";
147 return std::string();
148 }
149 return DecryptTokenWithKey(system_salt_key_.get(),
150 GetSystemSalt(),
151 encrypted_token_hex);
152 }
153
119 private: 154 private:
120 void LoadSystemSalt() { 155 void LoadSystemSalt() {
121 if (!system_salt_.empty()) 156 if (!system_salt_.empty())
122 return; 157 return;
123 DBusThreadManager::Get()->GetCryptohomeClient()-> 158 DBusThreadManager::Get()->GetCryptohomeClient()->
124 GetSystemSalt(&system_salt_); 159 GetSystemSalt(&system_salt_);
125 CHECK(!system_salt_.empty()); 160 CHECK(!system_salt_.empty());
126 CHECK_EQ(system_salt_.size() % 2, 0U); 161 CHECK_EQ(system_salt_.size() % 2, 0U);
127 } 162 }
128 163
164 // TODO: should this use the system salt for both the password and the salt
165 // value, or should this use a separate salt value?
166 bool LoadSystemSaltKey() {
167 if (!system_salt_key_.get())
168 system_salt_key_.reset(PassphraseToKey(GetSystemSalt(), GetSystemSalt()));
169 return system_salt_key_.get();
170 }
171
172 crypto::SymmetricKey* PassphraseToKey(const std::string& passprhase,
173 const std::string& salt) {
174 return crypto::SymmetricKey::DeriveKeyFromPassword(
175 crypto::SymmetricKey::AES, passprhase, salt, 1000, 256);
176 }
177
178
179 // Encrypts (AES) the token given |key| and |salt|.
180 std::string EncryptTokenWithKey(crypto::SymmetricKey* key,
181 const std::string& salt,
182 const std::string& token) {
183 crypto::Encryptor encryptor;
184 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
185 LOG(WARNING) << "Failed to initialize Encryptor.";
186 return std::string();
187 }
188 std::string nonce = salt.substr(0, kKeySize);
189 std::string encoded_token;
190 CHECK(encryptor.SetCounter(nonce));
191 if (!encryptor.Encrypt(token, &encoded_token)) {
192 LOG(WARNING) << "Failed to encrypt token.";
193 return std::string();
194 }
195
196 return StringToLowerASCII(base::HexEncode(
197 reinterpret_cast<const void*>(encoded_token.data()),
198 encoded_token.size()));
199 }
200
201 // Decrypts (AES) hex encoded encrypted token given |key| and |salt|.
202 std::string DecryptTokenWithKey(crypto::SymmetricKey* key,
203 const std::string& salt,
204 const std::string& encrypted_token_hex) {
205 std::vector<uint8> encrypted_token_bytes;
206 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) {
207 LOG(WARNING) << "Corrupt encrypted token found.";
208 return std::string();
209 }
210
211 std::string encrypted_token(
212 reinterpret_cast<char*>(encrypted_token_bytes.data()),
213 encrypted_token_bytes.size());
214 crypto::Encryptor encryptor;
215 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
216 LOG(WARNING) << "Failed to initialize Encryptor.";
217 return std::string();
218 }
219
220 std::string nonce = salt.substr(0, kKeySize);
221 std::string token;
222 CHECK(encryptor.SetCounter(nonce));
223 if (!encryptor.Decrypt(encrypted_token, &token)) {
224 LOG(WARNING) << "Failed to decrypt token.";
225 return std::string();
226 }
227 return token;
228 }
229
129 base::WeakPtrFactory<CryptohomeLibraryImpl> weak_ptr_factory_; 230 base::WeakPtrFactory<CryptohomeLibraryImpl> weak_ptr_factory_;
130 std::vector<uint8> system_salt_; 231 std::vector<uint8> system_salt_;
232 // A key based on the system salt. Useful for encrypting device-level
233 // data for which we have no additional credentials.
234 scoped_ptr<crypto::SymmetricKey> system_salt_key_;
131 235
132 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); 236 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
133 }; 237 };
134 238
135 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { 239 class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
136 public: 240 public:
137 CryptohomeLibraryStubImpl() 241 CryptohomeLibraryStubImpl()
138 : locked_(false) {} 242 : locked_(false) {}
139 virtual ~CryptohomeLibraryStubImpl() {} 243 virtual ~CryptohomeLibraryStubImpl() {}
140 244
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 283 }
180 284
181 virtual bool InstallAttributesIsFirstInstall() OVERRIDE { 285 virtual bool InstallAttributesIsFirstInstall() OVERRIDE {
182 return !locked_; 286 return !locked_;
183 } 287 }
184 288
185 virtual std::string GetSystemSalt() OVERRIDE { 289 virtual std::string GetSystemSalt() OVERRIDE {
186 return kStubSystemSalt; 290 return kStubSystemSalt;
187 } 291 }
188 292
293 virtual std::string EncryptWithSystemSalt(const std::string& token) {
294 return token;
295 }
296
297 virtual std::string DecryptWithSystemSalt(
298 const std::string& encrypted_token_hex) {
299 return encrypted_token_hex;
300 }
301
189 private: 302 private:
190 std::map<std::string, std::string> install_attrs_; 303 std::map<std::string, std::string> install_attrs_;
191 bool locked_; 304 bool locked_;
192 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl); 305 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl);
193 }; 306 };
194 307
195 CryptohomeLibrary::CryptohomeLibrary() {} 308 CryptohomeLibrary::CryptohomeLibrary() {}
196 CryptohomeLibrary::~CryptohomeLibrary() {} 309 CryptohomeLibrary::~CryptohomeLibrary() {}
197 310
311 static CryptohomeLibrary* g_cryptohome_library = NULL;
312 static CryptohomeLibrary* g_test_cryptohome_library = NULL;
313
198 // static 314 // static
199 CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) { 315 void CryptohomeLibrary::Initialize() {
200 CryptohomeLibrary* impl; 316 CHECK(!g_cryptohome_library);
201 if (stub) 317 if (base::chromeos::IsRunningOnChromeOS())
202 impl = new CryptohomeLibraryStubImpl(); 318 g_cryptohome_library = new CryptohomeLibraryStubImpl();
203 else 319 else
204 impl = new CryptohomeLibraryImpl(); 320 g_cryptohome_library = new CryptohomeLibraryImpl();
205 return impl; 321 }
322
323 // static
324 bool CryptohomeLibrary::IsInitialized() {
325 return g_cryptohome_library;
326 }
327
328 // static
329 void CryptohomeLibrary::Shutdown() {
330 CHECK(g_cryptohome_library);
331 delete g_cryptohome_library;
332 g_cryptohome_library = NULL;
333 }
334
335 // static
336 CryptohomeLibrary* CryptohomeLibrary::Get() {
337 CHECK(g_cryptohome_library || g_test_cryptohome_library)
338 << "CryptohomeLibrary::Get() called before Initialize()";
339 if (g_test_cryptohome_library)
340 return g_test_cryptohome_library;
341 return g_cryptohome_library;
342 }
343
344 // static
345 void CryptohomeLibrary::SetForTest(CryptohomeLibrary* impl) {
346 CHECK(!g_test_cryptohome_library || !impl);
347 g_test_cryptohome_library = impl;
348 }
349
350 // static
351 CryptohomeLibrary* CryptohomeLibrary::GetTestImpl() {
352 return new CryptohomeLibraryStubImpl();
206 } 353 }
207 354
208 } // namespace chromeos 355 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698