- add sources.
[platform/framework/web/crosswalk.git] / src / crypto / mock_apple_keychain.h
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.
4
5 #ifndef CRYPTO_MOCK_KEYCHAIN_MAC_H_
6 #define CRYPTO_MOCK_KEYCHAIN_MAC_H_
7
8 #include <stdint.h>
9
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
14
15 #include "base/compiler_specific.h"
16 #include "crypto/apple_keychain.h"
17
18 namespace crypto {
19
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.
24 //
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();
33
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;
55
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;
96
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;
102
103   // Returns true if all items added with AddInternetPassword have a creator
104   // code set.
105   bool CreatorCodesSetForAddedItems() const;
106
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;
118   };
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)
122
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;
130   }
131
132   // Returns the true if |AddGenericPassword()| was called.
133   bool called_add_generic() const { return called_add_generic_; }
134
135   // Returns the value of the password set when |AddGenericPassword()| was
136   // called.
137   std::string add_generic_password() const { return add_generic_password_; }
138
139   // Returns the number of allocations - deallocations for password data.
140   int password_data_count() const { return password_data_count_; }
141
142  private:
143
144   // Type used for the keys in the std::map(s) and MockAppleKeychain items.
145   typedef uintptr_t MockKeychainItemType;
146
147   // Type of the map holding the mock keychain attributes.
148   typedef std::map<MockKeychainItemType, SecKeychainAttributeList>
149       MockKeychainAttributesMap;
150
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);
197
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);
202
203   static const SecKeychainSearchRef kDummySearchRef;
204
205   typedef struct KeychainPasswordData {
206     KeychainPasswordData() : data(NULL), length(0) {}
207     void* data;
208     UInt32 length;
209   } KeychainPasswordData;
210
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_;
217
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_;
223
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_;
230
231   // Tracks which items (by key) were added with AddInternetPassword.
232   mutable std::set<MockKeychainItemType> added_via_api_;
233 #endif  // !defined(OS_IOS)
234
235   // Result code for the |FindGenericPassword()| method.
236   OSStatus find_generic_result_;
237
238   // Records whether |AddGenericPassword()| gets called.
239   mutable bool called_add_generic_;
240
241   // Tracks the allocations and frees of password data in |FindGenericPassword|
242   // and |ItemFreeContent|.
243   mutable int password_data_count_;
244
245   // Records the password being set when |AddGenericPassword()| gets called.
246   mutable std::string add_generic_password_;
247 };
248
249 }  // namespace crypto
250
251 #endif  // CRYPTO_MOCK_KEYCHAIN_MAC_H_