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