Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CRYPTO_MOCK_KEYCHAIN_MAC_H_ | 5 #ifndef CRYPTO_MOCK_KEYCHAIN_MAC_H_ |
| 6 #define CRYPTO_MOCK_KEYCHAIN_MAC_H_ | 6 #define CRYPTO_MOCK_KEYCHAIN_MAC_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| 11 #include <set> | 11 #include <set> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "crypto/keychain_mac.h" | 16 #include "crypto/apple_keychain.h" |
| 17 | 17 |
| 18 namespace crypto { | 18 namespace crypto { |
| 19 | 19 |
| 20 // Type used for the keys in the std::map(s) and MockKeychain items. | 20 // Type used for the keys in the std::map(s) and MockAppleKeychain items. |
| 21 typedef uintptr_t MockKeychainItemType; | 21 typedef uintptr_t MockKeychainItemType; |
| 22 | 22 |
| 23 // Type of the map holding the mock keychain attributes. | |
| 24 typedef std::map<MockKeychainItemType, SecKeychainAttributeList> | |
| 25 MockKeychainAttributesMap; | |
|
Ryan Sleevi
2012/08/29 01:18:38
This is an implementation detail of the MockAppleK
msarda
2012/08/29 11:58:27
Done.
| |
| 26 | |
| 23 // Mock Keychain wrapper for testing code that interacts with the OS X | 27 // Mock Keychain wrapper for testing code that interacts with the OS X |
| 24 // Keychain. Implemented by storing SecKeychainAttributeList and | 28 // Keychain. Implemented by storing SecKeychainAttributeList and |
| 25 // KeychainPasswordData values in separate mutable containers and | 29 // KeychainPasswordData values in separate mutable containers and |
| 26 // mapping them to integer keys. | 30 // mapping them to integer keys. |
| 27 // | 31 // |
| 28 // Note that "const" is pretty much meaningless for this class; the const-ness | 32 // Note that "const" is pretty much meaningless for this class; the const-ness |
| 29 // of MacKeychain doesn't apply to the actual keychain data, so all of the Mock | 33 // of AppleKeychain doesn't apply to the actual keychain data, so all of the |
| 30 // data is mutable; don't assume that it won't change over the life of tests. | 34 // Mock data is mutable; don't assume that it won't change over the life of |
| 31 class CRYPTO_EXPORT MockKeychain : public MacKeychain { | 35 // tests. |
| 36 class CRYPTO_EXPORT MockAppleKeychain : public AppleKeychain { | |
| 32 public: | 37 public: |
| 33 MockKeychain(); | 38 MockAppleKeychain(); |
| 34 virtual ~MockKeychain(); | 39 virtual ~MockAppleKeychain(); |
| 35 | 40 |
| 36 // MacKeychain implementation. | 41 // AppleKeychain implementation. |
| 42 virtual OSStatus FindGenericPassword( | |
| 43 CFTypeRef keychainOrArray, | |
| 44 UInt32 serviceNameLength, | |
| 45 const char* serviceName, | |
| 46 UInt32 accountNameLength, | |
| 47 const char* accountName, | |
| 48 UInt32* passwordLength, | |
| 49 void** passwordData, | |
| 50 SecKeychainItemRef* itemRef) const OVERRIDE; | |
| 51 virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList, | |
| 52 void* data) const OVERRIDE; | |
| 53 virtual OSStatus AddGenericPassword( | |
| 54 SecKeychainRef keychain, | |
| 55 UInt32 serviceNameLength, | |
| 56 const char* serviceName, | |
| 57 UInt32 accountNameLength, | |
| 58 const char* accountName, | |
| 59 UInt32 passwordLength, | |
| 60 const void* passwordData, | |
| 61 SecKeychainItemRef* itemRef) const OVERRIDE; | |
| 62 | |
| 63 #if !defined(OS_IOS) | |
| 37 virtual OSStatus ItemCopyAttributesAndData( | 64 virtual OSStatus ItemCopyAttributesAndData( |
| 38 SecKeychainItemRef itemRef, | 65 SecKeychainItemRef itemRef, |
| 39 SecKeychainAttributeInfo* info, | 66 SecKeychainAttributeInfo* info, |
| 40 SecItemClass* itemClass, | 67 SecItemClass* itemClass, |
| 41 SecKeychainAttributeList** attrList, | 68 SecKeychainAttributeList** attrList, |
| 42 UInt32* length, | 69 UInt32* length, |
| 43 void** outData) const OVERRIDE; | 70 void** outData) const OVERRIDE; |
| 44 // Pass "fail_me" as the data to get errSecAuthFailed. | 71 // Pass "fail_me" as the data to get errSecAuthFailed. |
| 45 virtual OSStatus ItemModifyAttributesAndData( | 72 virtual OSStatus ItemModifyAttributesAndData( |
| 46 SecKeychainItemRef itemRef, | 73 SecKeychainItemRef itemRef, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 65 UInt32 securityDomainLength, | 92 UInt32 securityDomainLength, |
| 66 const char* securityDomain, | 93 const char* securityDomain, |
| 67 UInt32 accountNameLength, | 94 UInt32 accountNameLength, |
| 68 const char* accountName, | 95 const char* accountName, |
| 69 UInt32 pathLength, const char* path, | 96 UInt32 pathLength, const char* path, |
| 70 UInt16 port, SecProtocolType protocol, | 97 UInt16 port, SecProtocolType protocol, |
| 71 SecAuthenticationType authenticationType, | 98 SecAuthenticationType authenticationType, |
| 72 UInt32 passwordLength, | 99 UInt32 passwordLength, |
| 73 const void* passwordData, | 100 const void* passwordData, |
| 74 SecKeychainItemRef* itemRef) const OVERRIDE; | 101 SecKeychainItemRef* itemRef) const OVERRIDE; |
| 75 virtual OSStatus FindGenericPassword( | |
| 76 CFTypeRef keychainOrArray, | |
| 77 UInt32 serviceNameLength, | |
| 78 const char* serviceName, | |
| 79 UInt32 accountNameLength, | |
| 80 const char* accountName, | |
| 81 UInt32* passwordLength, | |
| 82 void** passwordData, | |
| 83 SecKeychainItemRef* itemRef) const OVERRIDE; | |
| 84 virtual OSStatus ItemFreeContent(SecKeychainAttributeList* attrList, | |
| 85 void* data) const OVERRIDE; | |
| 86 virtual OSStatus AddGenericPassword( | |
| 87 SecKeychainRef keychain, | |
| 88 UInt32 serviceNameLength, | |
| 89 const char* serviceName, | |
| 90 UInt32 accountNameLength, | |
| 91 const char* accountName, | |
| 92 UInt32 passwordLength, | |
| 93 const void* passwordData, | |
| 94 SecKeychainItemRef* itemRef) const OVERRIDE; | |
| 95 virtual void Free(CFTypeRef ref) const OVERRIDE; | 102 virtual void Free(CFTypeRef ref) const OVERRIDE; |
| 96 | 103 |
| 97 // Return the counts of objects returned by Create/Copy functions but never | 104 // Return the counts of objects returned by Create/Copy functions but never |
| 98 // Free'd as they should have been. | 105 // Free'd as they should have been. |
| 99 int UnfreedSearchCount() const; | 106 int UnfreedSearchCount() const; |
| 100 int UnfreedKeychainItemCount() const; | 107 int UnfreedKeychainItemCount() const; |
| 101 int UnfreedAttributeDataCount() const; | 108 int UnfreedAttributeDataCount() const; |
| 102 | 109 |
| 103 // Returns true if all items added with AddInternetPassword have a creator | 110 // Returns true if all items added with AddInternetPassword have a creator |
| 104 // code set. | 111 // code set. |
| 105 bool CreatorCodesSetForAddedItems() const; | 112 bool CreatorCodesSetForAddedItems() const; |
| 106 | 113 |
| 107 struct KeychainTestData { | 114 struct KeychainTestData { |
| 108 const SecAuthenticationType auth_type; | 115 const SecAuthenticationType auth_type; |
| 109 const char* server; | 116 const char* server; |
| 110 const SecProtocolType protocol; | 117 const SecProtocolType protocol; |
| 111 const char* path; | 118 const char* path; |
| 112 const UInt32 port; | 119 const UInt32 port; |
| 113 const char* security_domain; | 120 const char* security_domain; |
| 114 const char* creation_date; | 121 const char* creation_date; |
| 115 const char* username; | 122 const char* username; |
| 116 const char* password; | 123 const char* password; |
| 117 const bool negative_item; | 124 const bool negative_item; |
| 118 }; | 125 }; |
| 119 // Adds a keychain item with the given info to the test set. | 126 // Adds a keychain item with the given info to the test set. |
| 120 void AddTestItem(const KeychainTestData& item_data); | 127 void AddTestItem(const KeychainTestData& item_data); |
| 128 #endif // !defined(OS_IOS) | |
| 121 | 129 |
| 122 // |FindGenericPassword()| can return different results depending on user | 130 // |FindGenericPassword()| can return different results depending on user |
| 123 // interaction with the system Keychain. For mocking purposes we allow the | 131 // interaction with the system Keychain. For mocking purposes we allow the |
| 124 // user of this class to specify the result code of the | 132 // user of this class to specify the result code of the |
| 125 // |FindGenericPassword()| call so we can simulate the result of different | 133 // |FindGenericPassword()| call so we can simulate the result of different |
| 126 // user interactions. | 134 // user interactions. |
| 127 void set_find_generic_result(OSStatus result) { | 135 void set_find_generic_result(OSStatus result) { |
| 128 find_generic_result_ = result; | 136 find_generic_result_ = result; |
| 129 } | 137 } |
| 130 | 138 |
| 131 // Returns the true if |AddGenericPassword()| was called. | 139 // Returns the true if |AddGenericPassword()| was called. |
| 132 bool called_add_generic() const { return called_add_generic_; } | 140 bool called_add_generic() const { return called_add_generic_; } |
| 133 | 141 |
| 134 // Returns the value of the password set when |AddGenericPassword()| was | 142 // Returns the value of the password set when |AddGenericPassword()| was |
| 135 // called. | 143 // called. |
| 136 std::string add_generic_password() const { return add_generic_password_; } | 144 std::string add_generic_password() const { return add_generic_password_; } |
| 137 | 145 |
| 138 // Returns the number of allocations - deallocations for password data. | 146 // Returns the number of allocations - deallocations for password data. |
| 139 int password_data_count() const { return password_data_count_; } | 147 int password_data_count() const { return password_data_count_; } |
| 140 | 148 |
| 141 private: | 149 private: |
| 150 | |
| 151 #if !defined(OS_IOS) | |
| 142 // Returns true if the keychain already contains a password that matches the | 152 // Returns true if the keychain already contains a password that matches the |
| 143 // attributes provided. | 153 // attributes provided. |
| 144 bool AlreadyContainsInternetPassword( | 154 bool AlreadyContainsInternetPassword( |
| 145 UInt32 serverNameLength, | 155 UInt32 serverNameLength, |
| 146 const char* serverName, | 156 const char* serverName, |
| 147 UInt32 securityDomainLength, | 157 UInt32 securityDomainLength, |
| 148 const char* securityDomain, | 158 const char* securityDomain, |
| 149 UInt32 accountNameLength, | 159 UInt32 accountNameLength, |
| 150 const char* accountName, | 160 const char* accountName, |
| 151 UInt32 pathLength, | 161 UInt32 pathLength, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 171 // Sets the data of the corresponding attribute of the item-th test item to | 181 // Sets the data of the corresponding attribute of the item-th test item to |
| 172 // |value|. Assumes that the space has alread been allocated, and the length | 182 // |value|. Assumes that the space has alread been allocated, and the length |
| 173 // set. | 183 // set. |
| 174 void SetTestDataPort(MockKeychainItemType item, UInt32 value); | 184 void SetTestDataPort(MockKeychainItemType item, UInt32 value); |
| 175 void SetTestDataProtocol(MockKeychainItemType item, SecProtocolType value); | 185 void SetTestDataProtocol(MockKeychainItemType item, SecProtocolType value); |
| 176 void SetTestDataAuthType(MockKeychainItemType item, | 186 void SetTestDataAuthType(MockKeychainItemType item, |
| 177 SecAuthenticationType value); | 187 SecAuthenticationType value); |
| 178 void SetTestDataNegativeItem(MockKeychainItemType item, Boolean value); | 188 void SetTestDataNegativeItem(MockKeychainItemType item, Boolean value); |
| 179 void SetTestDataCreator(MockKeychainItemType item, OSType value); | 189 void SetTestDataCreator(MockKeychainItemType item, OSType value); |
| 180 // Sets the password data and length for the item-th test item. | 190 // Sets the password data and length for the item-th test item. |
| 181 void SetTestDataPasswordBytes( | 191 void SetTestDataPasswordBytes(MockKeychainItemType item, |
| 182 MockKeychainItemType item, | 192 const void* data, |
| 183 const void* data, | 193 size_t length); |
| 184 size_t length); | |
| 185 // Sets the password for the item-th test item. As with SetTestDataString, | 194 // Sets the password for the item-th test item. As with SetTestDataString, |
| 186 // the data will not be null-terminated. | 195 // the data will not be null-terminated. |
| 187 void SetTestDataPasswordString(MockKeychainItemType item, const char* value); | 196 void SetTestDataPasswordString(MockKeychainItemType item, const char* value); |
| 188 | 197 |
| 189 // Returns the address of the attribute in attribute_list with tag |tag|. | 198 // Returns the address of the attribute in attribute_list with tag |tag|. |
| 190 static SecKeychainAttribute* AttributeWithTag( | 199 static SecKeychainAttribute* AttributeWithTag( |
| 191 const SecKeychainAttributeList& attribute_list, | 200 const SecKeychainAttributeList& attribute_list, |
| 192 UInt32 tag); | 201 UInt32 tag); |
| 193 | 202 |
| 194 static const SecKeychainSearchRef kDummySearchRef; | 203 static const SecKeychainSearchRef kDummySearchRef; |
| 195 | 204 |
| 196 typedef struct KeychainPasswordData { | 205 typedef struct KeychainPasswordData { |
| 197 KeychainPasswordData() : data(NULL), length(0) {} | 206 KeychainPasswordData() : data(NULL), length(0) {} |
| 198 void* data; | 207 void* data; |
| 199 UInt32 length; | 208 UInt32 length; |
| 200 } KeychainPasswordData; | 209 } KeychainPasswordData; |
| 201 | 210 |
| 202 // Mutable because the MockKeychain API requires its internal keychain storage | 211 // Mutable because the MockAppleKeychain API requires its internal keychain |
| 203 // to be modifiable by users of this class. | 212 // storage to be modifiable by users of this class. |
| 213 mutable MockKeychainAttributesMap keychain_attr_list_; | |
| 204 mutable std::map<MockKeychainItemType, | 214 mutable std::map<MockKeychainItemType, |
| 205 SecKeychainAttributeList> keychain_attr_list_; | 215 KeychainPasswordData> keychain_data_; |
| 206 mutable std::map<MockKeychainItemType, KeychainPasswordData> keychain_data_; | |
| 207 mutable MockKeychainItemType next_item_key_; | 216 mutable MockKeychainItemType next_item_key_; |
| 208 | 217 |
| 209 // Tracks the items that should be returned in subsequent calls to | 218 // Tracks the items that should be returned in subsequent calls to |
| 210 // SearchCopyNext, based on the last call to SearchCreateFromAttributes. | 219 // SearchCopyNext, based on the last call to SearchCreateFromAttributes. |
| 211 // We can't handle multiple active searches, since we don't track the search | 220 // We can't handle multiple active searches, since we don't track the search |
| 212 // ref we return, but we don't need to for our mocking. | 221 // ref we return, but we don't need to for our mocking. |
| 213 mutable std::vector<MockKeychainItemType> remaining_search_results_; | 222 mutable std::vector<MockKeychainItemType> remaining_search_results_; |
| 214 | 223 |
| 215 // Track copies and releases to make sure they balance. Really these should | 224 // Track copies and releases to make sure they balance. Really these should |
| 216 // be maps to track per item, but this should be good enough to catch | 225 // be maps to track per item, but this should be good enough to catch |
| 217 // real mistakes. | 226 // real mistakes. |
| 218 mutable int search_copy_count_; | 227 mutable int search_copy_count_; |
| 219 mutable int keychain_item_copy_count_; | 228 mutable int keychain_item_copy_count_; |
| 220 mutable int attribute_data_copy_count_; | 229 mutable int attribute_data_copy_count_; |
| 221 | 230 |
| 222 // Tracks which items (by key) were added with AddInternetPassword. | 231 // Tracks which items (by key) were added with AddInternetPassword. |
| 223 mutable std::set<MockKeychainItemType> added_via_api_; | 232 mutable std::set<MockKeychainItemType> added_via_api_; |
| 233 #endif // !defined(OS_IOS) | |
| 224 | 234 |
| 225 // Result code for the |FindGenericPassword()| method. | 235 // Result code for the |FindGenericPassword()| method. |
| 226 OSStatus find_generic_result_; | 236 OSStatus find_generic_result_; |
| 227 | 237 |
| 228 // Records whether |AddGenericPassword()| gets called. | 238 // Records whether |AddGenericPassword()| gets called. |
| 229 mutable bool called_add_generic_; | 239 mutable bool called_add_generic_; |
| 230 | 240 |
| 231 // Tracks the allocations and frees of password data in |FindGenericPassword| | 241 // Tracks the allocations and frees of password data in |FindGenericPassword| |
| 232 // and |ItemFreeContent|. | 242 // and |ItemFreeContent|. |
| 233 mutable int password_data_count_; | 243 mutable int password_data_count_; |
| 234 | 244 |
| 235 // Records the password being set when |AddGenericPassword()| gets called. | 245 // Records the password being set when |AddGenericPassword()| gets called. |
| 236 mutable std::string add_generic_password_; | 246 mutable std::string add_generic_password_; |
| 237 }; | 247 }; |
| 238 | 248 |
| 239 } // namespace crypto | 249 } // namespace crypto |
| 240 | 250 |
| 241 #endif // CRYPTO_MOCK_KEYCHAIN_MAC_H_ | 251 #endif // CRYPTO_MOCK_KEYCHAIN_MAC_H_ |
| OLD | NEW |