Home | History | Annotate | Download | only in password_manager
      1 // Copyright (c) 2010 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/password_manager/encryptor_password_mac.h"
      6 
      7 #import <Security/Security.h>
      8 
      9 #include "chrome/browser/keychain_mac.h"
     10 #include "chrome/browser/sync/util/crypto_helpers.h"
     11 #include "grit/generated_resources.h"
     12 #include "ui/base/l10n/l10n_util.h"
     13 
     14 namespace {
     15 
     16 // Generates a random password and adds it to the Keychain.  The added password
     17 // is returned from the function.  If an error occurs, an empty password is
     18 // returned.
     19 std::string AddRandomPasswordToKeychain(const MacKeychain& keychain,
     20                                         const std::string& service_name,
     21                                         const std::string& account_name) {
     22   std::string password = Generate128BitRandomHexString();
     23   void* password_data =
     24       const_cast<void*>(static_cast<const void*>(password.data()));
     25 
     26   OSStatus error = keychain.AddGenericPassword(NULL,
     27                                                service_name.size(),
     28                                                service_name.data(),
     29                                                account_name.size(),
     30                                                account_name.data(),
     31                                                password.size(),
     32                                                password_data,
     33                                                NULL);
     34 
     35   if (error != noErr) {
     36     DLOG(ERROR) << "Keychain add failed with error " << error;
     37     return std::string();
     38   }
     39 
     40   return password;
     41 }
     42 
     43 }  // namespace
     44 
     45 std::string EncryptorPassword::GetEncryptorPassword() const {
     46   // These two strings ARE indeed user facing.  But they are used to access
     47   // the encryption keyword.  So as to not lose encrypted data when system
     48   // locale changes we DO NOT LOCALIZE.
     49   const std::string service_name = "Chrome Safe Storage";
     50   const std::string account_name = "Chrome";
     51 
     52   UInt32 password_length = 0;
     53   void* password_data = NULL;
     54   OSStatus error = keychain_.FindGenericPassword(NULL,
     55                                                  service_name.size(),
     56                                                  service_name.data(),
     57                                                  account_name.size(),
     58                                                  account_name.data(),
     59                                                  &password_length,
     60                                                  &password_data,
     61                                                  NULL);
     62 
     63   if (error == noErr) {
     64     std::string password =
     65         std::string(static_cast<char*>(password_data), password_length);
     66     keychain_.ItemFreeContent(NULL, password_data);
     67     return password;
     68   } else if (error == errSecItemNotFound) {
     69     return AddRandomPasswordToKeychain(keychain_, service_name, account_name);
     70   } else {
     71     DLOG(ERROR) << "Keychain lookup failed with error " << error;
     72     return std::string();
     73   }
     74 }
     75 
     76 
     77