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