• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/cros/cryptohome_library.h"
6 
7 #include "base/command_line.h"
8 #include "base/hash_tables.h"
9 #include "base/message_loop.h"
10 #include "chrome/browser/chromeos/cros/cros_library.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "content/browser/browser_thread.h"
13 
14 namespace chromeos {
15 
16 // This class handles the interaction with the ChromeOS cryptohome library APIs.
17 class CryptohomeLibraryImpl : public CryptohomeLibrary {
18  public:
CryptohomeLibraryImpl()19   CryptohomeLibraryImpl() {
20     if (CrosLibrary::Get()->EnsureLoaded())
21       Init();
22   }
~CryptohomeLibraryImpl()23   virtual ~CryptohomeLibraryImpl() {}
24 
CheckKey(const std::string & user_email,const std::string & passhash)25   bool CheckKey(const std::string& user_email, const std::string& passhash) {
26     return chromeos::CryptohomeCheckKey(user_email.c_str(), passhash.c_str());
27   }
28 
AsyncCheckKey(const std::string & user_email,const std::string & passhash,Delegate * d)29   bool AsyncCheckKey(const std::string& user_email,
30                      const std::string& passhash,
31                      Delegate* d) {
32     return CacheCallback(
33         chromeos::CryptohomeAsyncCheckKey(user_email.c_str(), passhash.c_str()),
34         d,
35         "Couldn't initiate async check of user's key.");
36   }
37 
MigrateKey(const std::string & user_email,const std::string & old_hash,const std::string & new_hash)38   bool MigrateKey(const std::string& user_email,
39                   const std::string& old_hash,
40                   const std::string& new_hash) {
41     return chromeos::CryptohomeMigrateKey(user_email.c_str(),
42                                           old_hash.c_str(),
43                                           new_hash.c_str());
44   }
45 
AsyncMigrateKey(const std::string & user_email,const std::string & old_hash,const std::string & new_hash,Delegate * d)46   bool AsyncMigrateKey(const std::string& user_email,
47                        const std::string& old_hash,
48                        const std::string& new_hash,
49                        Delegate* d) {
50     return CacheCallback(
51         chromeos::CryptohomeAsyncMigrateKey(user_email.c_str(),
52                                             old_hash.c_str(),
53                                             new_hash.c_str()),
54         d,
55         "Couldn't initiate aync migration of user's key");
56   }
57 
Mount(const std::string & user_email,const std::string & passhash,int * error_code)58   bool Mount(const std::string& user_email,
59              const std::string& passhash,
60              int* error_code) {
61     return chromeos::CryptohomeMountAllowFail(user_email.c_str(),
62                                               passhash.c_str(),
63                                               error_code);
64   }
65 
AsyncMount(const std::string & user_email,const std::string & passhash,const bool create_if_missing,Delegate * d)66   bool AsyncMount(const std::string& user_email,
67                   const std::string& passhash,
68                   const bool create_if_missing,
69                   Delegate* d) {
70     return CacheCallback(
71         chromeos::CryptohomeAsyncMountSafe(user_email.c_str(),
72                                            passhash.c_str(),
73                                            create_if_missing,
74                                            false,
75                                            NULL),
76         d,
77         "Couldn't initiate async mount of cryptohome.");
78   }
79 
MountForBwsi(int * error_code)80   bool MountForBwsi(int* error_code) {
81     return chromeos::CryptohomeMountGuest(error_code);
82   }
83 
AsyncMountForBwsi(Delegate * d)84   bool AsyncMountForBwsi(Delegate* d) {
85     return CacheCallback(chromeos::CryptohomeAsyncMountGuest(),
86                          d,
87                          "Couldn't initiate async mount of cryptohome.");
88   }
89 
Unmount()90   bool Unmount() {
91     return chromeos::CryptohomeUnmount();
92   }
93 
Remove(const std::string & user_email)94   bool Remove(const std::string& user_email) {
95     return chromeos::CryptohomeRemove(user_email.c_str());
96   }
97 
AsyncRemove(const std::string & user_email,Delegate * d)98   bool AsyncRemove(const std::string& user_email, Delegate* d) {
99     return CacheCallback(
100         chromeos::CryptohomeAsyncRemove(user_email.c_str()),
101         d,
102         "Couldn't initiate async removal of cryptohome.");
103   }
104 
IsMounted()105   bool IsMounted() {
106     return chromeos::CryptohomeIsMounted();
107   }
108 
GetSystemSalt()109   CryptohomeBlob GetSystemSalt() {
110     CryptohomeBlob system_salt;
111     char* salt_buf;
112     int salt_len;
113     bool result = chromeos::CryptohomeGetSystemSaltSafe(&salt_buf, &salt_len);
114     if (result) {
115       system_salt.resize(salt_len);
116       if ((int)system_salt.size() == salt_len) {
117         memcpy(&system_salt[0], static_cast<const void*>(salt_buf),
118                salt_len);
119       } else {
120         system_salt.clear();
121       }
122     }
123     return system_salt;
124   }
125 
AsyncDoAutomaticFreeDiskSpaceControl(Delegate * d)126   bool AsyncDoAutomaticFreeDiskSpaceControl(Delegate* d) {
127     return CacheCallback(
128         chromeos::CryptohomeAsyncDoAutomaticFreeDiskSpaceControl(),
129         d,
130         "Couldn't do automatic free disk space control.");
131   }
132 
TpmIsReady()133   bool TpmIsReady() {
134     return chromeos::CryptohomeTpmIsReady();
135   }
136 
TpmIsEnabled()137   bool TpmIsEnabled() {
138     return chromeos::CryptohomeTpmIsEnabled();
139   }
140 
TpmIsOwned()141   bool TpmIsOwned() {
142     return chromeos::CryptohomeTpmIsOwned();
143   }
144 
TpmIsBeingOwned()145   bool TpmIsBeingOwned() {
146     return chromeos::CryptohomeTpmIsBeingOwned();
147   }
148 
TpmGetPassword(std::string * password)149   bool TpmGetPassword(std::string* password) {
150     char *password_buf;
151     bool result = chromeos::CryptohomeTpmGetPasswordSafe(&password_buf);
152     *password = password_buf;
153     chromeos::CryptohomeFreeString(password_buf);
154     return result;
155   }
156 
TpmCanAttemptOwnership()157   void TpmCanAttemptOwnership() {
158     chromeos::CryptohomeTpmCanAttemptOwnership();
159   }
160 
TpmClearStoredPassword()161   void TpmClearStoredPassword() {
162     chromeos::CryptohomeTpmClearStoredPassword();
163   }
164 
InstallAttributesGet(const std::string & name,std::string * value)165   bool InstallAttributesGet(const std::string& name, std::string* value) {
166     char* local_value;
167     bool done =
168         chromeos::CryptohomeInstallAttributesGet(name.c_str(), &local_value);
169     if (done) {
170       *value = local_value;
171       chromeos::CryptohomeFreeString(local_value);
172     }
173     return done;
174   }
175 
InstallAttributesSet(const std::string & name,const std::string & value)176   bool InstallAttributesSet(const std::string& name, const std::string& value) {
177     return chromeos::CryptohomeInstallAttributesSet(name.c_str(),
178                                                     value.c_str());
179   }
180 
InstallAttributesCount()181   int InstallAttributesCount() {
182     return chromeos::CryptohomeInstallAttributesCount();
183   }
184 
InstallAttributesFinalize()185   bool InstallAttributesFinalize() {
186     return chromeos::CryptohomeInstallAttributesFinalize();
187   }
188 
InstallAttributesIsReady()189   bool InstallAttributesIsReady() {
190     return chromeos::CryptohomeInstallAttributesIsReady();
191   }
192 
InstallAttributesIsSecure()193   bool InstallAttributesIsSecure() {
194     return chromeos::CryptohomeInstallAttributesIsSecure();
195   }
196 
InstallAttributesIsInvalid()197   bool InstallAttributesIsInvalid() {
198     return chromeos::CryptohomeInstallAttributesIsInvalid();
199   }
200 
InstallAttributesIsFirstInstall()201   bool InstallAttributesIsFirstInstall() {
202     return chromeos::CryptohomeInstallAttributesIsFirstInstall();
203   }
204 
Pkcs11GetTpmTokenInfo(std::string * label,std::string * user_pin)205   void Pkcs11GetTpmTokenInfo(std::string* label, std::string* user_pin) {
206     chromeos::CryptohomePkcs11GetTpmTokenInfo(label, user_pin);
207   }
208 
Pkcs11IsTpmTokenReady()209   bool Pkcs11IsTpmTokenReady() {
210     return chromeos::CryptohomePkcs11IsTpmTokenReady();
211   }
212 
213  private:
Handler(const chromeos::CryptohomeAsyncCallStatus & event,void * cryptohome_library)214   static void Handler(const chromeos::CryptohomeAsyncCallStatus& event,
215                       void* cryptohome_library) {
216     CryptohomeLibraryImpl* library =
217         reinterpret_cast<CryptohomeLibraryImpl*>(cryptohome_library);
218     library->Dispatch(event);
219   }
220 
Init()221   void Init() {
222     cryptohome_connection_ = chromeos::CryptohomeMonitorSession(&Handler, this);
223   }
224 
Dispatch(const chromeos::CryptohomeAsyncCallStatus & event)225   void Dispatch(const chromeos::CryptohomeAsyncCallStatus& event) {
226     const CallbackMap::iterator callback = callback_map_.find(event.async_id);
227     if (callback == callback_map_.end()) {
228       LOG(ERROR) << "Received signal for unknown async_id " << event.async_id;
229       return;
230     }
231     if (callback->second)
232       callback->second->OnComplete(event.return_status, event.return_code);
233     callback_map_.erase(callback);
234   }
235 
CacheCallback(int async_id,Delegate * d,const char * error)236   bool CacheCallback(int async_id, Delegate* d, const char* error) {
237     if (async_id == 0) {
238       LOG(ERROR) << error;
239       return false;
240     }
241     VLOG(1) << "Adding handler for " << async_id;
242     callback_map_[async_id] = d;
243     return true;
244   }
245 
246   typedef base::hash_map<int, Delegate*> CallbackMap;
247   mutable CallbackMap callback_map_;
248 
249   void* cryptohome_connection_;
250 
251   DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl);
252 };
253 
254 class CryptohomeLibraryStubImpl : public CryptohomeLibrary {
255  public:
CryptohomeLibraryStubImpl()256   CryptohomeLibraryStubImpl()
257     : locked_(false) {}
~CryptohomeLibraryStubImpl()258   virtual ~CryptohomeLibraryStubImpl() {}
259 
CheckKey(const std::string & user_email,const std::string & passhash)260   bool CheckKey(const std::string& user_email, const std::string& passhash) {
261     return true;
262   }
263 
AsyncCheckKey(const std::string & user_email,const std::string & passhash,Delegate * callback)264   bool AsyncCheckKey(const std::string& user_email,
265                      const std::string& passhash,
266                      Delegate* callback) {
267     BrowserThread::PostTask(
268         BrowserThread::UI, FROM_HERE,
269         NewRunnableFunction(&DoStubCallback, callback));
270     return true;
271   }
272 
MigrateKey(const std::string & user_email,const std::string & old_hash,const std::string & new_hash)273   bool MigrateKey(const std::string& user_email,
274                   const std::string& old_hash,
275                   const std::string& new_hash) {
276     return true;
277   }
278 
AsyncMigrateKey(const std::string & user_email,const std::string & old_hash,const std::string & new_hash,Delegate * callback)279   bool AsyncMigrateKey(const std::string& user_email,
280                        const std::string& old_hash,
281                        const std::string& new_hash,
282                        Delegate* callback) {
283     BrowserThread::PostTask(
284         BrowserThread::UI, FROM_HERE,
285         NewRunnableFunction(&DoStubCallback, callback));
286     return true;
287   }
288 
Mount(const std::string & user_email,const std::string & passhash,int * error_code)289   bool Mount(const std::string& user_email,
290              const std::string& passhash,
291              int* error_code) {
292     // For testing password change.
293     if (user_email ==
294         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
295             switches::kLoginUserWithNewPassword)) {
296       *error_code = kCryptohomeMountErrorKeyFailure;
297       return false;
298     }
299 
300     return true;
301   }
302 
AsyncMount(const std::string & user_email,const std::string & passhash,const bool create_if_missing,Delegate * callback)303   bool AsyncMount(const std::string& user_email,
304                   const std::string& passhash,
305                   const bool create_if_missing,
306                   Delegate* callback) {
307     BrowserThread::PostTask(
308         BrowserThread::UI, FROM_HERE,
309         NewRunnableFunction(&DoStubCallback, callback));
310     return true;
311   }
312 
MountForBwsi(int * error_code)313   bool MountForBwsi(int* error_code) {
314     return true;
315   }
316 
AsyncMountForBwsi(Delegate * callback)317   bool AsyncMountForBwsi(Delegate* callback) {
318     BrowserThread::PostTask(
319         BrowserThread::UI, FROM_HERE,
320         NewRunnableFunction(&DoStubCallback, callback));
321     return true;
322   }
323 
Unmount()324   bool Unmount() {
325     return true;
326   }
327 
Remove(const std::string & user_email)328   bool Remove(const std::string& user_email) {
329     return true;
330   }
331 
AsyncRemove(const std::string & user_email,Delegate * callback)332   bool AsyncRemove(const std::string& user_email, Delegate* callback) {
333     BrowserThread::PostTask(
334         BrowserThread::UI, FROM_HERE,
335         NewRunnableFunction(&DoStubCallback, callback));
336     return true;
337   }
338 
IsMounted()339   bool IsMounted() {
340     return true;
341   }
342 
GetSystemSalt()343   CryptohomeBlob GetSystemSalt() {
344     CryptohomeBlob salt = CryptohomeBlob();
345     salt.push_back(0);
346     salt.push_back(0);
347     return salt;
348   }
349 
AsyncDoAutomaticFreeDiskSpaceControl(Delegate * callback)350   bool AsyncDoAutomaticFreeDiskSpaceControl(Delegate* callback) {
351     BrowserThread::PostTask(
352         BrowserThread::UI, FROM_HERE,
353         NewRunnableFunction(&DoStubCallback, callback));
354     return true;
355   }
356 
357   // Tpm begin ready after 20-th call.
TpmIsReady()358   bool TpmIsReady() {
359     static int counter = 0;
360     return ++counter > 20;
361   }
362 
TpmIsEnabled()363   bool TpmIsEnabled() {
364     return true;
365   }
366 
TpmIsOwned()367   bool TpmIsOwned() {
368     return true;
369   }
370 
TpmIsBeingOwned()371   bool TpmIsBeingOwned() {
372     return true;
373   }
374 
TpmGetPassword(std::string * password)375   bool TpmGetPassword(std::string* password) {
376     *password = "Stub-TPM-password";
377     return true;
378   }
379 
TpmCanAttemptOwnership()380   void TpmCanAttemptOwnership() {}
381 
TpmClearStoredPassword()382   void TpmClearStoredPassword() {}
383 
InstallAttributesGet(const std::string & name,std::string * value)384   bool InstallAttributesGet(const std::string& name, std::string* value) {
385     if (install_attrs_.find(name) != install_attrs_.end()) {
386       *value = install_attrs_[name];
387       return true;
388     }
389     return false;
390   }
391 
InstallAttributesSet(const std::string & name,const std::string & value)392   bool InstallAttributesSet(const std::string& name, const std::string& value) {
393     install_attrs_[name] = value;
394     return true;
395   }
396 
InstallAttributesCount()397   int InstallAttributesCount() {
398     return install_attrs_.size();
399   }
400 
InstallAttributesFinalize()401   bool InstallAttributesFinalize() {
402     locked_ = true;
403     return true;
404   }
405 
InstallAttributesIsReady()406   bool InstallAttributesIsReady() {
407     return true;
408   }
409 
InstallAttributesIsSecure()410   bool InstallAttributesIsSecure() {
411     return false;
412   }
413 
InstallAttributesIsInvalid()414   bool InstallAttributesIsInvalid() {
415     return false;
416   }
417 
InstallAttributesIsFirstInstall()418   bool InstallAttributesIsFirstInstall() {
419     return !locked_;
420   }
421 
Pkcs11GetTpmTokenInfo(std::string * label,std::string * user_pin)422   void Pkcs11GetTpmTokenInfo(std::string* label,
423                              std::string* user_pin) {
424     *label = "Stub TPM Token";
425     *user_pin = "012345";
426   }
427 
Pkcs11IsTpmTokenReady()428   bool Pkcs11IsTpmTokenReady() { return true; }
429 
430  private:
DoStubCallback(Delegate * callback)431   static void DoStubCallback(Delegate* callback) {
432     if (callback)
433       callback->OnComplete(true, kCryptohomeMountErrorNone);
434   }
435 
436   std::map<std::string, std::string> install_attrs_;
437   bool locked_;
438   DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl);
439 };
440 
CryptohomeLibrary()441 CryptohomeLibrary::CryptohomeLibrary() {}
~CryptohomeLibrary()442 CryptohomeLibrary::~CryptohomeLibrary() {}
443 
444 // static
GetImpl(bool stub)445 CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) {
446   if (stub)
447     return new CryptohomeLibraryStubImpl();
448   else
449     return new CryptohomeLibraryImpl();
450 }
451 
452 } // namespace chromeos
453