diff options
author | msarda@chromium.org <msarda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 13:03:46 +0000 |
---|---|---|
committer | msarda@chromium.org <msarda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-30 13:03:46 +0000 |
commit | 982f1ab97f266866f5ea7cdf7980fb8c2685a713 (patch) | |
tree | 260c13aad3c10eb298e9d076917ba461a289b971 /crypto | |
parent | 57ed6c2888e68e0baa6919cee16b3c4726552e09 (diff) | |
download | chromium_src-982f1ab97f266866f5ea7cdf7980fb8c2685a713.zip chromium_src-982f1ab97f266866f5ea7cdf7980fb8c2685a713.tar.gz chromium_src-982f1ab97f266866f5ea7cdf7980fb8c2685a713.tar.bz2 |
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
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/apple_keychain.h (renamed from crypto/keychain_mac.h) | 58 | ||||
-rw-r--r-- | crypto/apple_keychain_ios.mm | 202 | ||||
-rw-r--r-- | crypto/apple_keychain_mac.mm (renamed from crypto/keychain_mac.cc) | 62 | ||||
-rw-r--r-- | crypto/crypto.gyp | 32 | ||||
-rw-r--r-- | crypto/mock_apple_keychain.cc | 61 | ||||
-rw-r--r-- | crypto/mock_apple_keychain.h (renamed from crypto/mock_keychain_mac.h) | 86 | ||||
-rw-r--r-- | crypto/mock_apple_keychain_ios.cc | 20 | ||||
-rw-r--r-- | crypto/mock_apple_keychain_mac.cc (renamed from crypto/mock_keychain_mac.cc) | 152 |
8 files changed, 468 insertions, 205 deletions
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); |