OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/os_crypt/os_crypt.h" | 5 #include "components/os_crypt/os_crypt.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
11 #include <memory> | 11 #include <memory> |
12 | 12 |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/synchronization/lock.h" |
17 #include "components/os_crypt/key_storage_linux.h" | 18 #include "components/os_crypt/key_storage_linux.h" |
18 #include "crypto/encryptor.h" | 19 #include "crypto/encryptor.h" |
19 #include "crypto/symmetric_key.h" | 20 #include "crypto/symmetric_key.h" |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 // Salt for Symmetric key derivation. | 24 // Salt for Symmetric key derivation. |
24 const char kSalt[] = "saltysalt"; | 25 const char kSalt[] = "saltysalt"; |
25 | 26 |
26 // Key size required for 128 bit AES. | 27 // Key size required for 128 bit AES. |
(...skipping 20 matching lines...) Expand all Loading... |
47 const char kObfuscationPrefix[][4] = { | 48 const char kObfuscationPrefix[][4] = { |
48 "v10", "v11", | 49 "v10", "v11", |
49 }; | 50 }; |
50 | 51 |
51 struct Cache { | 52 struct Cache { |
52 std::unique_ptr<KeyStorageLinux> key_storage_cache; | 53 std::unique_ptr<KeyStorageLinux> key_storage_cache; |
53 std::unique_ptr<std::string> password_v10_cache; | 54 std::unique_ptr<std::string> password_v10_cache; |
54 std::unique_ptr<std::string> password_v11_cache; | 55 std::unique_ptr<std::string> password_v11_cache; |
55 bool is_key_storage_cached; | 56 bool is_key_storage_cached; |
56 bool is_password_v11_cached; | 57 bool is_password_v11_cached; |
| 58 // Guards access to |g_cache|, making lazy initialization of individual parts |
| 59 // thread safe. |
| 60 base::Lock lock; |
57 }; | 61 }; |
58 | 62 |
59 base::LazyInstance<Cache>::Leaky g_cache = LAZY_INSTANCE_INITIALIZER; | 63 base::LazyInstance<Cache>::Leaky g_cache = LAZY_INSTANCE_INITIALIZER; |
60 | 64 |
61 // Lazy acquisition and caching of a KeyStorage. Will be null if no service is | 65 // Lazy acquisition and caching of a KeyStorage. Will be null if no service is |
62 // found. | 66 // found. |
63 KeyStorageLinux* GetKeyStorage() { | 67 KeyStorageLinux* GetKeyStorage() { |
64 if (!g_cache.Get().is_key_storage_cached) { | 68 if (!g_cache.Get().is_key_storage_cached) { |
65 g_cache.Get().is_key_storage_cached = true; | 69 g_cache.Get().is_key_storage_cached = true; |
66 g_cache.Get().key_storage_cache = KeyStorageLinux::CreateService(); | 70 g_cache.Get().key_storage_cache = KeyStorageLinux::CreateService(); |
67 } | 71 } |
68 return g_cache.Get().key_storage_cache.get(); | 72 return g_cache.Get().key_storage_cache.get(); |
69 } | 73 } |
70 | 74 |
71 // Returns a cached string of "peanuts". | 75 // Returns a cached string of "peanuts". Is thread-safe. |
72 std::string* GetPasswordV10() { | 76 std::string* GetPasswordV10() { |
73 if (!g_cache.Get().password_v10_cache.get()) | 77 base::AutoLock auto_lock(g_cache.Get().lock); |
| 78 if (!g_cache.Get().password_v10_cache.get()) { |
74 g_cache.Get().password_v10_cache.reset(new std::string("peanuts")); | 79 g_cache.Get().password_v10_cache.reset(new std::string("peanuts")); |
| 80 } |
75 return g_cache.Get().password_v10_cache.get(); | 81 return g_cache.Get().password_v10_cache.get(); |
76 } | 82 } |
77 | 83 |
78 // Caches and returns the password from the KeyStorage or null if there is no | 84 // Caches and returns the password from the KeyStorage or null if there is no |
79 // service. | 85 // service. Is thread-safe. |
80 std::string* GetPasswordV11() { | 86 std::string* GetPasswordV11() { |
| 87 base::AutoLock auto_lock(g_cache.Get().lock); |
81 if (!g_cache.Get().is_password_v11_cached) { | 88 if (!g_cache.Get().is_password_v11_cached) { |
82 g_cache.Get().is_password_v11_cached = true; | |
83 g_cache.Get().password_v11_cache.reset( | 89 g_cache.Get().password_v11_cache.reset( |
84 GetKeyStorage() ? new std::string(GetKeyStorage()->GetKey()) : nullptr); | 90 GetKeyStorage() ? new std::string(GetKeyStorage()->GetKey()) : nullptr); |
| 91 g_cache.Get().is_password_v11_cached = true; |
85 } | 92 } |
86 return g_cache.Get().password_v11_cache.get(); | 93 return g_cache.Get().password_v11_cache.get(); |
87 } | 94 } |
88 | 95 |
89 // Pointer to a function that creates and returns the |KeyStorage| instance to | 96 // Pointer to a function that creates and returns the |KeyStorage| instance to |
90 // be used. The function maintains ownership of the pointer. | 97 // be used. The function maintains ownership of the pointer. |
91 KeyStorageLinux* (*g_key_storage_provider)() = &GetKeyStorage; | 98 KeyStorageLinux* (*g_key_storage_provider)() = &GetKeyStorage; |
92 | 99 |
93 // Pointers to functions that return a password for deriving the encryption key. | 100 // Pointers to functions that return a password for deriving the encryption key. |
94 // One function for each supported password version (see Version enum). | 101 // One function for each supported password version (see Version enum). |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 static bool is_get_password_saved = false; | 248 static bool is_get_password_saved = false; |
242 static std::string* (*get_password_save[arraysize(g_get_password)])(); | 249 static std::string* (*get_password_save[arraysize(g_get_password)])(); |
243 if (!is_get_password_saved) { | 250 if (!is_get_password_saved) { |
244 std::copy(std::begin(g_get_password), std::end(g_get_password), | 251 std::copy(std::begin(g_get_password), std::end(g_get_password), |
245 std::begin(get_password_save)); | 252 std::begin(get_password_save)); |
246 is_get_password_saved = true; | 253 is_get_password_saved = true; |
247 } | 254 } |
248 | 255 |
249 if (get_key_storage_mock && get_password_v11_mock) { | 256 if (get_key_storage_mock && get_password_v11_mock) { |
250 // Bypass calling KeyStorage::CreateService and caching of the key for V11 | 257 // Bypass calling KeyStorage::CreateService and caching of the key for V11 |
251 g_get_password[Version::V11] = get_password_v11_mock; | 258 if (get_password_v11_mock) |
| 259 g_get_password[Version::V11] = get_password_v11_mock; |
252 // OSCrypt will determine the encryption version by checking if a | 260 // OSCrypt will determine the encryption version by checking if a |
253 // |KeyStorage| instance can be created. Enable V11 by returning the mock. | 261 // |KeyStorage| instance can be created. Enable V11 by returning the mock. |
254 g_key_storage_provider = get_key_storage_mock; | 262 if (get_key_storage_mock) |
| 263 g_key_storage_provider = get_key_storage_mock; |
255 } else { | 264 } else { |
256 // Restore real implementation | 265 // Restore real implementation |
257 std::copy(std::begin(get_password_save), std::end(get_password_save), | 266 std::copy(std::begin(get_password_save), std::end(get_password_save), |
258 std::begin(g_get_password)); | 267 std::begin(g_get_password)); |
| 268 g_key_storage_provider = &GetKeyStorage; |
259 } | 269 } |
260 } | 270 } |
OLD | NEW |