From c5e30a0fa07ca9eaa44ddaf3b8ee6cb401556ada Mon Sep 17 00:00:00 2001 From: Julius Zint Date: Sun, 14 Feb 2021 17:40:11 +0100 Subject: [PATCH] The TouchID keypair can no be removed from the macOS keychain This is a good feature for security and stability. It gives users the option to prevent TouchID unlock for any previously unlocked database and it is also helpful in cases where only one part of the keypair is in the macOS keychain. --- MacPass/Base.lproj/IntegrationPreferences.xib | 84 ++++++++++++++----- MacPass/MPConstants.h | 7 ++ MacPass/MPConstants.m | 3 + MacPass/MPIntegrationPreferencesController.m | 29 +++++++ MacPass/MPPasswordInputController.m | 12 ++- 5 files changed, 109 insertions(+), 26 deletions(-) diff --git a/MacPass/Base.lproj/IntegrationPreferences.xib b/MacPass/Base.lproj/IntegrationPreferences.xib index 8705ad7d..63b9f590 100644 --- a/MacPass/Base.lproj/IntegrationPreferences.xib +++ b/MacPass/Base.lproj/IntegrationPreferences.xib @@ -27,19 +27,19 @@ - + - + - + - + - + Autotype might not work properly. Some issues where found that prevent Autotype or Global Autotype to work. Please run the Autotype Doctor to fix those issues. @@ -48,7 +48,7 @@ - + @@ -107,14 +107,14 @@ - + If enabled, a dialog will show up before Autotype is executed even if only a single match was found to prevent accidental input and wrong matches @@ -123,42 +123,42 @@ - + @@ -205,20 +205,20 @@ - + - + - + @@ -239,17 +239,57 @@ + + + + + + + + + + + + MacPass will no longer be able to unlock any Database with TouchID until it is successfully unlocked with the password and or keyfile. + + + + + + + + + + + + + + + + + + - + + - + diff --git a/MacPass/MPConstants.h b/MacPass/MPConstants.h index ef3e1577..de914f18 100644 --- a/MacPass/MPConstants.h +++ b/MacPass/MPConstants.h @@ -40,4 +40,11 @@ FOUNDATION_EXPORT NSString *const MPPluginUTI; FOUNDATION_EXPORT NSString *const MPBundleHelpURLKey; FOUNDATION_EXPORT NSString *const MPBundlePluginRepositoryURLKey; FOUNDATION_EXPORT NSString *const MPPluginCompatibilityURLKey; + +/** + Keychain Keys + */ +extern NSString *const TouchIdUnlockPublicKeyTag; +extern NSString *const TouchIdUnlockPrivateKeyTag; + #endif diff --git a/MacPass/MPConstants.m b/MacPass/MPConstants.m index 99041ee1..f4729f82 100644 --- a/MacPass/MPConstants.m +++ b/MacPass/MPConstants.m @@ -31,3 +31,6 @@ NSString *const MPBundleHelpURLKey = @"MPHelpURL"; NSString *const MPBundlePluginRepositoryURLKey = @"MPPluginRepositoryURL"; NSString *const MPPluginCompatibilityURLKey = @"MPPluginCompatibilityURLKey"; +NSString *const TouchIdUnlockPublicKeyTag = @"com.hicknhacksoftware.macpass.publickey"; +NSString *const TouchIdUnlockPrivateKeyTag = @"com.hicknhacksoftware.macpass.privatekey"; + diff --git a/MacPass/MPIntegrationPreferencesController.m b/MacPass/MPIntegrationPreferencesController.m index 8f6bb026..759612b6 100644 --- a/MacPass/MPIntegrationPreferencesController.m +++ b/MacPass/MPIntegrationPreferencesController.m @@ -24,6 +24,7 @@ #import "MPSettingsHelper.h" #import "MPIconHelper.h" #import "MPAutotypeDoctor.h" +#import "MPConstants.h" #import "DDHotKeyCenter.h" #import "DDHotKey+MacPassAdditions.h" @@ -129,4 +130,32 @@ - (void)runAutotypeDoctor:(id)sender { [MPAutotypeDoctor.defaultDoctor runChecksAndPresentResults]; } + +#pragma mark - +#pragma mark Keychain Actions +- (IBAction)RenewTouchIdKey:(id)sender { + NSData* publicKeyTag = [TouchIdUnlockPublicKeyTag dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *publicKeyQuery = @{ + (id)kSecClass: (id)kSecClassKey, + (id)kSecAttrApplicationTag: publicKeyTag, + (id)kSecReturnRef: @YES, + }; + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)publicKeyQuery); + if (status != errSecSuccess) { + NSString* description = (__bridge NSString*)SecCopyErrorMessageString(status, NULL); + NSLog(@"Error while trying to delete public key from Keychain: %@", description); + } + + NSData* privateKeyTag = [TouchIdUnlockPrivateKeyTag dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *privateKeyQuery = @{ + (id)kSecClass: (id)kSecClassKey, + (id)kSecAttrApplicationTag: privateKeyTag, + (id)kSecReturnRef: @YES, + }; + status = SecItemDelete((__bridge CFDictionaryRef)privateKeyQuery); + if (status != errSecSuccess) { + NSString* description = (__bridge NSString*)SecCopyErrorMessageString(status, NULL); + NSLog(@"Error while trying to delete private key from Keychain: %@", description); + } +} @end diff --git a/MacPass/MPPasswordInputController.m b/MacPass/MPPasswordInputController.m index 0241b151..6fdb30f0 100644 --- a/MacPass/MPPasswordInputController.m +++ b/MacPass/MPPasswordInputController.m @@ -28,6 +28,7 @@ #import "MPPathControl.h" #import "MPTouchBarButtonCreator.h" #import "MPSettingsHelper.h" +#import "MPConstants.h" #import "HNHUi/HNHUi.h" @@ -175,8 +176,8 @@ static NSMutableDictionary* touchIDSecuredPasswords; CFErrorRef error = NULL; NSString* publicKeyLabel = @"MacPass TouchID Feature Public Key"; NSString* privateKeyLabel = @"MacPass TouchID Feature Private Key"; - NSData* publicKeyTag = [@"com.hicknhacksoftware.macpass.publickey" dataUsingEncoding:NSUTF8StringEncoding]; - NSData* privateKeyTag = [@"com.hicknhacksoftware.macpass.privatekey" dataUsingEncoding:NSUTF8StringEncoding]; + NSData* publicKeyTag = [TouchIdUnlockPublicKeyTag dataUsingEncoding:NSUTF8StringEncoding]; + NSData* privateKeyTag = [TouchIdUnlockPrivateKeyTag dataUsingEncoding:NSUTF8StringEncoding]; SecAccessControlRef access = NULL; if (@available(macOS 10.13.4, *)) { SecAccessControlCreateFlags flags = kSecAccessControlBiometryCurrentSet; @@ -228,7 +229,7 @@ static NSMutableDictionary* touchIDSecuredPasswords; - (NSData*) _touchIdEncryptCompositeKey: (KPKCompositeKey*) compositeKey { NSData* encryptedKey = nil; NSData* keyData = [NSKeyedArchiver archivedDataWithRootObject:compositeKey]; - NSData* tag = [@"com.hicknhacksoftware.macpass.publickey" dataUsingEncoding:NSUTF8StringEncoding]; + NSData* tag = [TouchIdUnlockPublicKeyTag dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *getquery = @{ (id)kSecClass: (id)kSecClassKey, (id)kSecAttrApplicationTag: tag, @@ -265,7 +266,7 @@ static NSMutableDictionary* touchIDSecuredPasswords; - (KPKCompositeKey*) _touchIdDecryptCompositeKey: (NSData*) encryptedKey { KPKCompositeKey* result = nil; if(encryptedKey != nil) { - NSData* tag = [@"com.hicknhacksoftware.macpass.privatekey" dataUsingEncoding:NSUTF8StringEncoding]; + NSData* tag = [TouchIdUnlockPrivateKeyTag dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *queryPrivateKey = @{ (id)kSecClass: (id)kSecClassKey, (id)kSecAttrApplicationTag: tag, @@ -333,6 +334,9 @@ static NSMutableDictionary* touchIDSecuredPasswords; self.completionHandler(compositeKey, nil, false, &error); [self _showError:error]; } + else { + self.touchIdButton.hidden = true; + } } - (IBAction)touchIdEnabledChanged:(id)sender {