diff --git a/src/App/Pages/Accounts/SetPasswordPageViewModel.cs b/src/App/Pages/Accounts/SetPasswordPageViewModel.cs index ad477338f..57ffaac79 100644 --- a/src/App/Pages/Accounts/SetPasswordPageViewModel.cs +++ b/src/App/Pages/Accounts/SetPasswordPageViewModel.cs @@ -206,9 +206,9 @@ namespace Bit.App.Pages // Grab Organization Keys var response = await _apiService.GetOrganizationKeysAsync(OrgId); var publicKey = CoreHelpers.Base64UrlDecode(response.PublicKey); - // Grab user's Encryption Key and encrypt with Org Public Key - var userEncKey = await _cryptoService.GetEncKeyAsync(); - var encryptedKey = await _cryptoService.RsaEncryptAsync(userEncKey.Key, publicKey); + // Grab User Key and encrypt with Org Public Key + var userKey = await _cryptoService.GetUserKeyAsync(); + var encryptedKey = await _cryptoService.RsaEncryptAsync(userKey.Key, publicKey); // Request var resetRequest = new OrganizationUserResetPasswordEnrollmentRequest { diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs index f6f2c8a3d..f097b395c 100644 --- a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs +++ b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs @@ -438,18 +438,19 @@ namespace Bit.App.Pages var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile)); var email = await _stateService.GetEmailAsync(); var pinKey = await _cryptoService.MakePinKeyAsync(pin, email, kdfConfig); - var key = await _cryptoService.GetKeyAsync(); - var pinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey); + var userKey = await _cryptoService.GetUserKeyAsync(); + var pinProtectedKey = await _cryptoService.EncryptAsync(userKey.Key, pinKey); + + var encPin = await _cryptoService.EncryptAsync(pin); + await _stateService.SetProtectedPinAsync(encPin.EncryptedString); if (masterPassOnRestart) { - var encPin = await _cryptoService.EncryptAsync(pin); - await _stateService.SetProtectedPinAsync(encPin.EncryptedString); - await _stateService.SetPinProtectedKeyAsync(pinProtectedKey); + await _stateService.SetUserKeyPinEphemeralAsync(pinProtectedKey); } else { - await _stateService.SetPinProtectedAsync(pinProtectedKey.EncryptedString); + await _stateService.SetUserKeyPinAsync(pinProtectedKey); } } else @@ -459,7 +460,6 @@ namespace Bit.App.Pages } if (!_pin) { - await _cryptoService.ClearPinProtectedKeyAsync(); await _vaultTimeoutService.ClearAsync(); } BuildList(); diff --git a/src/Core/Abstractions/ICryptoService.cs b/src/Core/Abstractions/ICryptoService.cs index bfd66b1ed..1a084b4a3 100644 --- a/src/Core/Abstractions/ICryptoService.cs +++ b/src/Core/Abstractions/ICryptoService.cs @@ -42,11 +42,10 @@ namespace Bit.Core.Abstractions Task> MakeKeyPairAsync(SymmetricCryptoKey key = null); Task ClearKeyPairAsync(bool memoryOnly = false, string userId = null); Task MakePinKeyAsync(string pin, string salt, KdfConfig config); + Task ClearPinKeysAsync(string userId = null); Task DecryptUserKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedUserKey = null); Task DecryptMasterKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedMasterKey = null); Task MakeSendKeyAsync(byte[] keyMaterial); - // TODO(Jake): This isn't used, delete? - Task ClearKeysAsync(string userId = null); Task RsaEncryptAsync(byte[] data, byte[] publicKey = null); Task RsaDecryptAsync(string encValue, byte[] privateKey = null); Task RandomNumberAsync(int min, int max); @@ -67,15 +66,11 @@ namespace Bit.Core.Abstractions - Task ClearEncKeyAsync(bool memoryOnly = false, string userId = null); - Task ClearKeyAsync(string userId = null); - Task ClearPinProtectedKeyAsync(string userId = null); void ClearCache(); + Task GetEncKeyAsync(SymmetricCryptoKey key = null); Task GetKeyAsync(string userId = null); - Task HasKeyAsync(string userId = null); Task> MakeEncKeyAsync(SymmetricCryptoKey key); - // TODO(Jake): This isn't used, delete Task SetEncKeyAsync(string encKey); Task SetKeyAsync(SymmetricCryptoKey key); } diff --git a/src/Core/Services/CipherService.cs b/src/Core/Services/CipherService.cs index 18ffd3c4f..89003249d 100644 --- a/src/Core/Services/CipherService.cs +++ b/src/Core/Services/CipherService.cs @@ -249,7 +249,7 @@ namespace Bit.Core.Services { try { - var hashKey = await _cryptoService.HasKeyAsync(); + var hashKey = await _cryptoService.HasUserKeyAsync(); if (!hashKey) { throw new Exception("No key."); diff --git a/src/Core/Services/CollectionService.cs b/src/Core/Services/CollectionService.cs index fe30159dc..f8e88e365 100644 --- a/src/Core/Services/CollectionService.cs +++ b/src/Core/Services/CollectionService.cs @@ -101,7 +101,7 @@ namespace Bit.Core.Services { return _decryptedCollectionCache; } - var hasKey = await _cryptoService.HasKeyAsync(); + var hasKey = await _cryptoService.HasUserKeyAsync(); if (!hasKey) { throw new Exception("No key."); diff --git a/src/Core/Services/CryptoService.cs b/src/Core/Services/CryptoService.cs index 1c1349112..4b31303f4 100644 --- a/src/Core/Services/CryptoService.cs +++ b/src/Core/Services/CryptoService.cs @@ -428,7 +428,7 @@ namespace Bit.Core.Services return await StretchKeyAsync(pinKey) as PinKey; } - public async Task ClearPinKeys(string userId = null) + public async Task ClearPinKeysAsync(string userId = null) { await _stateService.SetUserKeyPinAsync(null, userId); await _stateService.SetUserKeyPinEphemeralAsync(null, userId); @@ -476,20 +476,6 @@ namespace Bit.Core.Services return new SymmetricCryptoKey(sendKey); } - // TODO(Jake): This isn't used, delete? - public async Task ClearKeysAsync(string userId = null) - { - await Task.WhenAll(new Task[] - { - ClearUserKeyAsync(userId), - ClearPasswordHashAsync(userId), - ClearOrgKeysAsync(false, userId), - ClearKeyPairAsync(false, userId), - // TODO(Jake): replace with ClearPinKeys - ClearPinProtectedKeyAsync(userId) - }); - } - public async Task RsaEncryptAsync(byte[] data, byte[] publicKey = null) { if (publicKey == null) @@ -711,7 +697,7 @@ namespace Bit.Core.Services { var obj = new EncryptedObject { - Key = await GetKeyForEncryptionAsync(key), + Key = key ?? await GetUserKeyWithLegacySupportAsync(), Iv = await _cryptoFunctionService.RandomBytesAsync(16) }; obj.Data = await _cryptoFunctionService.AesEncryptAsync(data, obj.Iv, obj.Key.EncKey); @@ -728,7 +714,7 @@ namespace Bit.Core.Services private async Task AesDecryptToUtf8Async(EncryptionType encType, string data, string iv, string mac, SymmetricCryptoKey key) { - var keyForEnc = await GetKeyForEncryptionAsync(key); + var keyForEnc = key ?? await GetUserKeyWithLegacySupportAsync(); var theKey = ResolveLegacyKey(encType, keyForEnc); if (theKey.MacKey != null && mac == null) { @@ -782,7 +768,7 @@ namespace Bit.Core.Services SymmetricCryptoKey key) { - var keyForEnc = await GetKeyForEncryptionAsync(key); + var keyForEnc = key ?? await GetUserKeyWithLegacySupportAsync(); var theKey = ResolveLegacyKey(encType, keyForEnc); if (theKey.MacKey != null && mac == null) { @@ -820,19 +806,6 @@ namespace Bit.Core.Services } - private async Task GetUserKeyWithLegacySupport(string userId = null) - { - var userKey = await GetUserKeyAsync(); - if (userKey != null) - { - return userKey; - } - - // Legacy support: encryption used to be done with the master key (derived from master password). - // Users who have not migrated will have a null user key and must use the master key instead. - return (SymmetricCryptoKey)await GetMasterKeyAsync() as UserKey; - } - private async Task GetKeyForEncryptionAsync(SymmetricCryptoKey key = null) { if (key != null) @@ -1159,35 +1132,8 @@ namespace Bit.Core.Services - public async Task HasKeyAsync(string userId = null) - { - var key = await GetKeyAsync(userId); - return key != null; - } - - public async Task ClearKeyAsync(string userId = null) - { - await _stateService.SetKeyDecryptedAsync(null, userId); - _legacyEtmKey = null; - await _stateService.SetKeyEncryptedAsync(null, userId); - } - public async Task ClearEncKeyAsync(bool memoryOnly = false, string userId = null) - { - _encKey = null; - if (!memoryOnly) - { - await _stateService.SetEncKeyEncryptedAsync(null, userId); - } - } - - - - public async Task ClearPinProtectedKeyAsync(string userId = null) - { - await _stateService.SetPinProtectedAsync(null, userId); - } public void ClearCache() { diff --git a/src/Core/Services/FolderService.cs b/src/Core/Services/FolderService.cs index 044ee2b93..4aa2e9f3d 100644 --- a/src/Core/Services/FolderService.cs +++ b/src/Core/Services/FolderService.cs @@ -77,7 +77,7 @@ namespace Bit.Core.Services { return _decryptedFolderCache; } - var hasKey = await _cryptoService.HasKeyAsync(); + var hasKey = await _cryptoService.HasUserKeyAsync(); if (!hasKey) { throw new Exception("No key."); diff --git a/src/Core/Services/KeyConnectorService.cs b/src/Core/Services/KeyConnectorService.cs index 70cbd1e78..a997c5c40 100644 --- a/src/Core/Services/KeyConnectorService.cs +++ b/src/Core/Services/KeyConnectorService.cs @@ -60,11 +60,11 @@ namespace Bit.Core.Services public async Task MigrateUser() { var organization = await GetManagingOrganization(); - var key = await _cryptoService.GetKeyAsync(); + var masterKey = await _cryptoService.GetMasterKeyAsync(); try { - var keyConnectorRequest = new KeyConnectorUserKeyRequest(key.EncKeyB64); + var keyConnectorRequest = new KeyConnectorUserKeyRequest(masterKey.EncKeyB64); await _apiService.PostUserKeyToKeyConnector(organization.KeyConnectorUrl, keyConnectorRequest); } catch (Exception e) diff --git a/src/Core/Services/PasswordGenerationService.cs b/src/Core/Services/PasswordGenerationService.cs index 3210cccad..a3b3a853b 100644 --- a/src/Core/Services/PasswordGenerationService.cs +++ b/src/Core/Services/PasswordGenerationService.cs @@ -247,7 +247,7 @@ namespace Bit.Core.Services public async Task> GetHistoryAsync() { - var hasKey = await _cryptoService.HasKeyAsync(); + var hasKey = await _cryptoService.HasUserKeyAsync(); if (!hasKey) { return new List(); @@ -262,7 +262,7 @@ namespace Bit.Core.Services public async Task AddHistoryAsync(string password, CancellationToken token = default(CancellationToken)) { - var hasKey = await _cryptoService.HasKeyAsync(); + var hasKey = await _cryptoService.HasUserKeyAsync(); if (!hasKey) { return; diff --git a/src/Core/Services/SendService.cs b/src/Core/Services/SendService.cs index b59fad7e6..c2d24109b 100644 --- a/src/Core/Services/SendService.cs +++ b/src/Core/Services/SendService.cs @@ -143,7 +143,7 @@ namespace Bit.Core.Services return _decryptedSendsCache; } - var hasKey = await _cryptoService.HasKeyAsync(); + var hasKey = await _cryptoService.HasUserKeyAsync(); if (!hasKey) { throw new Exception("No Key."); diff --git a/src/Core/Services/VaultTimeoutService.cs b/src/Core/Services/VaultTimeoutService.cs index ad7cb0ce4..f1060c2e1 100644 --- a/src/Core/Services/VaultTimeoutService.cs +++ b/src/Core/Services/VaultTimeoutService.cs @@ -61,7 +61,7 @@ namespace Bit.Core.Services public async Task IsLockedAsync(string userId = null) { - var hasKey = await _cryptoService.HasKeyAsync(userId); + var hasKey = await _cryptoService.HasUserKeyAsync(userId); if (hasKey) { var biometricSet = await IsBiometricLockSetAsync(userId); @@ -196,10 +196,10 @@ namespace Bit.Core.Services } } await Task.WhenAll( - _cryptoService.ClearKeyAsync(userId), + _cryptoService.ClearUserKeyAsync(userId), + _cryptoService.ClearMasterKeyAsync(userId), _cryptoService.ClearOrgKeysAsync(true, userId), - _cryptoService.ClearKeyPairAsync(true, userId), - _cryptoService.ClearEncKeyAsync(true, userId)); + _cryptoService.ClearKeyPairAsync(true, userId)); if (isActiveAccount) { @@ -257,8 +257,7 @@ namespace Bit.Core.Services public async Task ClearAsync(string userId = null) { - await _stateService.SetPinProtectedKeyAsync(null, userId); - await _stateService.SetProtectedPinAsync(null, userId); + await _cryptoService.ClearPinKeysAsync(userId); } public async Task GetVaultTimeout(string userId = null) diff --git a/test/Core.Test/Services/SendServiceTests.cs b/test/Core.Test/Services/SendServiceTests.cs index 6038465d5..688d0fef0 100644 --- a/test/Core.Test/Services/SendServiceTests.cs +++ b/test/Core.Test/Services/SendServiceTests.cs @@ -145,7 +145,7 @@ namespace Bit.Core.Test.Services return; var sendDataDict = sendDatas.ToDictionary(d => d.Id, d => d); - sutProvider.GetDependency().HasKeyAsync().Returns(true); + sutProvider.GetDependency().HasUserKeyAsync().Returns(true); ServiceContainer.Register("cryptoService", sutProvider.GetDependency()); sutProvider.GetDependency().StringComparer.Returns(StringComparer.CurrentCulture); sutProvider.GetDependency().GetActiveUserIdAsync().Returns(userId);