diff --git a/src/Core/Abstractions/ICryptoService.cs b/src/Core/Abstractions/ICryptoService.cs index b170b3e23..3970a8588 100644 --- a/src/Core/Abstractions/ICryptoService.cs +++ b/src/Core/Abstractions/ICryptoService.cs @@ -36,7 +36,7 @@ namespace Bit.Core.Abstractions Task GetOrgKeyAsync(string orgId); Task> GetOrgKeysAsync(); Task ClearOrgKeysAsync(bool memoryOnly = false, string userId = null); - Task GetPublicKeyAsync(); + Task GetUserPublicKeyAsync(); Task SetUserPrivateKeyAsync(string encPrivateKey); Task GetUserPrivateKeyAsync(); Task> GetFingerprintAsync(string userId, byte[] publicKey = null); diff --git a/src/Core/Services/CryptoService.cs b/src/Core/Services/CryptoService.cs index 0be99c7b6..20df21640 100644 --- a/src/Core/Services/CryptoService.cs +++ b/src/Core/Services/CryptoService.cs @@ -56,7 +56,7 @@ namespace Bit.Core.Services // Refresh the Pin Key if the user has a Pin set if (await _stateService.GetProtectedPinAsync(userId) != null) { - await StorePinKey(userKey, userId); + await UpdateUserKeyPinAsync(userKey, userId); } else { @@ -174,7 +174,7 @@ namespace Bit.Core.Services } else { - throw new Exception("Unsupported encKey type."); + throw new Exception($"Unsupported encrypted user key type: {encUserKey.EncryptionType}"); } if (decUserKey == null) @@ -184,40 +184,45 @@ namespace Bit.Core.Services return new UserKey(decUserKey); } - public async Task> MakeDataEncKeyAsync(UserKey key) + public async Task> MakeDataEncKeyAsync(UserKey userKey) { - if (key == null) + if (userKey is null) { - throw new Exception("No user key provided"); + throw new ArgumentNullException(nameof(userKey)); } var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64); - return await BuildProtectedSymmetricKey(key, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes)); + return await BuildProtectedSymmetricKey(userKey, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes)); } - public async Task> MakeDataEncKeyAsync(OrgKey key) + public async Task> MakeDataEncKeyAsync(OrgKey orgKey) { - if (key == null) + if (orgKey is null) { - throw new Exception("No org key provided"); + throw new ArgumentNullException(nameof(orgKey)); } var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64); - return await BuildProtectedSymmetricKey(key, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes)); + return await BuildProtectedSymmetricKey(orgKey, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes)); } public async Task HashMasterKeyAsync(string password, MasterKey masterKey, HashPurpose hashPurpose = HashPurpose.ServerAuthorization) { - if (masterKey == null) + if (password is null) + { + throw new ArgumentNullException(nameof(password)); + } + + if (masterKey is null) { masterKey = await GetMasterKeyAsync(); + + if (masterKey is null) + { + throw new ArgumentNullException(nameof(masterKey)); + } } - if (password == null || masterKey == null) - { - throw new Exception("Invalid parameters."); - } - var iterations = hashPurpose == HashPurpose.LocalAuthorization ? 2 : 1; - var hash = await _cryptoFunctionService.Pbkdf2Async(masterKey.Key, password, CryptoHashAlgorithm.Sha256, iterations); + var hash = await _cryptoFunctionService.Pbkdf2Async(masterKey.Key, password, CryptoHashAlgorithm.Sha256, (int)hashPurpose); return Convert.ToBase64String(hash); } @@ -259,7 +264,7 @@ namespace Bit.Core.Services } var serverPasswordHash = await HashMasterKeyAsync(masterPassword, key, HashPurpose.ServerAuthorization); - if (serverPasswordHash != null & storedPasswordHash == serverPasswordHash) + if (serverPasswordHash != null && storedPasswordHash == serverPasswordHash) { await SetMasterKeyHashAsync(localPasswordHash); return true; @@ -283,11 +288,11 @@ namespace Bit.Core.Services return null; } var orgKeys = await GetOrgKeysAsync(); - if (orgKeys == null || !orgKeys.ContainsKey(orgId)) + if (orgKeys?.TryGetValue(orgId, out var orgKey) == true) { - return null; + return orgKey; } - return orgKeys[orgId]; + return null; } public Task> GetOrgKeysAsync() @@ -343,7 +348,7 @@ namespace Bit.Core.Services } } - public async Task GetPublicKeyAsync() + public async Task GetUserPublicKeyAsync() { if (_publicKey != null) { @@ -387,7 +392,7 @@ namespace Bit.Core.Services { if (publicKey == null) { - publicKey = await GetPublicKeyAsync(); + publicKey = await GetUserPublicKeyAsync(); } if (publicKey == null) { @@ -427,7 +432,7 @@ namespace Bit.Core.Services _stateService.SetUserKeyPinAsync(null, userId), _stateService.SetUserKeyPinEphemeralAsync(null, userId), _stateService.SetProtectedPinAsync(null, userId), - clearDeprecatedPinKeysAsync(userId)); + ClearDeprecatedPinKeysAsync(userId)); } public async Task DecryptUserKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedUserKey = null) @@ -439,8 +444,8 @@ namespace Bit.Core.Services throw new Exception("No PIN protected user key found."); } var pinKey = await MakePinKeyAsync(pin, salt, kdfConfig); - var userKey = await DecryptToBytesAsync(pinProtectedUserKey, pinKey); - return new UserKey(userKey); + var userKeyBytes = await DecryptToBytesAsync(pinProtectedUserKey, pinKey); + return new UserKey(userKeyBytes); } // Only for migration purposes @@ -474,7 +479,7 @@ namespace Bit.Core.Services { if (publicKey == null) { - publicKey = await GetPublicKeyAsync(); + publicKey = await GetUserPublicKeyAsync(); } if (publicKey == null) { @@ -668,7 +673,7 @@ namespace Bit.Core.Services // --HELPER METHODS-- - private async Task StorePinKey(UserKey userKey, string userId = null) + private async Task UpdateUserKeyPinAsync(UserKey userKey, string userId = null) { var pin = await DecryptToUtf8Async(new EncString(await _stateService.GetProtectedPinAsync(userId))); var pinKey = await MakePinKeyAsync( @@ -974,7 +979,7 @@ namespace Bit.Core.Services return userKey; } - public Task clearDeprecatedPinKeysAsync(string userId = null) + public Task ClearDeprecatedPinKeysAsync(string userId = null) { return Task.WhenAll( _stateService.SetPinProtectedAsync(null, userId), diff --git a/src/Core/Services/VaultTimeoutService.cs b/src/Core/Services/VaultTimeoutService.cs index 55950f85b..1c1e61469 100644 --- a/src/Core/Services/VaultTimeoutService.cs +++ b/src/Core/Services/VaultTimeoutService.cs @@ -229,22 +229,19 @@ namespace Bit.Core.Services { // we can't depend on only the protected pin being set because old // versions only used it for MP on Restart - var pinIsEnabled = await _stateService.GetProtectedPinAsync(userId); - var userKeyPin = await _stateService.GetUserKeyPinAsync(userId); - var oldUserKeyPin = await _stateService.GetPinProtectedAsync(userId); + var isPinEnabled = await _stateService.GetProtectedPinAsync(userId) != null; + var hasUserKeyPin = await _stateService.GetUserKeyPinAsync(userId) != null; + var hasOldUserKeyPin = await _stateService.GetPinProtectedAsync(userId) != null; - if (userKeyPin != null || oldUserKeyPin != null) + if (hasUserKeyPin || hasOldUserKeyPin) { return PinLockType.Persistent; } - else if (pinIsEnabled != null && userKeyPin == null && oldUserKeyPin == null) + else if (isPinEnabled && !hasUserKeyPin && !hasOldUserKeyPin) { return PinLockType.Transient; } - else - { - return PinLockType.Disabled; - } + return PinLockType.Disabled; } public async Task IsBiometricLockSetAsync(string userId = null) diff --git a/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs b/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs index 165757d03..c7e2a409d 100644 --- a/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs +++ b/src/iOS.Core/Controllers/BaseLockPasswordViewController.cs @@ -30,7 +30,7 @@ namespace Bit.iOS.Core.Controllers private IBiometricService _biometricService; private IKeyConnectorService _keyConnectorService; private IAccountsManager _accountManager; - private PinLockEnum _pinStatus; + private PinLockType _pinStatus; private bool _pinEnabled; private bool _biometricEnabled; private bool _biometricIntegrityValid = true; @@ -104,7 +104,7 @@ namespace Bit.iOS.Core.Controllers if (autofillExtension && await _stateService.GetPasswordRepromptAutofillAsync()) { _passwordReprompt = true; - _pinStatus = PinLockEnum.Disabled; + _pinStatus = PinLockType.Disabled; _pinEnabled = false; _biometricEnabled = false; } @@ -114,8 +114,8 @@ namespace Bit.iOS.Core.Controllers var ephemeralPinSet = await _stateService.GetUserKeyPinEphemeralAsync() ?? await _stateService.GetPinProtectedKeyAsync(); - _pinEnabled = (_pinStatus == PinLockEnum.Transient && ephemeralPinSet != null) || - _pinStatus == PinLockEnum.Persistent; + _pinEnabled = (_pinStatus == PinLockType.Transient && ephemeralPinSet != null) || + _pinStatus == PinLockType.Persistent; _biometricEnabled = await _vaultTimeoutService.IsBiometricLockSetAsync() && await _cryptoService.HasEncryptedUserKeyAsync(); @@ -257,13 +257,13 @@ namespace Bit.iOS.Core.Controllers { EncString userKeyPin = null; EncString oldPinProtected = null; - if (_pinStatus == PinLockEnum.Persistent) + if (_pinStatus == PinLockType.Persistent) { userKeyPin = await _stateService.GetUserKeyPinAsync(); var oldEncryptedKey = await _stateService.GetPinProtectedAsync(); oldPinProtected = oldEncryptedKey != null ? new EncString(oldEncryptedKey) : null; } - else if (_pinStatus == PinLockEnum.Transient) + else if (_pinStatus == PinLockType.Transient) { userKeyPin = await _stateService.GetUserKeyPinEphemeralAsync(); oldPinProtected = await _stateService.GetPinProtectedKeyAsync(); @@ -273,7 +273,7 @@ namespace Bit.iOS.Core.Controllers if (oldPinProtected != null) { userKey = await _cryptoService.DecryptAndMigrateOldPinKeyAsync( - _pinStatus == PinLockEnum.Transient, + _pinStatus == PinLockType.Transient, inputtedValue, email, kdfConfig, diff --git a/src/iOS.Core/Controllers/LockPasswordViewController.cs b/src/iOS.Core/Controllers/LockPasswordViewController.cs index 990e3d9f7..8776bcc3a 100644 --- a/src/iOS.Core/Controllers/LockPasswordViewController.cs +++ b/src/iOS.Core/Controllers/LockPasswordViewController.cs @@ -1,20 +1,20 @@ using System; -using UIKit; -using Foundation; -using Bit.iOS.Core.Views; -using Bit.App.Resources; -using Bit.iOS.Core.Utilities; -using Bit.App.Abstractions; -using Bit.Core.Abstractions; -using Bit.Core.Utilities; using System.Threading.Tasks; -using Bit.App.Utilities; -using Bit.Core.Models.Domain; -using Bit.Core.Enums; -using Bit.App.Pages; +using Bit.App.Abstractions; using Bit.App.Models; -using Xamarin.Forms; +using Bit.App.Pages; +using Bit.App.Resources; +using Bit.App.Utilities; +using Bit.Core.Abstractions; +using Bit.Core.Enums; +using Bit.Core.Models.Domain; using Bit.Core.Services; +using Bit.Core.Utilities; +using Bit.iOS.Core.Utilities; +using Bit.iOS.Core.Views; +using Foundation; +using UIKit; +using Xamarin.Forms; namespace Bit.iOS.Core.Controllers { @@ -30,7 +30,7 @@ namespace Bit.iOS.Core.Controllers private IPlatformUtilsService _platformUtilsService; private IBiometricService _biometricService; private IKeyConnectorService _keyConnectorService; - private PinLockEnum _pinStatus; + private PinLockType _pinStatus; private bool _pinEnabled; private bool _biometricEnabled; private bool _biometricIntegrityValid = true; @@ -96,7 +96,7 @@ namespace Bit.iOS.Core.Controllers if (autofillExtension && await _stateService.GetPasswordRepromptAutofillAsync()) { _passwordReprompt = true; - _pinStatus = PinLockEnum.Disabled; + _pinStatus = PinLockType.Disabled; _pinEnabled = false; _biometricEnabled = false; } @@ -106,8 +106,8 @@ namespace Bit.iOS.Core.Controllers var ephemeralPinSet = await _stateService.GetUserKeyPinEphemeralAsync() ?? await _stateService.GetPinProtectedKeyAsync(); - _pinEnabled = (_pinStatus == PinLockEnum.Transient && ephemeralPinSet != null) || - _pinStatus == PinLockEnum.Persistent; + _pinEnabled = (_pinStatus == PinLockType.Transient && ephemeralPinSet != null) || + _pinStatus == PinLockType.Persistent; _biometricEnabled = await _vaultTimeoutService.IsBiometricLockSetAsync() && await _cryptoService.HasEncryptedUserKeyAsync(); @@ -129,7 +129,7 @@ namespace Bit.iOS.Core.Controllers { BaseNavItem.Title = AppResources.VerifyMasterPassword; } - + BaseCancelButton.Title = AppResources.Cancel; if (_biometricUnlockOnly) @@ -224,13 +224,13 @@ namespace Bit.iOS.Core.Controllers { EncString userKeyPin = null; EncString oldPinProtected = null; - if (_pinStatus == PinLockEnum.Persistent) + if (_pinStatus == PinLockType.Persistent) { userKeyPin = await _stateService.GetUserKeyPinAsync(); var oldEncryptedKey = await _stateService.GetPinProtectedAsync(); oldPinProtected = oldEncryptedKey != null ? new EncString(oldEncryptedKey) : null; } - else if (_pinStatus == PinLockEnum.Transient) + else if (_pinStatus == PinLockType.Transient) { userKeyPin = await _stateService.GetUserKeyPinEphemeralAsync(); oldPinProtected = await _stateService.GetPinProtectedKeyAsync(); @@ -240,7 +240,7 @@ namespace Bit.iOS.Core.Controllers if (oldPinProtected != null) { userKey = await _cryptoService.DecryptAndMigrateOldPinKeyAsync( - _pinStatus == PinLockEnum.Transient, + _pinStatus == PinLockType.Transient, inputtedValue, email, kdfConfig, @@ -284,7 +284,7 @@ namespace Bit.iOS.Core.Controllers else { var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig); - + var storedPasswordHash = await _cryptoService.GetMasterKeyHashAsync(); if (storedPasswordHash == null) { @@ -395,7 +395,7 @@ namespace Bit.iOS.Core.Controllers }); PresentViewController(alert, true, null); } - + private async Task LogOutAsync() { await AppHelpers.LogOutAsync(await _stateService.GetActiveUserIdAsync());