Fix bug in load time stats.
[chromium-blink-merge.git] / crypto / mock_keychain_mac.h
blob36bb94fc0d34337a6f45b772a4f9a9ad7cb84d0b
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/keychain_mac.h"
18 namespace crypto {
20 // Type used for the keys in the std::map(s) and MockKeychain items.
21 typedef uintptr_t MockKeychainItemType;
23 // Mock Keychain wrapper for testing code that interacts with the OS X
24 // Keychain. Implemented by storing SecKeychainAttributeList and
25 // KeychainPasswordData values in separate mutable containers and
26 // mapping them to integer keys.
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
30 // data is mutable; don't assume that it won't change over the life of tests.
31 class CRYPTO_EXPORT MockKeychain : public MacKeychain {
32 public:
33 MockKeychain();
34 virtual ~MockKeychain();
36 // MacKeychain implementation.
37 virtual OSStatus ItemCopyAttributesAndData(
38 SecKeychainItemRef itemRef,
39 SecKeychainAttributeInfo* info,
40 SecItemClass* itemClass,
41 SecKeychainAttributeList** attrList,
42 UInt32* length,
43 void** outData) const OVERRIDE;
44 // Pass "fail_me" as the data to get errSecAuthFailed.
45 virtual OSStatus ItemModifyAttributesAndData(
46 SecKeychainItemRef itemRef,
47 const SecKeychainAttributeList* attrList,
48 UInt32 length,
49 const void* data) const OVERRIDE;
50 virtual OSStatus ItemFreeAttributesAndData(SecKeychainAttributeList* attrList,
51 void* data) const OVERRIDE;
52 virtual OSStatus ItemDelete(SecKeychainItemRef itemRef) const OVERRIDE;
53 virtual OSStatus SearchCreateFromAttributes(
54 CFTypeRef keychainOrArray,
55 SecItemClass itemClass,
56 const SecKeychainAttributeList* attrList,
57 SecKeychainSearchRef* searchRef) const OVERRIDE;
58 virtual OSStatus SearchCopyNext(SecKeychainSearchRef searchRef,
59 SecKeychainItemRef* itemRef) const OVERRIDE;
60 // Pass "some.domain.com" as the serverName to get errSecDuplicateItem.
61 virtual OSStatus AddInternetPassword(
62 SecKeychainRef keychain,
63 UInt32 serverNameLength,
64 const char* serverName,
65 UInt32 securityDomainLength,
66 const char* securityDomain,
67 UInt32 accountNameLength,
68 const char* accountName,
69 UInt32 pathLength, const char* path,
70 UInt16 port, SecProtocolType protocol,
71 SecAuthenticationType authenticationType,
72 UInt32 passwordLength,
73 const void* passwordData,
74 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;
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);
122 // |FindGenericPassword()| can return different results depending on user
123 // interaction with the system Keychain. For mocking purposes we allow the
124 // user of this class to specify the result code of the
125 // |FindGenericPassword()| call so we can simulate the result of different
126 // user interactions.
127 void set_find_generic_result(OSStatus result) {
128 find_generic_result_ = result;
131 // Returns the true if |AddGenericPassword()| was called.
132 bool called_add_generic() const { return called_add_generic_; }
134 // Returns the value of the password set when |AddGenericPassword()| was
135 // called.
136 std::string add_generic_password() const { return add_generic_password_; }
138 // Returns the number of allocations - deallocations for password data.
139 int password_data_count() const { return password_data_count_; }
141 private:
142 // Returns true if the keychain already contains a password that matches the
143 // attributes provided.
144 bool AlreadyContainsInternetPassword(
145 UInt32 serverNameLength,
146 const char* serverName,
147 UInt32 securityDomainLength,
148 const char* securityDomain,
149 UInt32 accountNameLength,
150 const char* accountName,
151 UInt32 pathLength,
152 const char* path,
153 UInt16 port,
154 SecProtocolType protocol,
155 SecAuthenticationType authenticationType) const;
156 // Initializes storage for keychain data at |key|.
157 void InitializeKeychainData(MockKeychainItemType key) const;
158 // Sets the data and length of |tag| in the item-th test item.
159 void SetTestDataBytes(
160 MockKeychainItemType item,
161 UInt32 tag,
162 const void* data,
163 size_t length);
164 // Sets the data and length of |tag| in the item-th test item based on
165 // |value|. The null-terminator will not be included; the Keychain Services
166 // docs don't indicate whether it is or not, so clients should not assume
167 // that it will be.
168 void SetTestDataString(MockKeychainItemType item,
169 UInt32 tag,
170 const char* value);
171 // 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
173 // set.
174 void SetTestDataPort(MockKeychainItemType item, UInt32 value);
175 void SetTestDataProtocol(MockKeychainItemType item, SecProtocolType value);
176 void SetTestDataAuthType(MockKeychainItemType item,
177 SecAuthenticationType value);
178 void SetTestDataNegativeItem(MockKeychainItemType item, Boolean value);
179 void SetTestDataCreator(MockKeychainItemType item, OSType value);
180 // Sets the password data and length for the item-th test item.
181 void SetTestDataPasswordBytes(
182 MockKeychainItemType item,
183 const void* data,
184 size_t length);
185 // Sets the password for the item-th test item. As with SetTestDataString,
186 // the data will not be null-terminated.
187 void SetTestDataPasswordString(MockKeychainItemType item, const char* value);
189 // Returns the address of the attribute in attribute_list with tag |tag|.
190 static SecKeychainAttribute* AttributeWithTag(
191 const SecKeychainAttributeList& attribute_list,
192 UInt32 tag);
194 static const SecKeychainSearchRef kDummySearchRef;
196 typedef struct KeychainPasswordData {
197 KeychainPasswordData() : data(NULL), length(0) {}
198 void* data;
199 UInt32 length;
200 } KeychainPasswordData;
202 // Mutable because the MockKeychain API requires its internal keychain storage
203 // to be modifiable by users of this class.
204 mutable std::map<MockKeychainItemType,
205 SecKeychainAttributeList> keychain_attr_list_;
206 mutable std::map<MockKeychainItemType, KeychainPasswordData> keychain_data_;
207 mutable MockKeychainItemType next_item_key_;
209 // Tracks the items that should be returned in subsequent calls to
210 // SearchCopyNext, based on the last call to SearchCreateFromAttributes.
211 // 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.
213 mutable std::vector<MockKeychainItemType> remaining_search_results_;
215 // 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
217 // real mistakes.
218 mutable int search_copy_count_;
219 mutable int keychain_item_copy_count_;
220 mutable int attribute_data_copy_count_;
222 // Tracks which items (by key) were added with AddInternetPassword.
223 mutable std::set<MockKeychainItemType> added_via_api_;
225 // Result code for the |FindGenericPassword()| method.
226 OSStatus find_generic_result_;
228 // Records whether |AddGenericPassword()| gets called.
229 mutable bool called_add_generic_;
231 // Tracks the allocations and frees of password data in |FindGenericPassword|
232 // and |ItemFreeContent|.
233 mutable int password_data_count_;
235 // Records the password being set when |AddGenericPassword()| gets called.
236 mutable std::string add_generic_password_;
239 } // namespace crypto
241 #endif // CRYPTO_MOCK_KEYCHAIN_MAC_H_