Upstream version 9.38.198.0
[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   // Type used for the keys in the std::map(s) and MockAppleKeychain items.
144   typedef uintptr_t MockKeychainItemType;
145
146   // Type of the map holding the mock keychain attributes.
147   typedef std::map<MockKeychainItemType, SecKeychainAttributeList>
148       MockKeychainAttributesMap;
149
150 #if !defined(OS_IOS)
151   // Returns true if the keychain already contains a password that matches the
152   // attributes provided.
153   bool AlreadyContainsInternetPassword(
154       UInt32 serverNameLength,
155       const char* serverName,
156       UInt32 securityDomainLength,
157       const char* securityDomain,
158       UInt32 accountNameLength,
159       const char* accountName,
160       UInt32 pathLength,
161       const char* path,
162       UInt16 port,
163       SecProtocolType protocol,
164       SecAuthenticationType authenticationType) const;
165   // Initializes storage for keychain data at |key|.
166   void InitializeKeychainData(MockKeychainItemType key) const;
167   // Sets the data and length of |tag| in the item-th test item.
168   void SetTestDataBytes(
169       MockKeychainItemType item,
170       UInt32 tag,
171       const void* data,
172       size_t length);
173   // Sets the data and length of |tag| in the item-th test item based on
174   // |value|. The null-terminator will not be included; the Keychain Services
175   // docs don't indicate whether it is or not, so clients should not assume
176   // that it will be.
177   void SetTestDataString(MockKeychainItemType item,
178                          UInt32 tag,
179                          const char* value);
180   // Sets the data of the corresponding attribute of the item-th test item to
181   // |value|. Assumes that the space has alread been allocated, and the length
182   // set.
183   void SetTestDataPort(MockKeychainItemType item, UInt32 value);
184   void SetTestDataProtocol(MockKeychainItemType item, SecProtocolType value);
185   void SetTestDataAuthType(MockKeychainItemType item,
186                            SecAuthenticationType value);
187   void SetTestDataNegativeItem(MockKeychainItemType item, Boolean value);
188   void SetTestDataCreator(MockKeychainItemType item, OSType value);
189   // Sets the password data and length for the item-th test item.
190   void SetTestDataPasswordBytes(MockKeychainItemType item,
191                                 const void* data,
192                                 size_t length);
193   // Sets the password for the item-th test item. As with SetTestDataString,
194   // the data will not be null-terminated.
195   void SetTestDataPasswordString(MockKeychainItemType item, const char* value);
196
197   // Returns the address of the attribute in attribute_list with tag |tag|.
198   static SecKeychainAttribute* AttributeWithTag(
199       const SecKeychainAttributeList& attribute_list,
200       UInt32 tag);
201
202   static const SecKeychainSearchRef kDummySearchRef;
203
204   typedef struct KeychainPasswordData {
205     KeychainPasswordData() : data(NULL), length(0) {}
206     void* data;
207     UInt32 length;
208   } KeychainPasswordData;
209
210   // Mutable because the MockAppleKeychain API requires its internal keychain
211   // storage to be modifiable by users of this class.
212   mutable MockKeychainAttributesMap keychain_attr_list_;
213   mutable std::map<MockKeychainItemType,
214                    KeychainPasswordData> keychain_data_;
215   mutable MockKeychainItemType next_item_key_;
216
217   // Tracks the items that should be returned in subsequent calls to
218   // SearchCopyNext, based on the last call to SearchCreateFromAttributes.
219   // We can't handle multiple active searches, since we don't track the search
220   // ref we return, but we don't need to for our mocking.
221   mutable std::vector<MockKeychainItemType> remaining_search_results_;
222
223   // Track copies and releases to make sure they balance. Really these should
224   // be maps to track per item, but this should be good enough to catch
225   // real mistakes.
226   mutable int search_copy_count_;
227   mutable int keychain_item_copy_count_;
228   mutable int attribute_data_copy_count_;
229
230   // Tracks which items (by key) were added with AddInternetPassword.
231   mutable std::set<MockKeychainItemType> added_via_api_;
232 #endif  // !defined(OS_IOS)
233
234   // Result code for the |FindGenericPassword()| method.
235   OSStatus find_generic_result_;
236
237   // Records whether |AddGenericPassword()| gets called.
238   mutable bool called_add_generic_;
239
240   // Tracks the allocations and frees of password data in |FindGenericPassword|
241   // and |ItemFreeContent|.
242   mutable int password_data_count_;
243
244   // Records the password being set when |AddGenericPassword()| gets called.
245   mutable std::string add_generic_password_;
246 };
247
248 }  // namespace crypto
249
250 #endif  // CRYPTO_MOCK_KEYCHAIN_MAC_H_