Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/time.h" | 6 #include "base/time.h" |
| 7 #include "chrome/browser/keychain_mock_mac.h" | 7 #include "chrome/browser/keychain_mock_mac.h" |
| 8 | 8 |
| 9 MockKeychain::MockKeychain(unsigned int item_capacity) | 9 MockKeychain::MockKeychain(unsigned int item_capacity) |
| 10 : item_capacity_(item_capacity), item_count_(0), search_copy_count_(0), | 10 : item_capacity_(item_capacity), item_count_(0), search_copy_count_(0), |
| 11 keychain_item_copy_count_(0), attribute_data_copy_count_(0) { | 11 keychain_item_copy_count_(0), attribute_data_copy_count_(0) { |
| 12 UInt32 tags[] = { kSecAccountItemAttr, | 12 UInt32 tags[] = { kSecAccountItemAttr, |
| 13 kSecServerItemAttr, | 13 kSecServerItemAttr, |
| 14 kSecPortItemAttr, | 14 kSecPortItemAttr, |
| 15 kSecPathItemAttr, | 15 kSecPathItemAttr, |
| 16 kSecProtocolItemAttr, | 16 kSecProtocolItemAttr, |
| 17 kSecAuthenticationTypeItemAttr, | 17 kSecAuthenticationTypeItemAttr, |
| 18 kSecSecurityDomainItemAttr, | 18 kSecSecurityDomainItemAttr, |
| 19 kSecCreationDateItemAttr, | 19 kSecCreationDateItemAttr, |
| 20 kSecNegativeItemAttr }; | 20 kSecNegativeItemAttr, |
| 21 kSecCreatorItemAttr }; | |
| 21 | 22 |
| 22 // Create the test keychain data storage. | 23 // Create the test keychain data storage. |
| 23 keychain_attr_list_ = static_cast<SecKeychainAttributeList*>( | 24 keychain_attr_list_ = static_cast<SecKeychainAttributeList*>( |
| 24 calloc(item_capacity_, sizeof(SecKeychainAttributeList))); | 25 calloc(item_capacity_, sizeof(SecKeychainAttributeList))); |
| 25 keychain_data_ = static_cast<KeychainPasswordData*>( | 26 keychain_data_ = static_cast<KeychainPasswordData*>( |
| 26 calloc(item_capacity_, sizeof(KeychainPasswordData))); | 27 calloc(item_capacity_, sizeof(KeychainPasswordData))); |
| 27 for (unsigned int i = 0; i < item_capacity_; ++i) { | 28 for (unsigned int i = 0; i < item_capacity_; ++i) { |
| 28 keychain_attr_list_[i].count = arraysize(tags); | 29 keychain_attr_list_[i].count = arraysize(tags); |
| 29 keychain_attr_list_[i].attr = static_cast<SecKeychainAttribute*>( | 30 keychain_attr_list_[i].attr = static_cast<SecKeychainAttribute*>( |
| 30 calloc(keychain_attr_list_[i].count, sizeof(SecKeychainAttribute))); | 31 calloc(keychain_attr_list_[i].count, sizeof(SecKeychainAttribute))); |
| 31 for (unsigned int j = 0; j < keychain_attr_list_[i].count; ++j) { | 32 for (unsigned int j = 0; j < keychain_attr_list_[i].count; ++j) { |
| 32 keychain_attr_list_[i].attr[j].tag = tags[j]; | 33 keychain_attr_list_[i].attr[j].tag = tags[j]; |
| 33 size_t data_size = 0; | 34 size_t data_size = 0; |
| 34 switch (tags[j]) { | 35 switch (tags[j]) { |
| 35 case kSecPortItemAttr: | 36 case kSecPortItemAttr: |
| 36 data_size = sizeof(UInt32); | 37 data_size = sizeof(UInt32); |
| 37 break; | 38 break; |
| 38 case kSecProtocolItemAttr: | 39 case kSecProtocolItemAttr: |
| 39 data_size = sizeof(SecProtocolType); | 40 data_size = sizeof(SecProtocolType); |
| 40 break; | 41 break; |
| 41 case kSecAuthenticationTypeItemAttr: | 42 case kSecAuthenticationTypeItemAttr: |
| 42 data_size = sizeof(SecAuthenticationType); | 43 data_size = sizeof(SecAuthenticationType); |
| 43 break; | 44 break; |
| 44 case kSecNegativeItemAttr: | 45 case kSecNegativeItemAttr: |
| 45 data_size = sizeof(Boolean); | 46 data_size = sizeof(Boolean); |
| 46 break; | 47 break; |
| 48 case kSecCreatorItemAttr: | |
| 49 data_size = sizeof(OSType); | |
| 50 break; | |
| 47 } | 51 } |
| 48 if (data_size > 0) { | 52 if (data_size > 0) { |
| 49 keychain_attr_list_[i].attr[j].length = data_size; | 53 keychain_attr_list_[i].attr[j].length = data_size; |
| 50 keychain_attr_list_[i].attr[j].data = calloc(1, data_size); | 54 keychain_attr_list_[i].attr[j].data = calloc(1, data_size); |
| 51 } | 55 } |
| 52 } | 56 } |
| 53 } | 57 } |
| 54 } | 58 } |
| 55 | 59 |
| 56 MockKeychain::~MockKeychain() { | 60 MockKeychain::~MockKeychain() { |
| 57 for (unsigned int i = 0; i < item_capacity_; ++i) { | 61 for (unsigned int i = 0; i < item_capacity_; ++i) { |
| 58 for (unsigned int j = 0; j < keychain_attr_list_[i].count; ++j) { | 62 for (unsigned int j = 0; j < keychain_attr_list_[i].count; ++j) { |
| 59 if (keychain_attr_list_[i].attr[j].data) { | 63 if (keychain_attr_list_[i].attr[j].data) { |
| 60 free(keychain_attr_list_[i].attr[j].data); | 64 free(keychain_attr_list_[i].attr[j].data); |
| 61 } | 65 } |
| 62 } | 66 } |
| 63 free(keychain_attr_list_[i].attr); | 67 free(keychain_attr_list_[i].attr); |
| 64 if (keychain_data_[i].data) { | 68 if (keychain_data_[i].data) { |
| 65 free(keychain_data_[i].data); | 69 free(keychain_data_[i].data); |
| 66 } | 70 } |
| 67 } | 71 } |
| 68 free(keychain_attr_list_); | 72 free(keychain_attr_list_); |
| 69 free(keychain_data_); | 73 free(keychain_data_); |
| 70 } | 74 } |
| 71 | 75 |
| 72 int MockKeychain::IndexForTag(const SecKeychainAttributeList& attribute_list, | 76 |
| 73 UInt32 tag) { | 77 SecKeychainAttribute* MockKeychain::AttributeWithTag( |
| 78 const SecKeychainAttributeList& attribute_list, UInt32 tag) { | |
| 79 int attribute_index = -1; | |
| 74 for (unsigned int i = 0; i < attribute_list.count; ++i) { | 80 for (unsigned int i = 0; i < attribute_list.count; ++i) { |
| 75 if (attribute_list.attr[i].tag == tag) { | 81 if (attribute_list.attr[i].tag == tag) { |
| 76 return i; | 82 attribute_index = i; |
| 83 break; | |
| 77 } | 84 } |
| 78 } | 85 } |
| 79 DCHECK(false); | 86 if (attribute_index == -1) { |
| 80 return -1; | 87 NOTREACHED(); |
|
Mark Mentovai
2009/07/02 03:03:33
Do we really need the NOTREACHED? You documented
| |
| 88 return NULL; | |
| 89 } | |
| 90 return &(attribute_list.attr[attribute_index]); | |
| 81 } | 91 } |
| 82 | 92 |
| 83 void MockKeychain::SetTestDataBytes(int item, UInt32 tag, const void* data, | 93 void MockKeychain::SetTestDataBytes(int item, UInt32 tag, const void* data, |
| 84 size_t length) { | 94 size_t length) { |
| 85 int attribute_index = IndexForTag(keychain_attr_list_[item], tag); | 95 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item], |
| 86 keychain_attr_list_[item].attr[attribute_index].length = length; | 96 tag); |
| 97 attribute->length = length; | |
| 87 if (length > 0) { | 98 if (length > 0) { |
| 88 if (keychain_attr_list_[item].attr[attribute_index].data) { | 99 if (attribute->data) { |
| 89 free(keychain_attr_list_[item].attr[attribute_index].data); | 100 free(attribute->data); |
| 90 } | 101 } |
| 91 keychain_attr_list_[item].attr[attribute_index].data = malloc(length); | 102 attribute->data = malloc(length); |
| 92 CHECK(keychain_attr_list_[item].attr[attribute_index].data); | 103 CHECK(attribute->data); |
| 93 memcpy(keychain_attr_list_[item].attr[attribute_index].data, data, length); | 104 memcpy(attribute->data, data, length); |
| 94 } else { | 105 } else { |
| 95 keychain_attr_list_[item].attr[attribute_index].data = NULL; | 106 attribute->data = NULL; |
| 96 } | 107 } |
| 97 } | 108 } |
| 98 | 109 |
| 99 void MockKeychain::SetTestDataString(int item, UInt32 tag, const char* value) { | 110 void MockKeychain::SetTestDataString(int item, UInt32 tag, const char* value) { |
| 100 SetTestDataBytes(item, tag, value, value ? strlen(value) : 0); | 111 SetTestDataBytes(item, tag, value, value ? strlen(value) : 0); |
| 101 } | 112 } |
| 102 | 113 |
| 103 void MockKeychain::SetTestDataPort(int item, UInt32 value) { | 114 void MockKeychain::SetTestDataPort(int item, UInt32 value) { |
| 104 int attribute_index = IndexForTag(keychain_attr_list_[item], | 115 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item], |
| 105 kSecPortItemAttr); | 116 kSecPortItemAttr); |
| 106 void* data = keychain_attr_list_[item].attr[attribute_index].data; | 117 UInt32* data = static_cast<UInt32*>(attribute->data); |
| 107 *(static_cast<UInt32*>(data)) = value; | 118 *data = value; |
| 108 } | 119 } |
| 109 | 120 |
| 110 void MockKeychain::SetTestDataProtocol(int item, SecProtocolType value) { | 121 void MockKeychain::SetTestDataProtocol(int item, SecProtocolType value) { |
| 111 int attribute_index = IndexForTag(keychain_attr_list_[item], | 122 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item], |
| 112 kSecProtocolItemAttr); | 123 kSecProtocolItemAttr); |
| 113 void* data = keychain_attr_list_[item].attr[attribute_index].data; | 124 SecProtocolType* data = static_cast<SecProtocolType*>(attribute->data); |
| 114 *(static_cast<SecProtocolType*>(data)) = value; | 125 *data = value; |
| 115 } | 126 } |
| 116 | 127 |
| 117 void MockKeychain::SetTestDataAuthType(int item, SecAuthenticationType value) { | 128 void MockKeychain::SetTestDataAuthType(int item, SecAuthenticationType value) { |
| 118 int attribute_index = IndexForTag(keychain_attr_list_[item], | 129 SecKeychainAttribute* attribute = AttributeWithTag( |
| 119 kSecAuthenticationTypeItemAttr); | 130 keychain_attr_list_[item], kSecAuthenticationTypeItemAttr); |
| 120 void* data = keychain_attr_list_[item].attr[attribute_index].data; | 131 SecAuthenticationType* data = static_cast<SecAuthenticationType*>( |
| 121 *(static_cast<SecAuthenticationType*>(data)) = value; | 132 attribute->data); |
| 133 *data = value; | |
| 122 } | 134 } |
| 123 | 135 |
| 124 void MockKeychain::SetTestDataNegativeItem(int item, Boolean value) { | 136 void MockKeychain::SetTestDataNegativeItem(int item, Boolean value) { |
| 125 int attribute_index = IndexForTag(keychain_attr_list_[item], | 137 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item], |
| 126 kSecNegativeItemAttr); | 138 kSecNegativeItemAttr); |
| 127 void* data = keychain_attr_list_[item].attr[attribute_index].data; | 139 Boolean* data = static_cast<Boolean*>(attribute->data); |
| 128 *(static_cast<Boolean*>(data)) = value; | 140 *data = value; |
| 141 } | |
| 142 | |
| 143 void MockKeychain::SetTestDataCreator(int item, OSType value) { | |
| 144 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[item], | |
| 145 kSecCreatorItemAttr); | |
| 146 OSType* data = static_cast<OSType*>(attribute->data); | |
| 147 *data = value; | |
| 129 } | 148 } |
| 130 | 149 |
| 131 void MockKeychain::SetTestDataPasswordBytes(int item, const void* data, | 150 void MockKeychain::SetTestDataPasswordBytes(int item, const void* data, |
| 132 size_t length) { | 151 size_t length) { |
| 133 keychain_data_[item].length = length; | 152 keychain_data_[item].length = length; |
| 134 if (length > 0) { | 153 if (length > 0) { |
| 135 if (keychain_data_[item].data) { | 154 if (keychain_data_[item].data) { |
| 136 free(keychain_data_[item].data); | 155 free(keychain_data_[item].data); |
| 137 } | 156 } |
| 138 keychain_data_[item].data = malloc(length); | 157 keychain_data_[item].data = malloc(length); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 if (length == strlen(fail_trigger) && | 197 if (length == strlen(fail_trigger) && |
| 179 memcmp(data, fail_trigger, length) == 0) { | 198 memcmp(data, fail_trigger, length) == 0) { |
| 180 return errSecAuthFailed; | 199 return errSecAuthFailed; |
| 181 } | 200 } |
| 182 | 201 |
| 183 unsigned int item_index = reinterpret_cast<unsigned int>(itemRef) - 1; | 202 unsigned int item_index = reinterpret_cast<unsigned int>(itemRef) - 1; |
| 184 if (item_index >= item_count_) { | 203 if (item_index >= item_count_) { |
| 185 return errSecInvalidItemRef; | 204 return errSecInvalidItemRef; |
| 186 } | 205 } |
| 187 | 206 |
| 207 MockKeychain* mutable_this = const_cast<MockKeychain*>(this); | |
| 188 if (attrList) { | 208 if (attrList) { |
| 189 NOTIMPLEMENTED(); | 209 for (UInt32 change_attr = 0; change_attr < attrList->count; ++change_attr) { |
| 210 if (attrList->attr[change_attr].tag == kSecCreatorItemAttr) { | |
| 211 void* data = attrList->attr[change_attr].data; | |
| 212 mutable_this->SetTestDataCreator(item_index, | |
| 213 *(static_cast<OSType*>(data))); | |
| 214 } else { | |
| 215 NOTIMPLEMENTED(); | |
| 216 } | |
| 217 } | |
| 190 } | 218 } |
| 191 if (data) { | 219 if (data) { |
| 192 MockKeychain* mutable_this = const_cast<MockKeychain*>(this); | |
| 193 mutable_this->SetTestDataPasswordBytes(item_index, data, length); | 220 mutable_this->SetTestDataPasswordBytes(item_index, data, length); |
| 194 } | 221 } |
| 195 return noErr; | 222 return noErr; |
| 196 } | 223 } |
| 197 | 224 |
| 198 OSStatus MockKeychain::ItemFreeAttributesAndData( | 225 OSStatus MockKeychain::ItemFreeAttributesAndData( |
| 199 SecKeychainAttributeList *attrList, | 226 SecKeychainAttributeList *attrList, |
| 200 void *data) const { | 227 void *data) const { |
| 201 --attribute_data_copy_count_; | 228 --attribute_data_copy_count_; |
| 202 return noErr; | 229 return noErr; |
| 203 } | 230 } |
| 204 | 231 |
| 205 OSStatus MockKeychain::SearchCreateFromAttributes( | 232 OSStatus MockKeychain::SearchCreateFromAttributes( |
| 206 CFTypeRef keychainOrArray, SecItemClass itemClass, | 233 CFTypeRef keychainOrArray, SecItemClass itemClass, |
| 207 const SecKeychainAttributeList *attrList, | 234 const SecKeychainAttributeList *attrList, |
| 208 SecKeychainSearchRef *searchRef) const { | 235 SecKeychainSearchRef *searchRef) const { |
| 209 // Figure out which of our mock items matches, and set up the array we'll use | 236 // Figure out which of our mock items matches, and set up the array we'll use |
| 210 // to generate results out of SearchCopyNext. | 237 // to generate results out of SearchCopyNext. |
| 211 remaining_search_results_.clear(); | 238 remaining_search_results_.clear(); |
| 212 for (unsigned int mock_item = 0; mock_item < item_count_; ++mock_item) { | 239 for (unsigned int mock_item = 0; mock_item < item_count_; ++mock_item) { |
| 213 bool mock_item_matches = true; | 240 bool mock_item_matches = true; |
| 214 for (UInt32 search_attr = 0; search_attr < attrList->count; ++search_attr) { | 241 for (UInt32 search_attr = 0; search_attr < attrList->count; ++search_attr) { |
| 215 int mock_attr = IndexForTag(keychain_attr_list_[mock_item], | |
| 216 attrList->attr[search_attr].tag); | |
| 217 SecKeychainAttribute* mock_attribute = | 242 SecKeychainAttribute* mock_attribute = |
| 218 &(keychain_attr_list_[mock_item].attr[mock_attr]); | 243 AttributeWithTag(keychain_attr_list_[mock_item], |
| 244 attrList->attr[search_attr].tag); | |
| 219 if (mock_attribute->length != attrList->attr[search_attr].length || | 245 if (mock_attribute->length != attrList->attr[search_attr].length || |
| 220 memcmp(mock_attribute->data, attrList->attr[search_attr].data, | 246 memcmp(mock_attribute->data, attrList->attr[search_attr].data, |
| 221 attrList->attr[search_attr].length) != 0) { | 247 attrList->attr[search_attr].length) != 0) { |
| 222 mock_item_matches = false; | 248 mock_item_matches = false; |
| 223 break; | 249 break; |
| 224 } | 250 } |
| 225 } | 251 } |
| 226 if (mock_item_matches) { | 252 if (mock_item_matches) { |
| 227 remaining_search_results_.push_back(mock_item); | 253 remaining_search_results_.push_back(mock_item); |
| 228 } | 254 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 passwordLength); | 296 passwordLength); |
| 271 base::Time::Exploded exploded_time; | 297 base::Time::Exploded exploded_time; |
| 272 base::Time::Now().UTCExplode(&exploded_time); | 298 base::Time::Now().UTCExplode(&exploded_time); |
| 273 char time_string[128]; | 299 char time_string[128]; |
| 274 snprintf(time_string, sizeof(time_string), "%04d%02d%02d%02d%02d%02dZ", | 300 snprintf(time_string, sizeof(time_string), "%04d%02d%02d%02d%02d%02dZ", |
| 275 exploded_time.year, exploded_time.month, exploded_time.day_of_month, | 301 exploded_time.year, exploded_time.month, exploded_time.day_of_month, |
| 276 exploded_time.hour, exploded_time.minute, exploded_time.second); | 302 exploded_time.hour, exploded_time.minute, exploded_time.second); |
| 277 mutable_this->SetTestDataString(target_item, kSecCreationDateItemAttr, | 303 mutable_this->SetTestDataString(target_item, kSecCreationDateItemAttr, |
| 278 time_string); | 304 time_string); |
| 279 | 305 |
| 306 added_via_api_.insert(target_item); | |
| 307 | |
| 280 if (itemRef) { | 308 if (itemRef) { |
| 281 *itemRef = reinterpret_cast<SecKeychainItemRef>(target_item + 1); | 309 *itemRef = reinterpret_cast<SecKeychainItemRef>(target_item + 1); |
| 310 ++keychain_item_copy_count_; | |
| 282 } | 311 } |
| 283 return noErr; | 312 return noErr; |
| 284 } | 313 } |
| 285 | 314 |
| 286 OSStatus MockKeychain::SearchCopyNext(SecKeychainSearchRef searchRef, | 315 OSStatus MockKeychain::SearchCopyNext(SecKeychainSearchRef searchRef, |
| 287 SecKeychainItemRef *itemRef) const { | 316 SecKeychainItemRef *itemRef) const { |
| 288 if (remaining_search_results_.empty()) { | 317 if (remaining_search_results_.empty()) { |
| 289 return errSecItemNotFound; | 318 return errSecItemNotFound; |
| 290 } | 319 } |
| 291 unsigned int index = remaining_search_results_.front(); | 320 unsigned int index = remaining_search_results_.front(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 312 } | 341 } |
| 313 | 342 |
| 314 int MockKeychain::UnfreedKeychainItemCount() const { | 343 int MockKeychain::UnfreedKeychainItemCount() const { |
| 315 return keychain_item_copy_count_; | 344 return keychain_item_copy_count_; |
| 316 } | 345 } |
| 317 | 346 |
| 318 int MockKeychain::UnfreedAttributeDataCount() const { | 347 int MockKeychain::UnfreedAttributeDataCount() const { |
| 319 return attribute_data_copy_count_; | 348 return attribute_data_copy_count_; |
| 320 } | 349 } |
| 321 | 350 |
| 351 bool MockKeychain::CreatorCodesSetForAddedItems() const { | |
| 352 for (std::set<unsigned int>::const_iterator i = added_via_api_.begin(); | |
| 353 i != added_via_api_.end(); ++i) { | |
| 354 SecKeychainAttribute* attribute = AttributeWithTag(keychain_attr_list_[*i], | |
| 355 kSecCreatorItemAttr); | |
| 356 OSType* data = static_cast<OSType*>(attribute->data); | |
| 357 if (*data == 0) { | |
|
Mark Mentovai
2009/07/02 03:03:33
Oh yeah. Much clearer this way.
| |
| 358 return false; | |
| 359 } | |
| 360 } | |
| 361 return true; | |
| 362 } | |
| 363 | |
| 322 void MockKeychain::AddTestItem(const KeychainTestData& item_data) { | 364 void MockKeychain::AddTestItem(const KeychainTestData& item_data) { |
| 323 unsigned int index = item_count_++; | 365 unsigned int index = item_count_++; |
| 324 CHECK(index < item_capacity_); | 366 CHECK(index < item_capacity_); |
| 325 | 367 |
| 326 SetTestDataAuthType(index, item_data.auth_type); | 368 SetTestDataAuthType(index, item_data.auth_type); |
| 327 SetTestDataString(index, kSecServerItemAttr, item_data.server); | 369 SetTestDataString(index, kSecServerItemAttr, item_data.server); |
| 328 SetTestDataProtocol(index, item_data.protocol); | 370 SetTestDataProtocol(index, item_data.protocol); |
| 329 SetTestDataString(index, kSecPathItemAttr, item_data.path); | 371 SetTestDataString(index, kSecPathItemAttr, item_data.path); |
| 330 SetTestDataPort(index, item_data.port); | 372 SetTestDataPort(index, item_data.port); |
| 331 SetTestDataString(index, kSecSecurityDomainItemAttr, | 373 SetTestDataString(index, kSecSecurityDomainItemAttr, |
| 332 item_data.security_domain); | 374 item_data.security_domain); |
| 333 SetTestDataString(index, kSecCreationDateItemAttr, item_data.creation_date); | 375 SetTestDataString(index, kSecCreationDateItemAttr, item_data.creation_date); |
| 334 SetTestDataString(index, kSecAccountItemAttr, item_data.username); | 376 SetTestDataString(index, kSecAccountItemAttr, item_data.username); |
| 335 SetTestDataPasswordString(index, item_data.password); | 377 SetTestDataPasswordString(index, item_data.password); |
| 336 SetTestDataNegativeItem(index, item_data.negative_item); | 378 SetTestDataNegativeItem(index, item_data.negative_item); |
| 337 } | 379 } |
| OLD | NEW |