diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs index f097b395c..1875405c8 100644 --- a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs +++ b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs @@ -439,18 +439,18 @@ namespace Bit.App.Pages var email = await _stateService.GetEmailAsync(); var pinKey = await _cryptoService.MakePinKeyAsync(pin, email, kdfConfig); var userKey = await _cryptoService.GetUserKeyAsync(); - var pinProtectedKey = await _cryptoService.EncryptAsync(userKey.Key, pinKey); + var protectedPinKey = await _cryptoService.EncryptAsync(userKey.Key, pinKey); var encPin = await _cryptoService.EncryptAsync(pin); await _stateService.SetProtectedPinAsync(encPin.EncryptedString); if (masterPassOnRestart) { - await _stateService.SetUserKeyPinEphemeralAsync(pinProtectedKey); + await _stateService.SetUserKeyPinEphemeralAsync(protectedPinKey); } else { - await _stateService.SetUserKeyPinAsync(pinProtectedKey); + await _stateService.SetUserKeyPinAsync(protectedPinKey); } } else diff --git a/src/Core/Services/CryptoService.cs b/src/Core/Services/CryptoService.cs index b336b3d4e..60e68c64d 100644 --- a/src/Core/Services/CryptoService.cs +++ b/src/Core/Services/CryptoService.cs @@ -146,7 +146,7 @@ namespace Bit.Core.Services public async Task> EncryptUserKeyWithMasterKeyAsync(MasterKey masterKey, UserKey userKey = null) { userKey ??= await GetUserKeyAsync(); - return await BuildProtectedSymmetricKey(masterKey, userKey.Key); + return await BuildProtectedSymmetricKey(masterKey, userKey.Key, keyBytes => new UserKey(keyBytes)); } public async Task DecryptUserKeyWithMasterKeyAsync(MasterKey masterKey, EncString encUserKey = null, string userId = null) @@ -174,7 +174,7 @@ namespace Bit.Core.Services } else if (encUserKey.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64) { - var newKey = await StretchKeyAsync(masterKey); + var newKey = await StretchKeyAsync(masterKey, keyBytes => new MasterKey(keyBytes)); decUserKey = await DecryptToBytesAsync(encUserKey, newKey); } else @@ -197,7 +197,7 @@ namespace Bit.Core.Services } var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64); - return await BuildProtectedSymmetricKey(key, newSymKey); + return await BuildProtectedSymmetricKey(key, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes)); } public async Task> MakeDataEncKeyAsync(OrgKey key) @@ -208,7 +208,7 @@ namespace Bit.Core.Services } var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64); - return await BuildProtectedSymmetricKey(key, newSymKey); + return await BuildProtectedSymmetricKey(key, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes)); } public async Task HashMasterKeyAsync(string password, MasterKey masterKey, HashPurpose hashPurpose = HashPurpose.ServerAuthorization) @@ -423,7 +423,7 @@ namespace Bit.Core.Services public async Task MakePinKeyAsync(string pin, string salt, KdfConfig config) { var pinKey = await MakeKeyAsync(pin, salt, config, keyBytes => new PinKey(keyBytes)); - return await StretchKeyAsync(pinKey) as PinKey; + return await StretchKeyAsync(pinKey, keyBytes => new PinKey(keyBytes)); } public Task ClearPinKeysAsync(string userId = null) @@ -819,14 +819,16 @@ namespace Bit.Core.Services return key; } - private async Task StretchKeyAsync(SymmetricCryptoKey key) + // TODO: This needs to be moved into SymmetricCryptoKey model to remove the keyCreator hack + private async Task StretchKeyAsync(SymmetricCryptoKey key, Func keyCreator) + where TKey : SymmetricCryptoKey { var newKey = new byte[64]; var enc = await _cryptoFunctionService.HkdfExpandAsync(key.Key, Encoding.UTF8.GetBytes("enc"), 32, HkdfAlgorithm.Sha256); Buffer.BlockCopy(enc, 0, newKey, 0, 32); var mac = await _cryptoFunctionService.HkdfExpandAsync(key.Key, Encoding.UTF8.GetBytes("mac"), 32, HkdfAlgorithm.Sha256); Buffer.BlockCopy(mac, 0, newKey, 32, 32); - return new SymmetricCryptoKey(newKey); + return keyCreator(newKey); } private List HashPhrase(byte[] hash, int minimumEntropy = 64) @@ -853,13 +855,14 @@ namespace Bit.Core.Services return phrase; } - private async Task> BuildProtectedSymmetricKey(SymmetricCryptoKey key, - byte[] encKey) where T : SymmetricCryptoKey + // TODO: This needs to be moved into SymmetricCryptoKey model to remove the keyCreator hack + private async Task> BuildProtectedSymmetricKey(SymmetricCryptoKey key, + byte[] encKey, Func keyCreator) where TKey : SymmetricCryptoKey { EncString encKeyEnc = null; if (key.Key.Length == 32) { - var newKey = await StretchKeyAsync(key); + var newKey = await StretchKeyAsync(key, keyCreator); encKeyEnc = await EncryptAsync(encKey, newKey); } else if (key.Key.Length == 64) @@ -870,10 +873,10 @@ namespace Bit.Core.Services { throw new Exception("Invalid key size."); } - return new Tuple(new SymmetricCryptoKey(encKey) as T, encKeyEnc); + return new Tuple(keyCreator(encKey), encKeyEnc); } - // TODO: This intantiator needs to be moved into each key type in order to get rid of the keyCreator hack + // TODO: This needs to be moved into SymmetricCryptoKey model to remove the keyCreator hack private async Task MakeKeyAsync(string password, string salt, KdfConfig kdfConfig, Func keyCreator) where TKey : SymmetricCryptoKey { diff --git a/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs b/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs index bebc7e925..165757d03 100644 --- a/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs +++ b/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs @@ -312,18 +312,18 @@ namespace Bit.iOS.Core.Controllers { var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig); - var storedPasswordHash = await _cryptoService.GetPasswordHashAsync(); + var storedPasswordHash = await _cryptoService.GetMasterKeyHashAsync(); if (storedPasswordHash == null) { var oldKey = await _secureStorageService.GetAsync("oldKey"); if (masterKey.KeyB64 == oldKey) { - var localPasswordHash = await _cryptoService.HashPasswordAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization); + var localPasswordHash = await _cryptoService.HashMasterKeyAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization); await _secureStorageService.RemoveAsync("oldKey"); - await _cryptoService.SetPasswordHashAsync(localPasswordHash); + await _cryptoService.SetMasterKeyHashAsync(localPasswordHash); } } - var passwordValid = await _cryptoService.CompareAndUpdatePasswordHashAsync(inputtedValue, masterKey); + var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(inputtedValue, masterKey); if (passwordValid) { await AppHelpers.ResetInvalidUnlockAttemptsAsync(); diff --git a/src/iOS.Core/Controllers/LockPasswordViewController.cs b/src/iOS.Core/Controllers/LockPasswordViewController.cs index 9d4019a47..990e3d9f7 100644 --- a/src/iOS.Core/Controllers/LockPasswordViewController.cs +++ b/src/iOS.Core/Controllers/LockPasswordViewController.cs @@ -285,18 +285,18 @@ namespace Bit.iOS.Core.Controllers { var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig); - var storedPasswordHash = await _cryptoService.GetPasswordHashAsync(); + var storedPasswordHash = await _cryptoService.GetMasterKeyHashAsync(); if (storedPasswordHash == null) { var oldKey = await _secureStorageService.GetAsync("oldKey"); if (masterKey.KeyB64 == oldKey) { - var localPasswordHash = await _cryptoService.HashPasswordAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization); + var localPasswordHash = await _cryptoService.HashMasterKeyAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization); await _secureStorageService.RemoveAsync("oldKey"); - await _cryptoService.SetPasswordHashAsync(localPasswordHash); + await _cryptoService.SetMasterKeyHashAsync(localPasswordHash); } } - var passwordValid = await _cryptoService.CompareAndUpdatePasswordHashAsync(inputtedValue, masterKey); + var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(inputtedValue, masterKey); if (passwordValid) { await AppHelpers.ResetInvalidUnlockAttemptsAsync();