From 07c8ed925b0dcbaed78711cf63b8b48715df42ce Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Tue, 16 Feb 2016 14:06:08 -0800 Subject: [PATCH] Treat authentication failures like a user cancel Addresses #72 --- Valet.podspec | 2 +- Valet/VALSecureEnclaveValet.h | 10 ++++------ Valet/VALSecureEnclaveValet.m | 4 ++-- .../ValetSecureElementTestViewController.m | 2 ++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Valet.podspec b/Valet.podspec index cd5543ff..26b67d68 100644 --- a/Valet.podspec +++ b/Valet.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Valet' - s.version = '2.2.0' + s.version = '2.2.1' 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' diff --git a/Valet/VALSecureEnclaveValet.h b/Valet/VALSecureEnclaveValet.h index dfb328a1..93e6100a 100644 --- a/Valet/VALSecureEnclaveValet.h +++ b/Valet/VALSecureEnclaveValet.h @@ -63,25 +63,23 @@ typedef NS_ENUM(NSUInteger, VALAccessControl) { @property (readonly) VALAccessControl accessControl; /// Convenience method for retrieving data from the keychain with a user prompt. -/// @param userPrompt The prompt displayed to the user in Apple's Touch ID and passcode entry UI. -/// @return The object currently stored in the keychain for the provided key. Returns nil if no string exists in the keychain for the specified key, or if the keychain is inaccessible. +/// @see -[VALSecureEnclave objectForKey:userPrompt:userCancelled:] - (nullable NSData *)objectForKey:(nonnull NSString *)key userPrompt:(nullable NSString *)userPrompt; /// Convenience method for retrieving data from the keychain with a user prompt. /// @param userPrompt The prompt displayed to the user in Apple's Touch ID and passcode entry UI. /// @param userCancelled A pointer to a BOOL which will be set to YES if the user cancels out of Touch ID or entering the device Passcode. -/// @return The object currently stored in the keychain for the provided key. Returns nil if no string exists in the keychain for the specified key, or if the keychain is inaccessible. +/// @return The object currently stored in the keychain for the provided key. Returns nil if no object exists in the keychain for the specified key, if the keychain is inaccessible, or if the user cancels out of the authentication UI. - (nullable NSData *)objectForKey:(nonnull NSString *)key userPrompt:(nullable NSString *)userPrompt userCancelled:(nullable inout BOOL *)userCancelled; /// Convenience method for retrieving a string from the keychain with a user prompt. -/// @param userPrompt The prompt displayed to the user in Apple's Touch ID and passcode entry UI. -/// @return The string currently stored in the keychain for the provided key. Returns nil if no string exists in the keychain for the specified key, or if the keychain is inaccessible. +/// @see -[VALSecureEnclave stringForKey:userPrompt:userCancelled:] - (nullable NSString *)stringForKey:(nonnull NSString *)key userPrompt:(nullable NSString *)userPrompt; /// Convenience method for retrieving a string from the keychain with a user prompt. /// @param userPrompt The prompt displayed to the user in Apple's Touch ID and passcode entry UI. /// @param userCancelled A pointer to a BOOL which will be set to YES if the user cancels out of Touch ID or entering the device Passcode. -/// @return The string currently stored in the keychain for the provided key. Returns nil if no string exists in the keychain for the specified key, or if the keychain is inaccessible. +/// @return The string currently stored in the keychain for the provided key. Returns nil if no string exists in the keychain for the specified key, if the keychain is inaccessible, or if the user cancels out of the authentication UI. - (nullable NSString *)stringForKey:(nonnull NSString *)key userPrompt:(nullable NSString *)userPrompt userCancelled:(nullable inout BOOL *)userCancelled; /// This method is not supported on VALSecureEnclaveValet. diff --git a/Valet/VALSecureEnclaveValet.m b/Valet/VALSecureEnclaveValet.m index 0805d14c..ebf021b1 100644 --- a/Valet/VALSecureEnclaveValet.m +++ b/Valet/VALSecureEnclaveValet.m @@ -308,7 +308,7 @@ - (nullable NSData *)objectForKey:(nonnull NSString *)key userPrompt:(nullable N OSStatus status = errSecSuccess; NSData *const objectForKey = [self objectForKey:key options:[self _optionsDictionaryForUserPrompt:userPrompt] status:&status]; if (userCancelled != NULL) { - *userCancelled = (status == errSecUserCanceled); + *userCancelled = (status == errSecUserCanceled || status == errSecAuthFailed); } return objectForKey; @@ -324,7 +324,7 @@ - (nullable NSString *)stringForKey:(nonnull NSString *)key userPrompt:(nullable OSStatus status = errSecSuccess; NSString *const stringForKey = [self stringForKey:key options:[self _optionsDictionaryForUserPrompt:userPrompt] status:&status]; if (userCancelled != NULL) { - *userCancelled = (status == errSecUserCanceled); + *userCancelled = (status == errSecUserCanceled || status == errSecAuthFailed); } return stringForKey; diff --git a/ValetTouchIDTest/ValetSecureElementTestViewController.m b/ValetTouchIDTest/ValetSecureElementTestViewController.m index 0618eea1..f937d171 100644 --- a/ValetTouchIDTest/ValetSecureElementTestViewController.m +++ b/ValetTouchIDTest/ValetSecureElementTestViewController.m @@ -60,6 +60,8 @@ - (IBAction)getItem:(id)sender; if (userCancelled) { self.textView.text = [self.textView.text stringByAppendingFormat:@"\n%s user cancelled TouchID", __PRETTY_FUNCTION__]; + } else if (password == nil) { + self.textView.text = [self.textView.text stringByAppendingFormat:@"\n%s object not found", __PRETTY_FUNCTION__]; } else { self.textView.text = [self.textView.text stringByAppendingFormat:@"\n%s %@", __PRETTY_FUNCTION__, password]; }