0

Rename MacKeychain to AppleKeychain

Rename MacKeychain to AppleKeychain and add mac and iOS specific 
implementations (crypto/apple_keychain_ios.mm and 
crypto/apple_keychain_mac.mm). Rename MockKeychain to 
MockAppleKeychain and split its implementations in 3 files 
crypto/mock_apple_keychain.cc, crypto/mock_apple_keychain_ios.cc and 
crypto/mock_apple_keychain_mac.cc).


Review URL: https://chromiumcodereview.appspot.com/10875029

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154123 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
msarda@chromium.org
2012-08-30 13:03:46 +00:00
parent 57ed6c2888
commit 982f1ab97f
17 changed files with 525 additions and 260 deletions

@ -10,11 +10,11 @@
#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/password_manager/encryptor_password_mac.h"
#include "crypto/apple_keychain.h"
#include "crypto/encryptor.h"
#include "crypto/keychain_mac.h"
#include "crypto/symmetric_key.h"
using crypto::MacKeychain;
using crypto::AppleKeychain;
namespace {
@ -45,7 +45,7 @@ crypto::SymmetricKey* GetEncryptionKey() {
if (use_mock_keychain) {
password = "mock_password";
} else {
MacKeychain keychain;
AppleKeychain keychain;
EncryptorPassword encryptor_password(keychain);
password = encryptor_password.GetEncryptorPassword();
}

@ -10,12 +10,12 @@
#include "base/basictypes.h"
namespace crypto {
class MacKeychain;
class AppleKeychain;
} // namespace crypto
class EncryptorPassword {
public:
explicit EncryptorPassword(const crypto::MacKeychain& keychain)
explicit EncryptorPassword(const crypto::AppleKeychain& keychain)
: keychain_(keychain) {
}
@ -29,7 +29,7 @@ class EncryptorPassword {
private:
DISALLOW_COPY_AND_ASSIGN(EncryptorPassword);
const crypto::MacKeychain& keychain_;
const crypto::AppleKeychain& keychain_;
};
#endif // CHROME_BROWSER_PASSWORD_MANAGER_ENCRYPTOR_PASSWORD_H__

@ -9,17 +9,17 @@
#include "base/base64.h"
#include "base/mac/mac_logging.h"
#include "base/rand_util.h"
#include "crypto/keychain_mac.h"
#include "crypto/apple_keychain.h"
#include "ui/base/l10n/l10n_util.h"
using crypto::MacKeychain;
using crypto::AppleKeychain;
namespace {
// 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 MacKeychain& keychain,
std::string AddRandomPasswordToKeychain(const AppleKeychain& keychain,
const std::string& service_name,
const std::string& account_name) {
// Generate a password with 128 bits of randomness.

@ -3,17 +3,17 @@
// found in the LICENSE file.
#include "chrome/browser/password_manager/encryptor_password_mac.h"
#include "crypto/mock_keychain_mac.h"
#include "crypto/mock_apple_keychain.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
using crypto::MockKeychain;
using crypto::MockAppleKeychain;
// Test that if we have an existing password in the Keychain and we are
// authorized by the user to read it then we get it back correctly.
TEST(EncryptorPasswordTest, FindPasswordSuccess) {
MockKeychain keychain;
MockAppleKeychain keychain;
keychain.set_find_generic_result(noErr);
EncryptorPassword password(keychain);
EXPECT_FALSE(password.GetEncryptorPassword().empty());
@ -24,7 +24,7 @@ TEST(EncryptorPasswordTest, FindPasswordSuccess) {
// Test that if we do not have an existing password in the Keychain then it
// gets added successfully and returned.
TEST(EncryptorPasswordTest, FindPasswordNotFound) {
MockKeychain keychain;
MockAppleKeychain keychain;
keychain.set_find_generic_result(errSecItemNotFound);
EncryptorPassword password(keychain);
EXPECT_EQ(24U, password.GetEncryptorPassword().length());
@ -35,7 +35,7 @@ TEST(EncryptorPasswordTest, FindPasswordNotFound) {
// Test that if get denied access by the user then we return an empty password.
// And we should not try to add one.
TEST(EncryptorPasswordTest, FindPasswordNotAuthorized) {
MockKeychain keychain;
MockAppleKeychain keychain;
keychain.set_find_generic_result(errSecAuthFailed);
EncryptorPassword password(keychain);
EXPECT_TRUE(password.GetEncryptorPassword().empty());
@ -46,7 +46,7 @@ TEST(EncryptorPasswordTest, FindPasswordNotAuthorized) {
// Test that if some random other error happens then we return an empty
// password, and we should not try to add one.
TEST(EncryptorPasswordTest, FindPasswordOtherError) {
MockKeychain keychain;
MockAppleKeychain keychain;
keychain.set_find_generic_result(errSecNotAvailable);
EncryptorPassword password(keychain);
EXPECT_TRUE(password.GetEncryptorPassword().empty());
@ -56,7 +56,7 @@ TEST(EncryptorPasswordTest, FindPasswordOtherError) {
// Test that subsequent additions to the keychain give different passwords.
TEST(EncryptorPasswordTest, PasswordsDiffer) {
MockKeychain keychain1;
MockAppleKeychain keychain1;
keychain1.set_find_generic_result(errSecItemNotFound);
EncryptorPassword encryptor_password1(keychain1);
std::string password1 = encryptor_password1.GetEncryptorPassword();
@ -64,7 +64,7 @@ TEST(EncryptorPasswordTest, PasswordsDiffer) {
EXPECT_TRUE(keychain1.called_add_generic());
EXPECT_EQ(0, keychain1.password_data_count());
MockKeychain keychain2;
MockAppleKeychain keychain2;
keychain2.set_find_generic_result(errSecItemNotFound);
EncryptorPassword encryptor_password2(keychain2);
std::string password2 = encryptor_password2.GetEncryptorPassword();

@ -21,8 +21,8 @@
#include "chrome/browser/password_manager/password_store_win.h"
#elif defined(OS_MACOSX)
#include "chrome/browser/password_manager/password_store_mac.h"
#include "crypto/keychain_mac.h"
#include "crypto/mock_keychain_mac.h"
#include "crypto/apple_keychain.h"
#include "crypto/mock_apple_keychain.h"
#elif defined(OS_CHROMEOS) || defined(OS_ANDROID)
// Don't do anything. We're going to use the default store.
#elif defined(OS_POSIX)
@ -115,9 +115,9 @@ PasswordStoreFactory::BuildServiceInstanceFor(Profile* profile) const {
WebDataServiceFactory::GetForProfile(profile, Profile::IMPLICIT_ACCESS));
#elif defined(OS_MACOSX)
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseMockKeychain)) {
ps = new PasswordStoreMac(new crypto::MockKeychain(), login_db);
ps = new PasswordStoreMac(new crypto::MockAppleKeychain(), login_db);
} else {
ps = new PasswordStoreMac(new crypto::MacKeychain(), login_db);
ps = new PasswordStoreMac(new crypto::AppleKeychain(), login_db);
}
#elif defined(OS_CHROMEOS) || defined(OS_ANDROID)
// For now, we use PasswordStoreDefault. We might want to make a native

@ -22,16 +22,16 @@
#include "chrome/browser/password_manager/password_store_change.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_service.h"
#include "crypto/keychain_mac.h"
#include "crypto/apple_keychain.h"
using crypto::MacKeychain;
using crypto::AppleKeychain;
using webkit::forms::PasswordForm;
// Utility class to handle the details of constructing and running a keychain
// search from a set of attributes.
class KeychainSearch {
public:
explicit KeychainSearch(const MacKeychain& keychain);
explicit KeychainSearch(const AppleKeychain& keychain);
~KeychainSearch();
// Sets up a keycahin search based on an non "null" (NULL for char*,
@ -49,12 +49,12 @@ class KeychainSearch {
void FindMatchingItems(std::vector<SecKeychainItemRef>* matches);
private:
const MacKeychain* keychain_;
const AppleKeychain* keychain_;
SecKeychainAttributeList search_attributes_;
SecKeychainSearchRef search_ref_;
};
KeychainSearch::KeychainSearch(const MacKeychain& keychain)
KeychainSearch::KeychainSearch(const AppleKeychain& keychain)
: keychain_(&keychain), search_ref_(NULL) {
search_attributes_.count = 0;
search_attributes_.attr = NULL;
@ -231,7 +231,7 @@ PasswordForm::Scheme SchemeForAuthType(SecAuthenticationType auth_type) {
}
}
bool FillPasswordFormFromKeychainItem(const MacKeychain& keychain,
bool FillPasswordFormFromKeychainItem(const AppleKeychain& keychain,
const SecKeychainItemRef& keychain_item,
PasswordForm* form) {
DCHECK(form);
@ -444,7 +444,8 @@ void MergePasswordForms(std::vector<PasswordForm*>* keychain_forms,
}
std::vector<PasswordForm*> GetPasswordsForForms(
const MacKeychain& keychain, std::vector<PasswordForm*>* database_forms) {
const AppleKeychain& keychain,
std::vector<PasswordForm*>* database_forms) {
MacKeychainPasswordFormAdapter keychain_adapter(&keychain);
std::vector<PasswordForm*> merged_forms;
@ -469,7 +470,7 @@ std::vector<PasswordForm*> GetPasswordsForForms(
#pragma mark -
MacKeychainPasswordFormAdapter::MacKeychainPasswordFormAdapter(
const MacKeychain* keychain)
const AppleKeychain* keychain)
: keychain_(keychain), finds_only_owned_(false) {
}
@ -734,7 +735,7 @@ OSType MacKeychainPasswordFormAdapter::CreatorCodeForSearch() {
#pragma mark -
PasswordStoreMac::PasswordStoreMac(MacKeychain* keychain,
PasswordStoreMac::PasswordStoreMac(AppleKeychain* keychain,
LoginDatabase* login_db)
: keychain_(keychain), login_metadata_db_(login_db) {
DCHECK(keychain_.get());

@ -18,7 +18,7 @@ class NotificationService;
}
namespace crypto {
class MacKeychain;
class AppleKeychain;
}
// Implements PasswordStore on top of the OS X Keychain, with an internal
@ -30,7 +30,7 @@ class PasswordStoreMac : public PasswordStore {
public:
// Takes ownership of |keychain| and |login_db|, both of which must be
// non-NULL.
PasswordStoreMac(crypto::MacKeychain* keychain, LoginDatabase* login_db);
PasswordStoreMac(crypto::AppleKeychain* keychain, LoginDatabase* login_db);
// Initializes |thread_| and |notification_service_|.
virtual bool Init() OVERRIDE;
@ -87,7 +87,7 @@ class PasswordStoreMac : public PasswordStore {
// thread.
void CreateNotificationService();
scoped_ptr<crypto::MacKeychain> keychain_;
scoped_ptr<crypto::AppleKeychain> keychain_;
scoped_ptr<LoginDatabase> login_metadata_db_;
// Thread that the synchronous methods are run on.

@ -11,18 +11,18 @@
#include <vector>
#include "base/time.h"
#include "crypto/keychain_mac.h"
#include "crypto/apple_keychain.h"
using crypto::MacKeychain;
using crypto::AppleKeychain;
// Adapter that wraps a MacKeychain and provides interaction in terms of
// Adapter that wraps a AppleKeychain and provides interaction in terms of
// PasswordForms instead of Keychain items.
class MacKeychainPasswordFormAdapter {
public:
// Creates an adapter for |keychain|. This class does not take ownership of
// |keychain|, so the caller must make sure that the keychain outlives the
// created object.
explicit MacKeychainPasswordFormAdapter(const MacKeychain* keychain);
explicit MacKeychainPasswordFormAdapter(const AppleKeychain* keychain);
// Returns PasswordForms for each keychain entry that could be used to fill
// |form|. Caller is responsible for deleting the returned forms.
@ -67,20 +67,20 @@ class MacKeychainPasswordFormAdapter {
private:
// Returns PasswordForms constructed from the given Keychain items, calling
// MacKeychain::Free on all of the keychain items and clearing the vector.
// AppleKeychain::Free on all of the keychain items and clearing the vector.
// Caller is responsible for deleting the returned forms.
std::vector<webkit::forms::PasswordForm*> ConvertKeychainItemsToForms(
std::vector<SecKeychainItemRef>* items);
// Searches |keychain| for the specific keychain entry that corresponds to the
// given form, and returns it (or NULL if no match is found). The caller is
// responsible for calling MacKeychain::Free on on the returned item.
// responsible for calling AppleKeychain::Free on on the returned item.
SecKeychainItemRef KeychainItemForForm(
const webkit::forms::PasswordForm& form);
// Returns the Keychain items matching the given signon_realm, scheme, and
// optionally path and username (either of both can be NULL).
// The caller is responsible for calling MacKeychain::Free on the
// The caller is responsible for calling AppleKeychain::Free on the
// returned items.
std::vector<SecKeychainItemRef> MatchingKeychainItems(
const std::string& signon_realm,
@ -119,7 +119,7 @@ class MacKeychainPasswordFormAdapter {
// a search of all items, regardless of creator.
OSType CreatorCodeForSearch();
const MacKeychain* keychain_;
const AppleKeychain* keychain_;
// If true, Keychain searches are restricted to items created by Chrome.
bool finds_only_owned_;
@ -140,7 +140,7 @@ namespace internal_keychain_helpers {
// becomes an issue, the password storage API will need to be refactored to
// allow the password to be retrieved later (accessing other fields doesn't
// require authorization).
bool FillPasswordFormFromKeychainItem(const MacKeychain& keychain,
bool FillPasswordFormFromKeychainItem(const AppleKeychain& keychain,
const SecKeychainItemRef& keychain_item,
webkit::forms::PasswordForm* form);
@ -156,7 +156,7 @@ bool FormsMatchForMerge(const webkit::forms::PasswordForm& form_a,
// On return, database_forms and keychain_forms will have only unused
// entries; for database_forms that means entries for which no corresponding
// password can be found (and which aren't blacklist entries), and for
// keychain_forms it's entries that weren't merged into at least one database
// keychain_forms its entries that weren't merged into at least one database
// form.
void MergePasswordForms(
std::vector<webkit::forms::PasswordForm*>* keychain_forms,
@ -167,7 +167,7 @@ void MergePasswordForms(
// possible using entries from |keychain| and returns them. On return,
// |database_forms| will contain only the forms for which no password was found.
std::vector<webkit::forms::PasswordForm*> GetPasswordsForForms(
const MacKeychain& keychain,
const AppleKeychain& keychain,
std::vector<webkit::forms::PasswordForm*>* database_forms);
} // internal_keychain_helpers

@ -17,10 +17,10 @@
#include "chrome/browser/password_manager/password_store_mac_internal.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/test/test_browser_thread.h"
#include "crypto/mock_keychain_mac.h"
#include "crypto/mock_apple_keychain.h"
using content::BrowserThread;
using crypto::MockKeychain;
using crypto::MockAppleKeychain;
using webkit::forms::PasswordForm;
using testing::_;
using testing::DoAll;
@ -51,7 +51,7 @@ ACTION(QuitUIMessageLoop) {
class PasswordStoreMacInternalsTest : public testing::Test {
public:
virtual void SetUp() {
MockKeychain::KeychainTestData test_data[] = {
MockAppleKeychain::KeychainTestData test_data[] = {
// Basic HTML form.
{ kSecAuthenticationTypeHTMLForm, "some.domain.com",
kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
@ -91,7 +91,7 @@ class PasswordStoreMacInternalsTest : public testing::Test {
"abc", "123", false },
};
keychain_ = new MockKeychain();
keychain_ = new MockAppleKeychain();
for (unsigned int i = 0; i < arraysize(test_data); ++i) {
keychain_->AddTestItem(test_data[i]);
@ -120,7 +120,7 @@ class PasswordStoreMacInternalsTest : public testing::Test {
EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems());
}
MockKeychain* keychain_;
MockAppleKeychain* keychain_;
};
#pragma mark -
@ -274,7 +274,7 @@ TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) {
};
for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(expected); ++i) {
// Create our fake KeychainItemRef; see MockKeychain docs.
// Create our fake KeychainItemRef; see MockAppleKeychain docs.
SecKeychainItemRef keychain_item =
reinterpret_cast<SecKeychainItemRef>(i + 1);
PasswordForm form;
@ -514,7 +514,8 @@ TEST_F(PasswordStoreMacInternalsTest, TestKeychainAdd) {
"gobbledygook", NULL, NULL, NULL, NULL,
L"anonymous", L"knock-knock", false, false, 0 }, false },
// Test that failing to update a duplicate (forced using the magic failure
// password; see MockKeychain::ItemModifyAttributesAndData) is reported.
// password; see MockAppleKeychain::ItemModifyAttributesAndData) is
// reported.
{ { PasswordForm::SCHEME_HTML, "http://some.domain.com",
"http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
L"joe_user", L"fail_me", false, false, 0 }, false },
@ -906,7 +907,7 @@ class PasswordStoreMacTest : public testing::Test {
FilePath db_file = db_dir_.path().AppendASCII("login.db");
ASSERT_TRUE(login_db_->Init(db_file));
keychain_ = new MockKeychain();
keychain_ = new MockAppleKeychain();
store_ = new PasswordStoreMac(keychain_, login_db_);
ASSERT_TRUE(store_->Init());
@ -922,7 +923,7 @@ class PasswordStoreMacTest : public testing::Test {
MessageLoopForUI message_loop_;
content::TestBrowserThread ui_thread_;
MockKeychain* keychain_; // Owned by store_.
MockAppleKeychain* keychain_; // Owned by store_.
LoginDatabase* login_db_; // Owned by store_.
scoped_refptr<PasswordStoreMac> store_;
ScopedTempDir db_dir_;
@ -941,14 +942,14 @@ TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
};
scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data));
login_db_->AddLogin(*joint_form);
MockKeychain::KeychainTestData joint_keychain_data = {
MockAppleKeychain::KeychainTestData joint_keychain_data = {
kSecAuthenticationTypeHTMLForm, "some.domain.com",
kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z",
"joe_user", "sekrit", false };
keychain_->AddTestItem(joint_keychain_data);
// Insert a password into the keychain only.
MockKeychain::KeychainTestData keychain_only_data = {
MockAppleKeychain::KeychainTestData keychain_only_data = {
kSecAuthenticationTypeHTMLForm, "keychain.only.com",
kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
"keychain", "only", false

@ -10,6 +10,12 @@
#include "base/basictypes.h"
#include "crypto/crypto_export.h"
#if defined (OS_IOS)
typedef void* SecKeychainRef;
typedef void* SecKeychainItemRef;
typedef void SecKeychainAttributeList;
#endif
namespace crypto {
// Wraps the KeychainServices API in a very thin layer, to allow it to be
@ -20,11 +26,33 @@ namespace crypto {
// SecKeychainFoo). The only exception is Free, which should be used for
// anything returned from this class that would normally be freed with
// CFRelease (to aid in testing).
class CRYPTO_EXPORT MacKeychain {
class CRYPTO_EXPORT AppleKeychain {
public:
MacKeychain();
virtual ~MacKeychain();
AppleKeychain();
virtual ~AppleKeychain();
virtual OSStatus FindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const;
virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const;
virtual OSStatus AddGenericPassword(SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const;
#if !defined(OS_IOS)
virtual OSStatus ItemCopyAttributesAndData(
SecKeychainItemRef itemRef,
SecKeychainAttributeInfo* info,
@ -67,32 +95,12 @@ class CRYPTO_EXPORT MacKeychain {
const void* passwordData,
SecKeychainItemRef* itemRef) const;
virtual OSStatus FindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const;
virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const;
virtual OSStatus AddGenericPassword(SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const;
// Calls CFRelease on the given ref, after checking that |ref| is non-NULL.
virtual void Free(CFTypeRef ref) const;
#endif // !defined(OS_IOS)
private:
DISALLOW_COPY_AND_ASSIGN(MacKeychain);
DISALLOW_COPY_AND_ASSIGN(AppleKeychain);
};
} // namespace crypto

@ -0,0 +1,202 @@
// Copyright (c) 2012 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 "crypto/apple_keychain.h"
#import <Foundation/Foundation.h>
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_nsobject.h"
namespace {
enum KeychainAction {
kKeychainActionCreate,
kKeychainActionUpdate
};
// Creates a dictionary that can be used to query the keystore.
// Ownership follows the Create rule.
CFDictionaryRef CreateGenericPasswordQuery(UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName) {
CFMutableDictionaryRef query =
CFDictionaryCreateMutable(NULL,
5,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Type of element is generic password.
CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
// Set the service name.
scoped_nsobject<NSString> service_name_ns(
[[NSString alloc] initWithBytes:serviceName
length:serviceNameLength
encoding:NSUTF8StringEncoding]);
CFDictionarySetValue(query, kSecAttrService,
base::mac::NSToCFCast(service_name_ns));
// Set the account name.
scoped_nsobject<NSString> account_name_ns(
[[NSString alloc] initWithBytes:accountName
length:accountNameLength
encoding:NSUTF8StringEncoding]);
CFDictionarySetValue(query, kSecAttrAccount,
base::mac::NSToCFCast(account_name_ns));
// Use the proper search constants, return only the data of the first match.
CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
return query;
}
// Creates a dictionary conatining the data to save into the keychain.
// Ownership follows the Create rule.
CFDictionaryRef CreateKeychainData(UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
KeychainAction action) {
CFMutableDictionaryRef keychain_data =
CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Set the password.
NSData* password = [NSData dataWithBytes:passwordData length:passwordLength];
CFDictionarySetValue(keychain_data, kSecValueData,
base::mac::NSToCFCast(password));
// If this is not a creation, no structural information is needed.
if (action != kKeychainActionCreate)
return keychain_data;
// Set the type of the data.
CFDictionarySetValue(keychain_data, kSecClass, kSecClassGenericPassword);
// Only allow access when the device has been unlocked.
CFDictionarySetValue(keychain_data,
kSecAttrAccessible,
kSecAttrAccessibleWhenUnlocked);
// Set the service name.
scoped_nsobject<NSString> service_name_ns(
[[NSString alloc] initWithBytes:serviceName
length:serviceNameLength
encoding:NSUTF8StringEncoding]);
CFDictionarySetValue(keychain_data, kSecAttrService,
base::mac::NSToCFCast(service_name_ns));
// Set the account name.
scoped_nsobject<NSString> account_name_ns(
[[NSString alloc] initWithBytes:accountName
length:accountNameLength
encoding:NSUTF8StringEncoding]);
CFDictionarySetValue(keychain_data, kSecAttrAccount,
base::mac::NSToCFCast(account_name_ns));
return keychain_data;
}
} // namespace
namespace crypto {
AppleKeychain::AppleKeychain() {}
AppleKeychain::~AppleKeychain() {}
OSStatus AppleKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const {
free(data);
return noErr;
}
OSStatus AppleKeychain::AddGenericPassword(SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const {
base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
CreateGenericPasswordQuery(serviceNameLength,
serviceName,
accountNameLength,
accountName));
// Check that there is not already a password.
OSStatus status = SecItemCopyMatching(query, NULL);
if (status == errSecItemNotFound) {
// A new entry must be created.
base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
CreateKeychainData(serviceNameLength,
serviceName,
accountNameLength,
accountName,
passwordLength,
passwordData,
kKeychainActionCreate));
status = SecItemAdd(keychain_data, NULL);
} else if (status == noErr) {
// The entry must be updated.
base::mac::ScopedCFTypeRef<CFDictionaryRef> keychain_data(
CreateKeychainData(serviceNameLength,
serviceName,
accountNameLength,
accountName,
passwordLength,
passwordData,
kKeychainActionUpdate));
status = SecItemUpdate(query, keychain_data);
}
return status;
}
OSStatus AppleKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const {
DCHECK((passwordData && passwordLength) ||
(!passwordData && !passwordLength));
base::mac::ScopedCFTypeRef<CFDictionaryRef> query(
CreateGenericPasswordQuery(serviceNameLength,
serviceName,
accountNameLength,
accountName));
// Get the keychain item containing the password.
CFTypeRef resultRef = NULL;
OSStatus status = SecItemCopyMatching(query, &resultRef);
base::mac::ScopedCFTypeRef<CFTypeRef> result(resultRef);
if (status != noErr) {
if (passwordData) {
*passwordData = NULL;
*passwordLength = 0;
}
return status;
}
if (passwordData) {
CFDataRef data = base::mac::CFCast<CFDataRef>(result);
NSUInteger length = CFDataGetLength(data);
*passwordData = malloc(length * sizeof(UInt8));
CFDataGetBytes(data, CFRangeMake(0, length), (UInt8*)*passwordData);
*passwordLength = length;
}
return status;
}
} // namespace crypto

@ -2,15 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "crypto/keychain_mac.h"
#include "crypto/apple_keychain.h"
#import <Foundation/Foundation.h>
namespace crypto {
MacKeychain::MacKeychain() {}
AppleKeychain::AppleKeychain() {}
MacKeychain::~MacKeychain() {}
AppleKeychain::~AppleKeychain() {}
OSStatus MacKeychain::ItemCopyAttributesAndData(
OSStatus AppleKeychain::ItemCopyAttributesAndData(
SecKeychainItemRef itemRef,
SecKeychainAttributeInfo* info,
SecItemClass* itemClass,
@ -21,7 +23,7 @@ OSStatus MacKeychain::ItemCopyAttributesAndData(
attrList, length, outData);
}
OSStatus MacKeychain::ItemModifyAttributesAndData(
OSStatus AppleKeychain::ItemModifyAttributesAndData(
SecKeychainItemRef itemRef,
const SecKeychainAttributeList* attrList,
UInt32 length,
@ -30,17 +32,17 @@ OSStatus MacKeychain::ItemModifyAttributesAndData(
data);
}
OSStatus MacKeychain::ItemFreeAttributesAndData(
OSStatus AppleKeychain::ItemFreeAttributesAndData(
SecKeychainAttributeList* attrList,
void* data) const {
return SecKeychainItemFreeAttributesAndData(attrList, data);
}
OSStatus MacKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
OSStatus AppleKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
return SecKeychainItemDelete(itemRef);
}
OSStatus MacKeychain::SearchCreateFromAttributes(
OSStatus AppleKeychain::SearchCreateFromAttributes(
CFTypeRef keychainOrArray,
SecItemClass itemClass,
const SecKeychainAttributeList* attrList,
@ -49,12 +51,12 @@ OSStatus MacKeychain::SearchCreateFromAttributes(
attrList, searchRef);
}
OSStatus MacKeychain::SearchCopyNext(SecKeychainSearchRef searchRef,
SecKeychainItemRef* itemRef) const {
OSStatus AppleKeychain::SearchCopyNext(SecKeychainSearchRef searchRef,
SecKeychainItemRef* itemRef) const {
return SecKeychainSearchCopyNext(searchRef, itemRef);
}
OSStatus MacKeychain::AddInternetPassword(
OSStatus AppleKeychain::AddInternetPassword(
SecKeychainRef keychain,
UInt32 serverNameLength,
const char* serverName,
@ -80,14 +82,14 @@ OSStatus MacKeychain::AddInternetPassword(
itemRef);
}
OSStatus MacKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const {
OSStatus AppleKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const {
return SecKeychainFindGenericPassword(keychainOrArray,
serviceNameLength,
serviceName,
@ -98,19 +100,19 @@ OSStatus MacKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
itemRef);
}
OSStatus MacKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const {
OSStatus AppleKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const {
return SecKeychainItemFreeContent(attrList, data);
}
OSStatus MacKeychain::AddGenericPassword(SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const {
OSStatus AppleKeychain::AddGenericPassword(SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const {
return SecKeychainAddGenericPassword(keychain,
serviceNameLength,
serviceName,
@ -121,7 +123,7 @@ OSStatus MacKeychain::AddGenericPassword(SecKeychainRef keychain,
itemRef);
}
void MacKeychain::Free(CFTypeRef ref) const {
void AppleKeychain::Free(CFTypeRef ref) const {
if (ref)
CFRelease(ref);
}

@ -65,6 +65,13 @@
'symmetric_key_win.cc',
],
}],
[ 'OS != "mac" and OS != "ios"', {
'sources!': [
'apple_keychain.h',
'mock_apple_keychain.cc',
'mock_apple_keychain.h',
],
}],
[ 'OS == "android"', {
'dependencies': [
'../third_party/openssl/openssl.gyp:openssl',
@ -86,6 +93,12 @@
},
},
],
[ 'OS == "ios"', {
'sources!': [
# This class is stubbed out on iOS.
'rsa_private_key.cc',
],
}],
[ 'OS == "mac"', {
'link_settings': {
'libraries': [
@ -156,18 +169,13 @@
],
},],
],
'target_conditions' : [
[ 'OS == "ios"', {
'sources!': [
# This class is stubbed out on iOS.
'rsa_private_key.cc',
],
}],
],
'sources': [
# NOTE: all transitive dependencies of HMAC on windows need
# to be placed in the source list above.
'<@(hmac_win64_related_sources)',
'apple_keychain.h',
'apple_keychain_ios.mm',
'apple_keychain_mac.mm',
'capi_util.cc',
'capi_util.h',
'crypto_export.h',
@ -188,12 +196,12 @@
'encryptor_openssl.cc',
'hmac_nss.cc',
'hmac_openssl.cc',
'keychain_mac.cc',
'keychain_mac.h',
'mac_security_services_lock.cc',
'mac_security_services_lock.h',
'mock_keychain_mac.cc',
'mock_keychain_mac.h',
'mock_apple_keychain.cc',
'mock_apple_keychain.h',
'mock_apple_keychain_ios.cc',
'mock_apple_keychain_mac.cc',
'p224_spake.cc',
'p224_spake.h',
'nss_util.cc',

@ -0,0 +1,61 @@
// Copyright (c) 2012 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 "base/logging.h"
#include "base/time.h"
#include "crypto/mock_apple_keychain.h"
namespace crypto {
OSStatus MockAppleKeychain::FindGenericPassword(
CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const {
// When simulating |noErr|, return canned |passwordData| and
// |passwordLength|. Otherwise, just return given code.
if (find_generic_result_ == noErr) {
static const char kPassword[] = "my_password";
DCHECK(passwordData);
// The function to free this data is mocked so the cast is fine.
*passwordData = const_cast<char*>(kPassword);
DCHECK(passwordLength);
*passwordLength = arraysize(kPassword);
password_data_count_++;
}
return find_generic_result_;
}
OSStatus MockAppleKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const {
// No-op.
password_data_count_--;
return noErr;
}
OSStatus MockAppleKeychain::AddGenericPassword(
SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const {
called_add_generic_ = true;
DCHECK_GT(passwordLength, 0U);
DCHECK(passwordData);
add_generic_password_ =
std::string(const_cast<char*>(static_cast<const char*>(passwordData)),
passwordLength);
return noErr;
}
} // namespace crypto

@ -13,27 +13,47 @@
#include <vector>
#include "base/compiler_specific.h"
#include "crypto/keychain_mac.h"
#include "crypto/apple_keychain.h"
namespace crypto {
// Type used for the keys in the std::map(s) and MockKeychain items.
typedef uintptr_t MockKeychainItemType;
// Mock Keychain wrapper for testing code that interacts with the OS X
// Keychain. Implemented by storing SecKeychainAttributeList and
// KeychainPasswordData values in separate mutable containers and
// mapping them to integer keys.
//
// Note that "const" is pretty much meaningless for this class; the const-ness
// of MacKeychain doesn't apply to the actual keychain data, so all of the Mock
// data is mutable; don't assume that it won't change over the life of tests.
class CRYPTO_EXPORT MockKeychain : public MacKeychain {
// of AppleKeychain doesn't apply to the actual keychain data, so all of the
// Mock data is mutable; don't assume that it won't change over the life of
// tests.
class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain {
public:
MockKeychain();
virtual ~MockKeychain();
MockAppleKeychain();
virtual ~MockAppleKeychain();
// MacKeychain implementation.
// AppleKeychain implementation.
virtual OSStatus FindGenericPassword(
CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const OVERRIDE;
virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const OVERRIDE;
virtual OSStatus AddGenericPassword(
SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const OVERRIDE;
#if !defined(OS_IOS)
virtual OSStatus ItemCopyAttributesAndData(
SecKeychainItemRef itemRef,
SecKeychainAttributeInfo* info,
@ -72,26 +92,6 @@ class CRYPTO_EXPORT MockKeychain : public MacKeychain {
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const OVERRIDE;
virtual OSStatus FindGenericPassword(
CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const OVERRIDE;
virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const OVERRIDE;
virtual OSStatus AddGenericPassword(
SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const OVERRIDE;
virtual void Free(CFTypeRef ref) const OVERRIDE;
// Return the counts of objects returned by Create/Copy functions but never
@ -118,6 +118,7 @@ class CRYPTO_EXPORT MockKeychain : public MacKeychain {
};
// Adds a keychain item with the given info to the test set.
void AddTestItem(const KeychainTestData& item_data);
#endif // !defined(OS_IOS)
// |FindGenericPassword()| can return different results depending on user
// interaction with the system Keychain. For mocking purposes we allow the
@ -139,6 +140,15 @@ class CRYPTO_EXPORT MockKeychain : public MacKeychain {
int password_data_count() const { return password_data_count_; }
private:
// Type used for the keys in the std::map(s) and MockAppleKeychain items.
typedef uintptr_t MockKeychainItemType;
// Type of the map holding the mock keychain attributes.
typedef std::map<MockKeychainItemType, SecKeychainAttributeList>
MockKeychainAttributesMap;
#if !defined(OS_IOS)
// Returns true if the keychain already contains a password that matches the
// attributes provided.
bool AlreadyContainsInternetPassword(
@ -178,10 +188,9 @@ class CRYPTO_EXPORT MockKeychain : public MacKeychain {
void SetTestDataNegativeItem(MockKeychainItemType item, Boolean value);
void SetTestDataCreator(MockKeychainItemType item, OSType value);
// Sets the password data and length for the item-th test item.
void SetTestDataPasswordBytes(
MockKeychainItemType item,
const void* data,
size_t length);
void SetTestDataPasswordBytes(MockKeychainItemType item,
const void* data,
size_t length);
// Sets the password for the item-th test item. As with SetTestDataString,
// the data will not be null-terminated.
void SetTestDataPasswordString(MockKeychainItemType item, const char* value);
@ -199,11 +208,11 @@ class CRYPTO_EXPORT MockKeychain : public MacKeychain {
UInt32 length;
} KeychainPasswordData;
// Mutable because the MockKeychain API requires its internal keychain storage
// to be modifiable by users of this class.
// Mutable because the MockAppleKeychain API requires its internal keychain
// storage to be modifiable by users of this class.
mutable MockKeychainAttributesMap keychain_attr_list_;
mutable std::map<MockKeychainItemType,
SecKeychainAttributeList> keychain_attr_list_;
mutable std::map<MockKeychainItemType, KeychainPasswordData> keychain_data_;
KeychainPasswordData> keychain_data_;
mutable MockKeychainItemType next_item_key_;
// Tracks the items that should be returned in subsequent calls to
@ -221,6 +230,7 @@ class CRYPTO_EXPORT MockKeychain : public MacKeychain {
// Tracks which items (by key) were added with AddInternetPassword.
mutable std::set<MockKeychainItemType> added_via_api_;
#endif // !defined(OS_IOS)
// Result code for the |FindGenericPassword()| method.
OSStatus find_generic_result_;

@ -0,0 +1,20 @@
// Copyright (c) 2012 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 "base/logging.h"
#include "base/time.h"
#include "crypto/mock_apple_keychain.h"
namespace crypto {
MockAppleKeychain::MockAppleKeychain()
: find_generic_result_(noErr),
called_add_generic_(false),
password_data_count_(0) {
}
MockAppleKeychain::~MockAppleKeychain() {
}
} // namespace crypto

@ -4,15 +4,15 @@
#include "base/logging.h"
#include "base/time.h"
#include "crypto/mock_keychain_mac.h"
#include "crypto/mock_apple_keychain.h"
namespace crypto {
// static
const SecKeychainSearchRef MockKeychain::kDummySearchRef =
const SecKeychainSearchRef MockAppleKeychain::kDummySearchRef =
reinterpret_cast<SecKeychainSearchRef>(1000);
MockKeychain::MockKeychain()
MockAppleKeychain::MockAppleKeychain()
: next_item_key_(0),
search_copy_count_(0),
keychain_item_copy_count_(0),
@ -21,7 +21,7 @@ MockKeychain::MockKeychain()
called_add_generic_(false),
password_data_count_(0) {}
void MockKeychain::InitializeKeychainData(MockKeychainItemType key) const {
void MockAppleKeychain::InitializeKeychainData(MockKeychainItemType key) const {
UInt32 tags[] = { kSecAccountItemAttr,
kSecServerItemAttr,
kSecPortItemAttr,
@ -64,9 +64,10 @@ void MockKeychain::InitializeKeychainData(MockKeychainItemType key) const {
}
}
MockKeychain::~MockKeychain() {
for (std::map<MockKeychainItemType, SecKeychainAttributeList>::iterator it =
keychain_attr_list_.begin(); it != keychain_attr_list_.end(); ++it) {
MockAppleKeychain::~MockAppleKeychain() {
for (MockKeychainAttributesMap::iterator it = keychain_attr_list_.begin();
it != keychain_attr_list_.end();
++it) {
for (unsigned int i = 0; i < it->second.count; ++i) {
if (it->second.attr[i].data)
free(it->second.attr[i].data);
@ -79,7 +80,7 @@ MockKeychain::~MockKeychain() {
keychain_data_.clear();
}
SecKeychainAttribute* MockKeychain::AttributeWithTag(
SecKeychainAttribute* MockAppleKeychain::AttributeWithTag(
const SecKeychainAttributeList& attribute_list,
UInt32 tag) {
int attribute_index = -1;
@ -96,10 +97,10 @@ SecKeychainAttribute* MockKeychain::AttributeWithTag(
return &(attribute_list.attr[attribute_index]);
}
void MockKeychain::SetTestDataBytes(MockKeychainItemType item,
UInt32 tag,
const void* data,
size_t length) {
void MockAppleKeychain::SetTestDataBytes(MockKeychainItemType item,
UInt32 tag,
const void* data,
size_t length) {
SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
tag);
attribute->length = length;
@ -114,31 +115,30 @@ void MockKeychain::SetTestDataBytes(MockKeychainItemType item,
}
}
void MockKeychain::SetTestDataString(
MockKeychainItemType item,
UInt32 tag,
const char* value) {
void MockAppleKeychain::SetTestDataString(MockKeychainItemType item,
UInt32 tag,
const char* value) {
SetTestDataBytes(item, tag, value, value ? strlen(value) : 0);
}
void MockKeychain::SetTestDataPort(MockKeychainItemType item, UInt32 value) {
void MockAppleKeychain::SetTestDataPort(MockKeychainItemType item,
UInt32 value) {
SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
kSecPortItemAttr);
UInt32* data = static_cast<UInt32*>(attribute->data);
*data = value;
}
void MockKeychain::SetTestDataProtocol(MockKeychainItemType item,
SecProtocolType value) {
void MockAppleKeychain::SetTestDataProtocol(MockKeychainItemType item,
SecProtocolType value) {
SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
kSecProtocolItemAttr);
SecProtocolType* data = static_cast<SecProtocolType*>(attribute->data);
*data = value;
}
void MockKeychain::SetTestDataAuthType(
MockKeychainItemType item,
SecAuthenticationType value) {
void MockAppleKeychain::SetTestDataAuthType(MockKeychainItemType item,
SecAuthenticationType value) {
SecKeychainAttribute* attribute = AttributeWithTag(
keychain_attr_list_[item], kSecAuthenticationTypeItemAttr);
SecAuthenticationType* data = static_cast<SecAuthenticationType*>(
@ -146,24 +146,25 @@ void MockKeychain::SetTestDataAuthType(
*data = value;
}
void MockKeychain::SetTestDataNegativeItem(MockKeychainItemType item,
Boolean value) {
void MockAppleKeychain::SetTestDataNegativeItem(MockKeychainItemType item,
Boolean value) {
SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
kSecNegativeItemAttr);
Boolean* data = static_cast<Boolean*>(attribute->data);
*data = value;
}
void MockKeychain::SetTestDataCreator(MockKeychainItemType item, OSType value) {
void MockAppleKeychain::SetTestDataCreator(MockKeychainItemType item,
OSType value) {
SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
kSecCreatorItemAttr);
OSType* data = static_cast<OSType*>(attribute->data);
*data = value;
}
void MockKeychain::SetTestDataPasswordBytes(MockKeychainItemType item,
const void* data,
size_t length) {
void MockAppleKeychain::SetTestDataPasswordBytes(MockKeychainItemType item,
const void* data,
size_t length) {
keychain_data_[item].length = length;
if (length > 0) {
if (keychain_data_[item].data)
@ -175,13 +176,12 @@ void MockKeychain::SetTestDataPasswordBytes(MockKeychainItemType item,
}
}
void MockKeychain::SetTestDataPasswordString(
MockKeychainItemType item,
const char* value) {
void MockAppleKeychain::SetTestDataPasswordString(MockKeychainItemType item,
const char* value) {
SetTestDataPasswordBytes(item, value, value ? strlen(value) : 0);
}
OSStatus MockKeychain::ItemCopyAttributesAndData(
OSStatus MockAppleKeychain::ItemCopyAttributesAndData(
SecKeychainItemRef itemRef,
SecKeychainAttributeInfo* info,
SecItemClass* itemClass,
@ -207,7 +207,7 @@ OSStatus MockKeychain::ItemCopyAttributesAndData(
return noErr;
}
OSStatus MockKeychain::ItemModifyAttributesAndData(
OSStatus MockAppleKeychain::ItemModifyAttributesAndData(
SecKeychainItemRef itemRef,
const SecKeychainAttributeList* attrList,
UInt32 length,
@ -224,7 +224,7 @@ OSStatus MockKeychain::ItemModifyAttributesAndData(
if (keychain_attr_list_.find(key) == keychain_attr_list_.end())
return errSecInvalidItemRef;
MockKeychain* mutable_this = const_cast<MockKeychain*>(this);
MockAppleKeychain* mutable_this = const_cast<MockAppleKeychain*>(this);
if (attrList) {
for (UInt32 change_attr = 0; change_attr < attrList->count; ++change_attr) {
if (attrList->attr[change_attr].tag == kSecCreatorItemAttr) {
@ -240,14 +240,14 @@ OSStatus MockKeychain::ItemModifyAttributesAndData(
return noErr;
}
OSStatus MockKeychain::ItemFreeAttributesAndData(
OSStatus MockAppleKeychain::ItemFreeAttributesAndData(
SecKeychainAttributeList* attrList,
void* data) const {
--attribute_data_copy_count_;
return noErr;
}
OSStatus MockKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
OSStatus MockAppleKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
MockKeychainItemType key =
reinterpret_cast<MockKeychainItemType>(itemRef) - 1;
@ -265,7 +265,7 @@ OSStatus MockKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
return noErr;
}
OSStatus MockKeychain::SearchCreateFromAttributes(
OSStatus MockAppleKeychain::SearchCreateFromAttributes(
CFTypeRef keychainOrArray,
SecItemClass itemClass,
const SecKeychainAttributeList* attrList,
@ -273,8 +273,8 @@ OSStatus MockKeychain::SearchCreateFromAttributes(
// Figure out which of our mock items matches, and set up the array we'll use
// to generate results out of SearchCopyNext.
remaining_search_results_.clear();
for (std::map<MockKeychainItemType, SecKeychainAttributeList>::const_iterator
it = keychain_attr_list_.begin();
for (MockKeychainAttributesMap::const_iterator it =
keychain_attr_list_.begin();
it != keychain_attr_list_.end();
++it) {
bool mock_item_matches = true;
@ -298,7 +298,7 @@ OSStatus MockKeychain::SearchCreateFromAttributes(
return noErr;
}
bool MockKeychain::AlreadyContainsInternetPassword(
bool MockAppleKeychain::AlreadyContainsInternetPassword(
UInt32 serverNameLength,
const char* serverName,
UInt32 securityDomainLength,
@ -310,8 +310,8 @@ bool MockKeychain::AlreadyContainsInternetPassword(
UInt16 port,
SecProtocolType protocol,
SecAuthenticationType authenticationType) const {
for (std::map<MockKeychainItemType, SecKeychainAttributeList>::const_iterator
it = keychain_attr_list_.begin();
for (MockKeychainAttributesMap::const_iterator it =
keychain_attr_list_.begin();
it != keychain_attr_list_.end();
++it) {
SecKeychainAttribute* attribute;
@ -374,7 +374,7 @@ bool MockKeychain::AlreadyContainsInternetPassword(
return false;
}
OSStatus MockKeychain::AddInternetPassword(
OSStatus MockAppleKeychain::AddInternetPassword(
SecKeychainRef keychain,
UInt32 serverNameLength,
const char* serverName,
@ -411,7 +411,7 @@ OSStatus MockKeychain::AddInternetPassword(
// Initialize keychain data storage at the target location.
InitializeKeychainData(key);
MockKeychain* mutable_this = const_cast<MockKeychain*>(this);
MockAppleKeychain* mutable_this = const_cast<MockAppleKeychain*>(this);
mutable_this->SetTestDataBytes(key, kSecServerItemAttr, serverName,
serverNameLength);
mutable_this->SetTestDataBytes(key, kSecSecurityDomainItemAttr,
@ -441,8 +441,8 @@ OSStatus MockKeychain::AddInternetPassword(
return noErr;
}
OSStatus MockKeychain::SearchCopyNext(SecKeychainSearchRef searchRef,
SecKeychainItemRef* itemRef) const {
OSStatus MockAppleKeychain::SearchCopyNext(SecKeychainSearchRef searchRef,
SecKeychainItemRef* itemRef) const {
if (remaining_search_results_.empty())
return errSecItemNotFound;
MockKeychainItemType key = remaining_search_results_.front();
@ -452,55 +452,7 @@ OSStatus MockKeychain::SearchCopyNext(SecKeychainSearchRef searchRef,
return noErr;
}
OSStatus MockKeychain::FindGenericPassword(CFTypeRef keychainOrArray,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32* passwordLength,
void** passwordData,
SecKeychainItemRef* itemRef) const {
// When simulating |noErr| we return canned |passwordData| and
// |passwordLenght|. Otherwise, just return given code.
if (find_generic_result_ == noErr) {
static char password[] = "my_password";
DCHECK(passwordData);
*passwordData = static_cast<void*>(password);
DCHECK(passwordLength);
*passwordLength = strlen(password);
password_data_count_++;
}
return find_generic_result_;
}
OSStatus MockKeychain::ItemFreeContent(SecKeychainAttributeList* attrList,
void* data) const {
// No-op.
password_data_count_--;
return noErr;
}
OSStatus MockKeychain::AddGenericPassword(SecKeychainRef keychain,
UInt32 serviceNameLength,
const char* serviceName,
UInt32 accountNameLength,
const char* accountName,
UInt32 passwordLength,
const void* passwordData,
SecKeychainItemRef* itemRef) const {
called_add_generic_ = true;
DCHECK(passwordLength > 0);
DCHECK(passwordData);
add_generic_password_ =
std::string(const_cast<char*>(static_cast<const char*>(passwordData)),
passwordLength);
return noErr;
}
void MockKeychain::Free(CFTypeRef ref) const {
void MockAppleKeychain::Free(CFTypeRef ref) const {
if (!ref)
return;
@ -511,19 +463,19 @@ void MockKeychain::Free(CFTypeRef ref) const {
}
}
int MockKeychain::UnfreedSearchCount() const {
int MockAppleKeychain::UnfreedSearchCount() const {
return search_copy_count_;
}
int MockKeychain::UnfreedKeychainItemCount() const {
int MockAppleKeychain::UnfreedKeychainItemCount() const {
return keychain_item_copy_count_;
}
int MockKeychain::UnfreedAttributeDataCount() const {
int MockAppleKeychain::UnfreedAttributeDataCount() const {
return attribute_data_copy_count_;
}
bool MockKeychain::CreatorCodesSetForAddedItems() const {
bool MockAppleKeychain::CreatorCodesSetForAddedItems() const {
for (std::set<MockKeychainItemType>::const_iterator
i = added_via_api_.begin();
i != added_via_api_.end();
@ -537,7 +489,7 @@ bool MockKeychain::CreatorCodesSetForAddedItems() const {
return true;
}
void MockKeychain::AddTestItem(const KeychainTestData& item_data) {
void MockAppleKeychain::AddTestItem(const KeychainTestData& item_data) {
MockKeychainItemType key = next_item_key_++;
InitializeKeychainData(key);