Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(326)

Side by Side Diff: crypto/mock_apple_keychain_mac.cc

Issue 2932473004: Remove depprecated methods in AppleKeychain. (Closed)
Patch Set: Clean up everything Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « crypto/mock_apple_keychain.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/time/time.h" 9 #include "base/time/time.h"
10 #include "crypto/mock_apple_keychain.h" 10 #include "crypto/mock_apple_keychain.h"
11 11
12 namespace crypto { 12 namespace crypto {
13 13
14 // static
15 const SecKeychainSearchRef MockAppleKeychain::kDummySearchRef =
16 reinterpret_cast<SecKeychainSearchRef>(1000);
17
18 MockAppleKeychain::MockAppleKeychain() 14 MockAppleKeychain::MockAppleKeychain()
19 : locked_(false), 15 : find_generic_result_(noErr),
20 next_item_key_(0),
21 search_copy_count_(0),
22 keychain_item_copy_count_(0),
23 attribute_data_copy_count_(0),
24 find_generic_result_(noErr),
25 called_add_generic_(false), 16 called_add_generic_(false),
26 password_data_count_(0) {} 17 password_data_count_(0) {}
27 18
28 void MockAppleKeychain::InitializeKeychainData(MockKeychainItemType key) const { 19 MockAppleKeychain::~MockAppleKeychain() {}
29 UInt32 tags[] = { kSecAccountItemAttr,
30 kSecServerItemAttr,
31 kSecPortItemAttr,
32 kSecPathItemAttr,
33 kSecProtocolItemAttr,
34 kSecAuthenticationTypeItemAttr,
35 kSecSecurityDomainItemAttr,
36 kSecCreationDateItemAttr,
37 kSecNegativeItemAttr,
38 kSecCreatorItemAttr };
39 keychain_attr_list_[key] = SecKeychainAttributeList();
40 keychain_data_[key] = KeychainPasswordData();
41 keychain_attr_list_[key].count = arraysize(tags);
42 keychain_attr_list_[key].attr = static_cast<SecKeychainAttribute*>(
43 calloc(keychain_attr_list_[key].count, sizeof(SecKeychainAttribute)));
44 for (unsigned int i = 0; i < keychain_attr_list_[key].count; ++i) {
45 keychain_attr_list_[key].attr[i].tag = tags[i];
46 size_t data_size = 0;
47 switch (tags[i]) {
48 case kSecPortItemAttr:
49 data_size = sizeof(UInt32);
50 break;
51 case kSecProtocolItemAttr:
52 data_size = sizeof(SecProtocolType);
53 break;
54 case kSecAuthenticationTypeItemAttr:
55 data_size = sizeof(SecAuthenticationType);
56 break;
57 case kSecNegativeItemAttr:
58 data_size = sizeof(Boolean);
59 break;
60 case kSecCreatorItemAttr:
61 data_size = sizeof(OSType);
62 break;
63 }
64 if (data_size > 0) {
65 keychain_attr_list_[key].attr[i].length = data_size;
66 keychain_attr_list_[key].attr[i].data = calloc(1, data_size);
67 }
68 }
69 }
70 20
71 MockAppleKeychain::~MockAppleKeychain() { 21 OSStatus MockAppleKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
72 for (MockKeychainAttributesMap::iterator it = keychain_attr_list_.begin();
73 it != keychain_attr_list_.end();
74 ++it) {
75 for (unsigned int i = 0; i < it->second.count; ++i) {
76 if (it->second.attr[i].data)
77 free(it->second.attr[i].data);
78 }
79 free(it->second.attr);
80 if (keychain_data_[it->first].data)
81 free(keychain_data_[it->first].data);
82 }
83 keychain_attr_list_.clear();
84 keychain_data_.clear();
85 }
86
87 SecKeychainAttribute* MockAppleKeychain::AttributeWithTag(
88 const SecKeychainAttributeList& attribute_list,
89 UInt32 tag) {
90 int attribute_index = -1;
91 for (unsigned int i = 0; i < attribute_list.count; ++i) {
92 if (attribute_list.attr[i].tag == tag) {
93 attribute_index = i;
94 break;
95 }
96 }
97 if (attribute_index == -1) {
98 NOTREACHED() << "Unsupported attribute: " << tag;
99 return NULL;
100 }
101 return &(attribute_list.attr[attribute_index]);
102 }
103
104 void MockAppleKeychain::SetTestDataBytes(MockKeychainItemType item,
105 UInt32 tag,
106 const void* data,
107 size_t length) {
108 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
109 tag);
110 attribute->length = length;
111 if (length > 0) {
112 if (attribute->data)
113 free(attribute->data);
114 attribute->data = malloc(length);
115 CHECK(attribute->data);
116 memcpy(attribute->data, data, length);
117 } else {
118 attribute->data = NULL;
119 }
120 }
121
122 void MockAppleKeychain::SetTestDataString(MockKeychainItemType item,
123 UInt32 tag,
124 const char* value) {
125 SetTestDataBytes(item, tag, value, value ? strlen(value) : 0);
126 }
127
128 void MockAppleKeychain::SetTestDataPort(MockKeychainItemType item,
129 UInt32 value) {
130 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
131 kSecPortItemAttr);
132 UInt32* data = static_cast<UInt32*>(attribute->data);
133 *data = value;
134 }
135
136 void MockAppleKeychain::SetTestDataProtocol(MockKeychainItemType item,
137 SecProtocolType value) {
138 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
139 kSecProtocolItemAttr);
140 SecProtocolType* data = static_cast<SecProtocolType*>(attribute->data);
141 *data = value;
142 }
143
144 void MockAppleKeychain::SetTestDataAuthType(MockKeychainItemType item,
145 SecAuthenticationType value) {
146 SecKeychainAttribute* attribute = AttributeWithTag(
147 keychain_attr_list_[item], kSecAuthenticationTypeItemAttr);
148 SecAuthenticationType* data = static_cast<SecAuthenticationType*>(
149 attribute->data);
150 *data = value;
151 }
152
153 void MockAppleKeychain::SetTestDataNegativeItem(MockKeychainItemType item,
154 Boolean value) {
155 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
156 kSecNegativeItemAttr);
157 Boolean* data = static_cast<Boolean*>(attribute->data);
158 *data = value;
159 }
160
161 void MockAppleKeychain::SetTestDataCreator(MockKeychainItemType item,
162 OSType value) {
163 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item],
164 kSecCreatorItemAttr);
165 OSType* data = static_cast<OSType*>(attribute->data);
166 *data = value;
167 }
168
169 void MockAppleKeychain::SetTestDataPasswordBytes(MockKeychainItemType item,
170 const void* data,
171 size_t length) {
172 keychain_data_[item].length = length;
173 if (length > 0) {
174 if (keychain_data_[item].data)
175 free(keychain_data_[item].data);
176 keychain_data_[item].data = malloc(length);
177 memcpy(keychain_data_[item].data, data, length);
178 } else {
179 keychain_data_[item].data = NULL;
180 }
181 }
182
183 void MockAppleKeychain::SetTestDataPasswordString(MockKeychainItemType item,
184 const char* value) {
185 SetTestDataPasswordBytes(item, value, value ? strlen(value) : 0);
186 }
187
188 OSStatus MockAppleKeychain::ItemCopyAttributesAndData(
189 SecKeychainItemRef itemRef,
190 SecKeychainAttributeInfo* info,
191 SecItemClass* itemClass,
192 SecKeychainAttributeList** attrList,
193 UInt32* length,
194 void** outData) const {
195 DCHECK(itemRef);
196 MockKeychainItemType key =
197 reinterpret_cast<MockKeychainItemType>(itemRef) - 1;
198 if (keychain_attr_list_.find(key) == keychain_attr_list_.end())
199 return errSecInvalidItemRef;
200
201 DCHECK(!itemClass); // itemClass not implemented in the Mock.
202 if (locked_ && outData)
203 return errSecAuthFailed;
204
205 if (attrList)
206 *attrList = &(keychain_attr_list_[key]);
207 if (outData) {
208 *outData = keychain_data_[key].data;
209 DCHECK(length);
210 *length = keychain_data_[key].length;
211 }
212
213 ++attribute_data_copy_count_;
214 return noErr; 22 return noErr;
215 } 23 }
216 24
217 OSStatus MockAppleKeychain::ItemModifyAttributesAndData(
218 SecKeychainItemRef itemRef,
219 const SecKeychainAttributeList* attrList,
220 UInt32 length,
221 const void* data) const {
222 DCHECK(itemRef);
223 if (locked_)
224 return errSecAuthFailed;
225 const char* fail_trigger = "fail_me";
226 if (length == strlen(fail_trigger) &&
227 memcmp(data, fail_trigger, length) == 0) {
228 return errSecAuthFailed;
229 }
230
231 MockKeychainItemType key =
232 reinterpret_cast<MockKeychainItemType>(itemRef) - 1;
233 if (keychain_attr_list_.find(key) == keychain_attr_list_.end())
234 return errSecInvalidItemRef;
235
236 MockAppleKeychain* mutable_this = const_cast<MockAppleKeychain*>(this);
237 if (attrList) {
238 for (UInt32 change_attr = 0; change_attr < attrList->count; ++change_attr) {
239 if (attrList->attr[change_attr].tag == kSecCreatorItemAttr) {
240 void* data = attrList->attr[change_attr].data;
241 mutable_this->SetTestDataCreator(key, *(static_cast<OSType*>(data)));
242 } else {
243 NOTIMPLEMENTED();
244 }
245 }
246 }
247 if (data)
248 mutable_this->SetTestDataPasswordBytes(key, data, length);
249 return noErr;
250 }
251
252 OSStatus MockAppleKeychain::ItemFreeAttributesAndData(
253 SecKeychainAttributeList* attrList,
254 void* data) const {
255 --attribute_data_copy_count_;
256 return noErr;
257 }
258
259 OSStatus MockAppleKeychain::ItemDelete(SecKeychainItemRef itemRef) const {
260 if (locked_)
261 return errSecAuthFailed;
262 MockKeychainItemType key =
263 reinterpret_cast<MockKeychainItemType>(itemRef) - 1;
264
265 for (unsigned int i = 0; i < keychain_attr_list_[key].count; ++i) {
266 if (keychain_attr_list_[key].attr[i].data)
267 free(keychain_attr_list_[key].attr[i].data);
268 }
269 free(keychain_attr_list_[key].attr);
270 if (keychain_data_[key].data)
271 free(keychain_data_[key].data);
272
273 keychain_attr_list_.erase(key);
274 keychain_data_.erase(key);
275 added_via_api_.erase(key);
276 return noErr;
277 }
278
279 OSStatus MockAppleKeychain::SearchCreateFromAttributes(
280 CFTypeRef keychainOrArray,
281 SecItemClass itemClass,
282 const SecKeychainAttributeList* attrList,
283 SecKeychainSearchRef* searchRef) const {
284 // Figure out which of our mock items matches, and set up the array we'll use
285 // to generate results out of SearchCopyNext.
286 remaining_search_results_.clear();
287 for (MockKeychainAttributesMap::const_iterator it =
288 keychain_attr_list_.begin();
289 it != keychain_attr_list_.end();
290 ++it) {
291 bool mock_item_matches = true;
292 for (UInt32 search_attr = 0; search_attr < attrList->count; ++search_attr) {
293 SecKeychainAttribute* mock_attribute =
294 AttributeWithTag(it->second, attrList->attr[search_attr].tag);
295 if (mock_attribute->length != attrList->attr[search_attr].length ||
296 memcmp(mock_attribute->data, attrList->attr[search_attr].data,
297 attrList->attr[search_attr].length) != 0) {
298 mock_item_matches = false;
299 break;
300 }
301 }
302 if (mock_item_matches)
303 remaining_search_results_.push_back(it->first);
304 }
305
306 DCHECK(searchRef);
307 *searchRef = kDummySearchRef;
308 ++search_copy_count_;
309 return noErr;
310 }
311
312 bool MockAppleKeychain::AlreadyContainsInternetPassword(
313 UInt32 serverNameLength,
314 const char* serverName,
315 UInt32 securityDomainLength,
316 const char* securityDomain,
317 UInt32 accountNameLength,
318 const char* accountName,
319 UInt32 pathLength,
320 const char* path,
321 UInt16 port,
322 SecProtocolType protocol,
323 SecAuthenticationType authenticationType) const {
324 for (MockKeychainAttributesMap::const_iterator it =
325 keychain_attr_list_.begin();
326 it != keychain_attr_list_.end();
327 ++it) {
328 SecKeychainAttribute* attribute;
329 attribute = AttributeWithTag(it->second, kSecServerItemAttr);
330 if ((attribute->length != serverNameLength) ||
331 (attribute->data == NULL && *serverName != '\0') ||
332 (attribute->data != NULL && *serverName == '\0') ||
333 strncmp(serverName,
334 (const char*) attribute->data,
335 serverNameLength) != 0) {
336 continue;
337 }
338 attribute = AttributeWithTag(it->second, kSecSecurityDomainItemAttr);
339 if ((attribute->length != securityDomainLength) ||
340 (attribute->data == NULL && *securityDomain != '\0') ||
341 (attribute->data != NULL && *securityDomain == '\0') ||
342 strncmp(securityDomain,
343 (const char*) attribute->data,
344 securityDomainLength) != 0) {
345 continue;
346 }
347 attribute = AttributeWithTag(it->second, kSecAccountItemAttr);
348 if ((attribute->length != accountNameLength) ||
349 (attribute->data == NULL && *accountName != '\0') ||
350 (attribute->data != NULL && *accountName == '\0') ||
351 strncmp(accountName,
352 (const char*) attribute->data,
353 accountNameLength) != 0) {
354 continue;
355 }
356 attribute = AttributeWithTag(it->second, kSecPathItemAttr);
357 if ((attribute->length != pathLength) ||
358 (attribute->data == NULL && *path != '\0') ||
359 (attribute->data != NULL && *path == '\0') ||
360 strncmp(path,
361 (const char*) attribute->data,
362 pathLength) != 0) {
363 continue;
364 }
365 attribute = AttributeWithTag(it->second, kSecPortItemAttr);
366 if ((attribute->data == NULL) ||
367 (port != *(static_cast<UInt32*>(attribute->data)))) {
368 continue;
369 }
370 attribute = AttributeWithTag(it->second, kSecProtocolItemAttr);
371 if ((attribute->data == NULL) ||
372 (protocol != *(static_cast<SecProtocolType*>(attribute->data)))) {
373 continue;
374 }
375 attribute = AttributeWithTag(it->second, kSecAuthenticationTypeItemAttr);
376 if ((attribute->data == NULL) ||
377 (authenticationType !=
378 *(static_cast<SecAuthenticationType*>(attribute->data)))) {
379 continue;
380 }
381 // The keychain already has this item, since all fields other than the
382 // password match.
383 return true;
384 }
385 return false;
386 }
387
388 OSStatus MockAppleKeychain::AddInternetPassword(
389 SecKeychainRef keychain,
390 UInt32 serverNameLength,
391 const char* serverName,
392 UInt32 securityDomainLength,
393 const char* securityDomain,
394 UInt32 accountNameLength,
395 const char* accountName,
396 UInt32 pathLength,
397 const char* path,
398 UInt16 port,
399 SecProtocolType protocol,
400 SecAuthenticationType authenticationType,
401 UInt32 passwordLength,
402 const void* passwordData,
403 SecKeychainItemRef* itemRef) const {
404 if (locked_)
405 return errSecAuthFailed;
406
407 // Check for the magic duplicate item trigger.
408 if (strcmp(serverName, "some.domain.com") == 0)
409 return errSecDuplicateItem;
410
411 // If the account already exists in the keychain, we don't add it.
412 if (AlreadyContainsInternetPassword(serverNameLength, serverName,
413 securityDomainLength, securityDomain,
414 accountNameLength, accountName,
415 pathLength, path,
416 port, protocol,
417 authenticationType)) {
418 return errSecDuplicateItem;
419 }
420
421 // Pick the next unused slot.
422 MockKeychainItemType key = next_item_key_++;
423
424 // Initialize keychain data storage at the target location.
425 InitializeKeychainData(key);
426
427 MockAppleKeychain* mutable_this = const_cast<MockAppleKeychain*>(this);
428 mutable_this->SetTestDataBytes(key, kSecServerItemAttr, serverName,
429 serverNameLength);
430 mutable_this->SetTestDataBytes(key, kSecSecurityDomainItemAttr,
431 securityDomain, securityDomainLength);
432 mutable_this->SetTestDataBytes(key, kSecAccountItemAttr, accountName,
433 accountNameLength);
434 mutable_this->SetTestDataBytes(key, kSecPathItemAttr, path, pathLength);
435 mutable_this->SetTestDataPort(key, port);
436 mutable_this->SetTestDataProtocol(key, protocol);
437 mutable_this->SetTestDataAuthType(key, authenticationType);
438 mutable_this->SetTestDataPasswordBytes(key, passwordData,
439 passwordLength);
440 base::Time::Exploded exploded_time;
441 base::Time::Now().UTCExplode(&exploded_time);
442 char time_string[128];
443 snprintf(time_string, sizeof(time_string), "%04d%02d%02d%02d%02d%02dZ",
444 exploded_time.year, exploded_time.month, exploded_time.day_of_month,
445 exploded_time.hour, exploded_time.minute, exploded_time.second);
446 mutable_this->SetTestDataString(key, kSecCreationDateItemAttr, time_string);
447
448 added_via_api_.insert(key);
449
450 if (itemRef) {
451 *itemRef = reinterpret_cast<SecKeychainItemRef>(key + 1);
452 ++keychain_item_copy_count_;
453 }
454 return noErr;
455 }
456
457 OSStatus MockAppleKeychain::SearchCopyNext(SecKeychainSearchRef searchRef,
458 SecKeychainItemRef* itemRef) const {
459 if (remaining_search_results_.empty())
460 return errSecItemNotFound;
461 MockKeychainItemType key = remaining_search_results_.front();
462 remaining_search_results_.erase(remaining_search_results_.begin());
463 *itemRef = reinterpret_cast<SecKeychainItemRef>(key + 1);
464 ++keychain_item_copy_count_;
465 return noErr;
466 }
467
468 void MockAppleKeychain::Free(CFTypeRef ref) const {
469 if (!ref)
470 return;
471
472 if (ref == kDummySearchRef) {
473 --search_copy_count_;
474 } else {
475 --keychain_item_copy_count_;
476 }
477 }
478
479 int MockAppleKeychain::UnfreedSearchCount() const {
480 return search_copy_count_;
481 }
482
483 int MockAppleKeychain::UnfreedKeychainItemCount() const {
484 return keychain_item_copy_count_;
485 }
486
487 int MockAppleKeychain::UnfreedAttributeDataCount() const {
488 return attribute_data_copy_count_;
489 }
490
491 bool MockAppleKeychain::CreatorCodesSetForAddedItems() const {
492 for (std::set<MockKeychainItemType>::const_iterator
493 i = added_via_api_.begin();
494 i != added_via_api_.end();
495 ++i) {
496 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[*i],
497 kSecCreatorItemAttr);
498 OSType* data = static_cast<OSType*>(attribute->data);
499 if (*data == 0)
500 return false;
501 }
502 return true;
503 }
504
505 void MockAppleKeychain::AddTestItem(const KeychainTestData& item_data) {
506 MockKeychainItemType key = next_item_key_++;
507
508 InitializeKeychainData(key);
509 SetTestDataAuthType(key, item_data.auth_type);
510 SetTestDataString(key, kSecServerItemAttr, item_data.server);
511 SetTestDataProtocol(key, item_data.protocol);
512 SetTestDataString(key, kSecPathItemAttr, item_data.path);
513 SetTestDataPort(key, item_data.port);
514 SetTestDataString(key, kSecSecurityDomainItemAttr,
515 item_data.security_domain);
516 SetTestDataString(key, kSecCreationDateItemAttr, item_data.creation_date);
517 SetTestDataString(key, kSecAccountItemAttr, item_data.username);
518 SetTestDataPasswordString(key, item_data.password);
519 SetTestDataNegativeItem(key, item_data.negative_item);
520 }
521
522 } // namespace crypto 25 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/mock_apple_keychain.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698