summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/password_manager/encryptor_mac.mm6
-rw-r--r--chrome/browser/password_manager/encryptor_password_mac.h6
-rw-r--r--chrome/browser/password_manager/encryptor_password_mac.mm6
-rw-r--r--chrome/browser/password_manager/encryptor_password_mac_unittest.cc16
-rw-r--r--chrome/browser/password_manager/password_store_factory.cc8
-rw-r--r--chrome/browser/password_manager/password_store_mac.cc19
-rw-r--r--chrome/browser/password_manager/password_store_mac.h6
-rw-r--r--chrome/browser/password_manager/password_store_mac_internal.h22
-rw-r--r--chrome/browser/password_manager/password_store_mac_unittest.cc23
-rw-r--r--crypto/apple_keychain.h (renamed from crypto/keychain_mac.h)58
-rw-r--r--crypto/apple_keychain_ios.mm202
-rw-r--r--crypto/apple_keychain_mac.mm (renamed from crypto/keychain_mac.cc)62
-rw-r--r--crypto/crypto.gyp32
-rw-r--r--crypto/mock_apple_keychain.cc61
-rw-r--r--crypto/mock_apple_keychain.h (renamed from crypto/mock_keychain_mac.h)86
-rw-r--r--crypto/mock_apple_keychain_ios.cc20
-rw-r--r--crypto/mock_apple_keychain_mac.cc (renamed from crypto/mock_keychain_mac.cc)152
17 files changed, 525 insertions, 260 deletions
diff --git a/chrome/browser/password_manager/encryptor_mac.mm b/chrome/browser/password_manager/encryptor_mac.mm
index 00116fa..c7f1cd4 100644
--- a/chrome/browser/password_manager/encryptor_mac.mm
+++ b/chrome/browser/password_manager/encryptor_mac.mm
@@ -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();
}
diff --git a/chrome/browser/password_manager/encryptor_password_mac.h b/chrome/browser/password_manager/encryptor_password_mac.h
index bd8182d..475ae20 100644
--- a/chrome/browser/password_manager/encryptor_password_mac.h
+++ b/chrome/browser/password_manager/encryptor_password_mac.h
@@ -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__
diff --git a/chrome/browser/password_manager/encryptor_password_mac.mm b/chrome/browser/password_manager/encryptor_password_mac.mm
index 9b5c23a..d472fad 100644
--- a/chrome/browser/password_manager/encryptor_password_mac.mm
+++ b/chrome/browser/password_manager/encryptor_password_mac.mm
@@ -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.
diff --git a/chrome/browser/password_manager/encryptor_password_mac_unittest.cc b/chrome/browser/password_manager/encryptor_password_mac_unittest.cc
index 284b881..f7b211a 100644
--- a/chrome/browser/password_manager/encryptor_password_mac_unittest.cc
+++ b/chrome/browser/password_manager/encryptor_password_mac_unittest.cc
@@ -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();
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index b110cb5d..a46d809 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -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
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
index 2b23db8..a1cb791 100644
--- a/chrome/browser/password_manager/password_store_mac.cc
+++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -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());
diff --git a/chrome/browser/password_manager/password_store_mac.h b/chrome/browser/password_manager/password_store_mac.h
index 36df2ba..3974ecb 100644
--- a/chrome/browser/password_manager/password_store_mac.h
+++ b/chrome/browser/password_manager/password_store_mac.h
@@ -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.
diff --git a/chrome/browser/password_manager/password_store_mac_internal.h b/chrome/browser/password_manager/password_store_mac_internal.h
index d3e8bca..b287557 100644
--- a/chrome/browser/password_manager/password_store_mac_internal.h
+++ b/chrome/browser/password_manager/password_store_mac_internal.h
@@ -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
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc
index f3fc3cb..be42d3b 100644
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -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
diff --git a/crypto/keychain_mac.h b/crypto/apple_keychain.h
index bbcf8b1..840ccee8 100644
--- a/crypto/keychain_mac.h
+++ b/crypto/apple_keychain.h
@@ -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
diff --git a/crypto/apple_keychain_ios.mm b/crypto/apple_keychain_ios.mm
new file mode 100644
index 0000000..1a4c9d5
--- /dev/null
+++ b/crypto/apple_keychain_ios.mm
@@ -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
diff --git a/crypto/keychain_mac.cc b/crypto/apple_keychain_mac.mm
index 4d5715b..545be19 100644
--- a/crypto/keychain_mac.cc
+++ b/crypto/apple_keychain_mac.mm
@@ -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);
}
diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp
index 40606a7..c9313080 100644
--- a/crypto/crypto.gyp
+++ b/crypto/crypto.gyp
@@ -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',
diff --git a/crypto/mock_apple_keychain.cc b/crypto/mock_apple_keychain.cc
new file mode 100644
index 0000000..bcabab8
--- /dev/null
+++ b/crypto/mock_apple_keychain.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
diff --git a/crypto/mock_keychain_mac.h b/crypto/mock_apple_keychain.h
index 36bb94f..efbb438 100644
--- a/crypto/mock_keychain_mac.h
+++ b/crypto/mock_apple_keychain.h
@@ -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();
+
+ // 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;
- // MacKeychain implementation.
+#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_;
diff --git a/crypto/mock_apple_keychain_ios.cc b/crypto/mock_apple_keychain_ios.cc
new file mode 100644
index 0000000..f94a80d
--- /dev/null
+++ b/crypto/mock_apple_keychain_ios.cc
@@ -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
diff --git a/crypto/mock_keychain_mac.cc b/crypto/mock_apple_keychain_mac.cc
index f8c6c97..181f108 100644
--- a/crypto/mock_keychain_mac.cc
+++ b/crypto/mock_apple_keychain_mac.cc
@@ -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);