123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/os_crypt/keychain_password_mac.h"
- #import <Security/Security.h>
- #include "base/base64.h"
- #include "base/mac/mac_logging.h"
- #include "base/mac/scoped_cftyperef.h"
- #include "base/no_destructor.h"
- #include "base/rand_util.h"
- #include "build/branding_buildflags.h"
- #include "crypto/apple_keychain.h"
- using crypto::AppleKeychain;
- #if defined(ALLOW_RUNTIME_CONFIGURABLE_KEY_STORAGE)
- using KeychainNameContainerType = base::NoDestructor<std::string>;
- #else
- using KeychainNameContainerType = const base::NoDestructor<std::string>;
- #endif
- namespace {
- // These two strings ARE indeed user facing. But they are used to access
- // the encryption keyword. So as to not lose encrypted data when system
- // locale changes we DO NOT LOCALIZE.
- #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
- const char kDefaultServiceName[] = "Chrome Safe Storage";
- const char kDefaultAccountName[] = "Chrome";
- #else
- const char kDefaultServiceName[] = "Chromium Safe Storage";
- const char kDefaultAccountName[] = "Chromium";
- #endif
- // Generates a random password and adds it to the Keychain. The added password
- // is returned from the function. If an error occurs, an empty password is
- // returned.
- std::string AddRandomPasswordToKeychain(const AppleKeychain& keychain,
- const std::string& service_name,
- const std::string& account_name) {
- // Generate a password with 128 bits of randomness.
- const int kBytes = 128 / 8;
- std::string password;
- base::Base64Encode(base::RandBytesAsString(kBytes), &password);
- void* password_data =
- const_cast<void*>(static_cast<const void*>(password.data()));
- OSStatus error = keychain.AddGenericPassword(
- service_name.size(), service_name.data(), account_name.size(),
- account_name.data(), password.size(), password_data, NULL);
- if (error != noErr) {
- OSSTATUS_DLOG(ERROR, error) << "Keychain add failed";
- return std::string();
- }
- return password;
- }
- } // namespace
- // static
- KeychainPassword::KeychainNameType& KeychainPassword::GetServiceName() {
- static KeychainNameContainerType service_name(kDefaultServiceName);
- return *service_name;
- }
- // static
- KeychainPassword::KeychainNameType& KeychainPassword::GetAccountName() {
- static KeychainNameContainerType account_name(kDefaultAccountName);
- return *account_name;
- }
- KeychainPassword::KeychainPassword(const AppleKeychain& keychain)
- : keychain_(keychain) {}
- KeychainPassword::~KeychainPassword() = default;
- std::string KeychainPassword::GetPassword() const {
- UInt32 password_length = 0;
- void* password_data = nullptr;
- OSStatus error = keychain_.FindGenericPassword(
- GetServiceName().size(), GetServiceName().c_str(),
- GetAccountName().size(), GetAccountName().c_str(), &password_length,
- &password_data, nullptr);
- if (error == noErr) {
- std::string password =
- std::string(static_cast<char*>(password_data), password_length);
- keychain_.ItemFreeContent(password_data);
- return password;
- }
- if (error == errSecItemNotFound) {
- std::string password = AddRandomPasswordToKeychain(
- keychain_, GetServiceName(), GetAccountName());
- return password;
- }
- OSSTATUS_LOG(ERROR, error) << "Keychain lookup failed";
- return std::string();
- }
|