Skip to content
This repository has been archived by the owner on Aug 24, 2019. It is now read-only.

Added support for iOS 8/OS X 10.0 AccessControl (Touch ID) #76

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Added support for iOS 8/OS X 10.0 AccessControl (Touch ID) #76

wants to merge 6 commits into from

Conversation

liamnichols
Copy link

Please don't automatically merge this!

I've made some modifications to the SSKeychainQuery class by adding some additional properties and methods that essentially allow you to use Touch ID with SSKeychain.

The main change is that i've modified the save: method to support the kSecAttrAccessControl and kSecUseNoAuthenticationUI attributes allowing you to specify a SSKeychainAccessControl object via the new accessControl property (was wrapping this in an NSObject the best approach?).

I have also made changes to fetch: and fetchAll: allowing you to pass in the kSecUseOperationPrompt (displayed when Touch ID is presented) via useOperationPrompt.

Finally, I've added a update: method as there was no existing wrapper around SecItemUpdate().

With all the above changes, You can now do something like the following to protect items with Touch ID:

SSKeychainQuery *query = [SSKeychainQuery new];
query.service = @"SomeService";
query.account = @"SomeAccount";
query.password = @"SomePassword";
query.accessControl = [SSKeychainAccessControl accessControlWithAccessibility:SSKeychainAccessibilityWhenPasscodeSetThisDeviceOnly flags:SSKeychainCreateFlagUserPresence];

NSError *saveError = nil;
if (![query save:&saveError]) {
    NSLog(@"Failed to save item to the keychain: %@", saveError);
} else {
    NSLog(@"saved item successfully");
}

Then, you can fetch them like so:

SSKeychainQuery *query = [SSKeychainQuery new];
query.service = @"SomeService";
query.account = @"SomeAccount";
query.useOperationPrompt = @"A prompt displayed when Touch ID alert is shown";

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSError *fetchError = nil;
    if (![query fetch:&fetchError]) {
        NSLog(@"Failed to fetch item from the keychain: %@", fetchError);
        // `errSecAuthFailed` indicates that the user cancelled the prompt
    } else {
        NSLog(@"got password: %@", query.password);
    }
});

I've not really done much when it comes to maintaining backwards compatibility but I've tested my branch when compiled against the iOS 7 SDK and it still compiles but I would like it if somebody else could check over everything beforehand.

Apple Sample Code: https://developer.apple.com/library/prerelease/ios/samplecode/KeychainTouchID/Introduction/Intro.html

Let me know what you think.

Liam

liamnichols and others added 6 commits September 1, 2014 19:18
`SSKeychainCreateFlags` should use `NS_OPTIONS` not `NS_ENUM` so it can be correctly converted in Swift.
Correct enum for keychain create flags
@liamnichols
Copy link
Author

Any news on getting this merged into the main repo? We've used it in a couple of projects here now and things seem to be working pretty well.

Thanks

@soffes
Copy link
Owner

soffes commented Jan 17, 2015

@calebd can you review?

@alexruperez
Copy link

👍 Nice!

@pcsantana
Copy link

pcsantana commented Jul 5, 2016

How to use accessControl with touch id? I could not find anything about it. I would like to know if is there a way to handle the errors if touch id not matching. For example, if user tap on cancel button (in touch ID dialog).
Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants