From 4d0f9d1c035e7af2ddaacb667c64e87cc9cad9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bispo?= Date: Wed, 30 Aug 2023 09:38:46 +0100 Subject: [PATCH] [PM-3543] [PM-3607] Fix password re-prompt when editing and on autofill. (#2713) * [PM-3543] [PM-3507] Fix password re-prompt when editing and on autofill. --- src/Android/MainApplication.cs | 2 +- .../Services/MobilePasswordRepromptService.cs | 22 +++++++++++++++++-- src/Core/Abstractions/ICryptoService.cs | 1 + src/Core/Services/CryptoService.cs | 9 ++++++++ src/iOS.Core/Utilities/iOSCoreHelpers.cs | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Android/MainApplication.cs b/src/Android/MainApplication.cs index cc2361821..287df60ed 100644 --- a/src/Android/MainApplication.cs +++ b/src/Android/MainApplication.cs @@ -159,7 +159,7 @@ namespace Bit.Droid var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService); var cryptoService = new CryptoService(stateService, cryptoFunctionService); var biometricService = new BiometricService(stateService, cryptoService); - var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService); + var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService, stateService); ServiceContainer.Register(preferencesStorage); ServiceContainer.Register("broadcasterService", broadcasterService); diff --git a/src/App/Services/MobilePasswordRepromptService.cs b/src/App/Services/MobilePasswordRepromptService.cs index c688e6edb..f9c3112da 100644 --- a/src/App/Services/MobilePasswordRepromptService.cs +++ b/src/App/Services/MobilePasswordRepromptService.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Bit.App.Abstractions; using Bit.App.Resources; +using Bit.App.Utilities; using Bit.Core.Abstractions; using Bit.Core.Enums; @@ -10,11 +11,13 @@ namespace Bit.App.Services { private readonly IPlatformUtilsService _platformUtilsService; private readonly ICryptoService _cryptoService; + private readonly IStateService _stateService; - public MobilePasswordRepromptService(IPlatformUtilsService platformUtilsService, ICryptoService cryptoService) + public MobilePasswordRepromptService(IPlatformUtilsService platformUtilsService, ICryptoService cryptoService, IStateService stateService) { _platformUtilsService = platformUtilsService; _cryptoService = cryptoService; + _stateService = stateService; } public string[] ProtectedFields { get; } = { "LoginTotp", "LoginPassword", "H_FieldValue", "CardNumber", "CardCode" }; @@ -42,7 +45,22 @@ namespace Bit.App.Services return false; }; - return await _cryptoService.CompareAndUpdateKeyHashAsync(password, null); + var masterKey = await _cryptoService.GetOrDeriveMasterKeyAsync(password); + var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(password, masterKey); + if (passwordValid) + { + await AppHelpers.ResetInvalidUnlockAttemptsAsync(); + + var userKey = await _cryptoService.DecryptUserKeyWithMasterKeyAsync(masterKey); + await _cryptoService.SetMasterKeyAsync(masterKey); + var hasKey = await _cryptoService.HasUserKeyAsync(); + if (!hasKey) + { + await _cryptoService.SetUserKeyAsync(userKey); + } + } + + return passwordValid; } private async Task ShouldByPassMasterPasswordRepromptAsync() diff --git a/src/Core/Abstractions/ICryptoService.cs b/src/Core/Abstractions/ICryptoService.cs index 9669bbfbc..282447d40 100644 --- a/src/Core/Abstractions/ICryptoService.cs +++ b/src/Core/Abstractions/ICryptoService.cs @@ -60,5 +60,6 @@ namespace Bit.Core.Abstractions Task EncryptAsync(string plainValue, SymmetricCryptoKey key = null); Task EncryptToBytesAsync(byte[] plainValue, SymmetricCryptoKey key = null); Task DecryptAndMigrateOldPinKeyAsync(bool masterPasswordOnRestart, string pin, string email, KdfConfig kdfConfig, EncString oldPinKey); + Task GetOrDeriveMasterKeyAsync(string password, string userId = null); } } diff --git a/src/Core/Services/CryptoService.cs b/src/Core/Services/CryptoService.cs index 89dce3e36..f01d470c6 100644 --- a/src/Core/Services/CryptoService.cs +++ b/src/Core/Services/CryptoService.cs @@ -700,6 +700,15 @@ namespace Bit.Core.Services return new EncByteArray(encBytes); } + public async Task GetOrDeriveMasterKeyAsync(string password, string userId = null) + { + var masterKey = await GetMasterKeyAsync(userId); + return masterKey ?? await this.MakeMasterKeyAsync( + password, + await _stateService.GetEmailAsync(userId), + await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile))); + } + // --HELPER METHODS-- private async Task StoreAdditionalKeysAsync(UserKey userKey, string userId = null) diff --git a/src/iOS.Core/Utilities/iOSCoreHelpers.cs b/src/iOS.Core/Utilities/iOSCoreHelpers.cs index 1c713147d..3b43a370c 100644 --- a/src/iOS.Core/Utilities/iOSCoreHelpers.cs +++ b/src/iOS.Core/Utilities/iOSCoreHelpers.cs @@ -115,7 +115,7 @@ namespace Bit.iOS.Core.Utilities var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService); var cryptoService = new CryptoService(stateService, cryptoFunctionService); var biometricService = new BiometricService(stateService, cryptoService); - var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService); + var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService, stateService); ServiceContainer.Register(preferencesStorage); ServiceContainer.Register("broadcasterService", broadcasterService);