Skip to content

Commit

Permalink
Merge pull request #64 from square/federman/can_access_keychain_optim…
Browse files Browse the repository at this point in the history
…ization

Prevent canAccessKeychain from logging to the console. Improve performance in likely case.
  • Loading branch information
dfed committed Jan 4, 2016
2 parents eb066df + a5f9e83 commit 447c783
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Valet.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Valet'
s.version = '2.0.6'
s.version = '2.0.7'
s.license = 'Apache License, Version 2.0'
s.summary = 'Valet lets you securely store data in the iOS or OS X Keychain without knowing a thing about how the Keychain works. It\'s easy. We promise.'
s.homepage = 'https://github.com/square/Valet'
Expand Down
21 changes: 14 additions & 7 deletions Valet/VALValet.m
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,21 @@ - (BOOL)canAccessKeychain;
NSString *const canaryKey = @"VAL_KeychainCanaryUsername";
NSString *const canaryValue = @"VAL_KeychainCanaryPassword";

// Manually add the key to the keychain since we don't care about duplicates and are optimizing for speed.
NSMutableDictionary *query = [self.baseQuery mutableCopy];
[query addEntriesFromDictionary:[self _secItemFormatDictionaryWithKey:canaryKey]];
query[(__bridge id)kSecValueData] = [canaryValue dataUsingEncoding:NSUTF8StringEncoding];
(void)VALAtomicSecItemAdd((__bridge CFDictionaryRef)query, NULL);

NSString *const retrievedCanaryValue = [self stringForKey:canaryKey];
canAccessKeychain = [canaryValue isEqualToString:retrievedCanaryValue];
if ([canaryValue isEqualToString:retrievedCanaryValue]) {
canAccessKeychain = YES;

} else {
// Canary value can't be found. Manually add the value to see if we can pull it back out.
NSMutableDictionary *query = [self.baseQuery mutableCopy];
[query addEntriesFromDictionary:[self _secItemFormatDictionaryWithKey:canaryKey]];
query[(__bridge id)kSecValueData] = [canaryValue dataUsingEncoding:NSUTF8StringEncoding];
(void)VALAtomicSecItemAdd((__bridge CFDictionaryRef)query, NULL);

NSString *const retrievedCanaryValueAfterAdding = [self stringForKey:canaryKey];
canAccessKeychain = [canaryValue isEqualToString:retrievedCanaryValueAfterAdding];
}

}, self.lockForSetAndRemoveOperations);

return canAccessKeychain;
Expand Down
7 changes: 7 additions & 0 deletions ValetTests/ValetTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ - (void)test_canAccessKeychain;
#endif
}

- (void)test_canAccessKeychain_performance;
{
[self measureBlock:^{
[self.valet canAccessKeychain];
}];
}

- (void)test_stringForKey_retrievesString;
{
XCTAssertNil([self.valet stringForKey:self.key]);
Expand Down

0 comments on commit 447c783

Please sign in to comment.