Support for storing multiple biometric integrity states for iOS (#1110)

* support for storing multiple biometric integrity states for iOS

* remove unused var & save new extension bio state upon password validation
This commit is contained in:
Matt Portune 2020-10-07 12:18:36 -04:00 committed by GitHub
parent 8f533bc576
commit 37e19d9a60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 12 deletions

View File

@ -30,8 +30,9 @@ namespace Bit.Droid.Services
_keystore.Load(null); _keystore.Load(null);
} }
public Task<bool> SetupBiometricAsync() public Task<bool> SetupBiometricAsync(string bioIntegrityKey = null)
{ {
// bioIntegrityKey used in iOS only
if (Build.VERSION.SdkInt >= BuildVersionCodes.M) if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{ {
CreateKey(); CreateKey();
@ -40,8 +41,9 @@ namespace Bit.Droid.Services
return Task.FromResult(true); return Task.FromResult(true);
} }
public Task<bool> ValidateIntegrityAsync() public Task<bool> ValidateIntegrityAsync(string bioIntegrityKey = null)
{ {
// bioIntegrityKey used in iOS only
if (Build.VERSION.SdkInt < BuildVersionCodes.M) if (Build.VERSION.SdkInt < BuildVersionCodes.M)
{ {
return Task.FromResult(true); return Task.FromResult(true);

View File

@ -4,7 +4,7 @@ namespace Bit.Core.Abstractions
{ {
public interface IBiometricService public interface IBiometricService
{ {
Task<bool> SetupBiometricAsync(); Task<bool> SetupBiometricAsync(string bioIntegrityKey = null);
Task<bool> ValidateIntegrityAsync(); Task<bool> ValidateIntegrityAsync(string bioIntegrityKey = null);
} }
} }

View File

@ -7,7 +7,9 @@ namespace Bit.iOS.Autofill
{ {
public LockPasswordViewController(IntPtr handle) public LockPasswordViewController(IntPtr handle)
: base(handle) : base(handle)
{ } {
BiometricIntegrityKey = "autofillBiometricState";
}
public CredentialProviderViewController CPViewController { get; set; } public CredentialProviderViewController CPViewController { get; set; }
public override UINavigationItem BaseNavItem => NavItem; public override UINavigationItem BaseNavItem => NavItem;

View File

@ -41,6 +41,8 @@ namespace Bit.iOS.Core.Controllers
public FormEntryTableViewCell MasterPasswordCell { get; set; } = new FormEntryTableViewCell( public FormEntryTableViewCell MasterPasswordCell { get; set; } = new FormEntryTableViewCell(
AppResources.MasterPassword); AppResources.MasterPassword);
public string BiometricIntegrityKey { get; set; }
public override void ViewDidLoad() public override void ViewDidLoad()
{ {
@ -86,7 +88,8 @@ namespace Bit.iOS.Core.Controllers
if (_biometricLock) if (_biometricLock)
{ {
_biometricIntegrityValid = _biometricService.ValidateIntegrityAsync().GetAwaiter().GetResult(); _biometricIntegrityValid = _biometricService.ValidateIntegrityAsync(BiometricIntegrityKey).GetAwaiter()
.GetResult();
if (!_biometricIntegrityValid) if (!_biometricIntegrityValid)
{ {
return; return;
@ -194,6 +197,12 @@ namespace Bit.iOS.Core.Controllers
_vaultTimeoutService.PinProtectedKey = await _cryptoService.EncryptAsync(key2.Key, pinKey); _vaultTimeoutService.PinProtectedKey = await _cryptoService.EncryptAsync(key2.Key, pinKey);
} }
await SetKeyAndContinueAsync(key2); await SetKeyAndContinueAsync(key2);
// Re-enable biometrics
if (_biometricLock & !_biometricIntegrityValid)
{
await _biometricService.SetupBiometricAsync(BiometricIntegrityKey);
}
} }
else else
{ {

View File

@ -14,24 +14,32 @@ namespace Bit.iOS.Core.Services
_storageService = storageService; _storageService = storageService;
} }
public async Task<bool> SetupBiometricAsync() public async Task<bool> SetupBiometricAsync(string bioIntegrityKey = null)
{ {
if (bioIntegrityKey == null)
{
bioIntegrityKey = "biometricState";
}
var state = GetState(); var state = GetState();
if (state != null) if (state != null)
{ {
await _storageService.SaveAsync("biometricState", ToBase64(state)); await _storageService.SaveAsync(bioIntegrityKey, ToBase64(state));
} }
return true; return true;
} }
public async Task<bool> ValidateIntegrityAsync() public async Task<bool> ValidateIntegrityAsync(string bioIntegrityKey = null)
{ {
var oldState = await _storageService.GetAsync<string>("biometricState"); if (bioIntegrityKey == null)
{
bioIntegrityKey = "biometricState";
}
var oldState = await _storageService.GetAsync<string>(bioIntegrityKey);
if (oldState == null) if (oldState == null)
{ {
// Fallback for upgraded devices // Fallback for upgraded devices
await SetupBiometricAsync(); await SetupBiometricAsync(bioIntegrityKey);
return true; return true;
} }

View File

@ -8,7 +8,9 @@ namespace Bit.iOS.Extension
{ {
public LockPasswordViewController(IntPtr handle) public LockPasswordViewController(IntPtr handle)
: base(handle) : base(handle)
{ } {
BiometricIntegrityKey = "extensionBiometricState";
}
public LoadingViewController LoadingController { get; set; } public LoadingViewController LoadingController { get; set; }
public override UINavigationItem BaseNavItem => NavItem; public override UINavigationItem BaseNavItem => NavItem;