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