mirror of
https://github.com/bitwarden/mobile
synced 2025-12-14 23:33:34 +00:00
[PM-2713] More conversions to crypto api
This commit is contained in:
@@ -206,9 +206,9 @@ namespace Bit.App.Pages
|
|||||||
// Grab Organization Keys
|
// Grab Organization Keys
|
||||||
var response = await _apiService.GetOrganizationKeysAsync(OrgId);
|
var response = await _apiService.GetOrganizationKeysAsync(OrgId);
|
||||||
var publicKey = CoreHelpers.Base64UrlDecode(response.PublicKey);
|
var publicKey = CoreHelpers.Base64UrlDecode(response.PublicKey);
|
||||||
// Grab user's Encryption Key and encrypt with Org Public Key
|
// Grab User Key and encrypt with Org Public Key
|
||||||
var userEncKey = await _cryptoService.GetEncKeyAsync();
|
var userKey = await _cryptoService.GetUserKeyAsync();
|
||||||
var encryptedKey = await _cryptoService.RsaEncryptAsync(userEncKey.Key, publicKey);
|
var encryptedKey = await _cryptoService.RsaEncryptAsync(userKey.Key, publicKey);
|
||||||
// Request
|
// Request
|
||||||
var resetRequest = new OrganizationUserResetPasswordEnrollmentRequest
|
var resetRequest = new OrganizationUserResetPasswordEnrollmentRequest
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -438,18 +438,19 @@ namespace Bit.App.Pages
|
|||||||
var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile));
|
var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile));
|
||||||
var email = await _stateService.GetEmailAsync();
|
var email = await _stateService.GetEmailAsync();
|
||||||
var pinKey = await _cryptoService.MakePinKeyAsync(pin, email, kdfConfig);
|
var pinKey = await _cryptoService.MakePinKeyAsync(pin, email, kdfConfig);
|
||||||
var key = await _cryptoService.GetKeyAsync();
|
var userKey = await _cryptoService.GetUserKeyAsync();
|
||||||
var pinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey);
|
var pinProtectedKey = await _cryptoService.EncryptAsync(userKey.Key, pinKey);
|
||||||
|
|
||||||
|
var encPin = await _cryptoService.EncryptAsync(pin);
|
||||||
|
await _stateService.SetProtectedPinAsync(encPin.EncryptedString);
|
||||||
|
|
||||||
if (masterPassOnRestart)
|
if (masterPassOnRestart)
|
||||||
{
|
{
|
||||||
var encPin = await _cryptoService.EncryptAsync(pin);
|
await _stateService.SetUserKeyPinEphemeralAsync(pinProtectedKey);
|
||||||
await _stateService.SetProtectedPinAsync(encPin.EncryptedString);
|
|
||||||
await _stateService.SetPinProtectedKeyAsync(pinProtectedKey);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _stateService.SetPinProtectedAsync(pinProtectedKey.EncryptedString);
|
await _stateService.SetUserKeyPinAsync(pinProtectedKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -459,7 +460,6 @@ namespace Bit.App.Pages
|
|||||||
}
|
}
|
||||||
if (!_pin)
|
if (!_pin)
|
||||||
{
|
{
|
||||||
await _cryptoService.ClearPinProtectedKeyAsync();
|
|
||||||
await _vaultTimeoutService.ClearAsync();
|
await _vaultTimeoutService.ClearAsync();
|
||||||
}
|
}
|
||||||
BuildList();
|
BuildList();
|
||||||
|
|||||||
@@ -42,11 +42,10 @@ namespace Bit.Core.Abstractions
|
|||||||
Task<Tuple<string, EncString>> MakeKeyPairAsync(SymmetricCryptoKey key = null);
|
Task<Tuple<string, EncString>> MakeKeyPairAsync(SymmetricCryptoKey key = null);
|
||||||
Task ClearKeyPairAsync(bool memoryOnly = false, string userId = null);
|
Task ClearKeyPairAsync(bool memoryOnly = false, string userId = null);
|
||||||
Task<PinKey> MakePinKeyAsync(string pin, string salt, KdfConfig config);
|
Task<PinKey> MakePinKeyAsync(string pin, string salt, KdfConfig config);
|
||||||
|
Task ClearPinKeysAsync(string userId = null);
|
||||||
Task<UserKey> DecryptUserKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedUserKey = null);
|
Task<UserKey> DecryptUserKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedUserKey = null);
|
||||||
Task<MasterKey> DecryptMasterKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedMasterKey = null);
|
Task<MasterKey> DecryptMasterKeyWithPinAsync(string pin, string salt, KdfConfig kdfConfig, EncString pinProtectedMasterKey = null);
|
||||||
Task<SymmetricCryptoKey> MakeSendKeyAsync(byte[] keyMaterial);
|
Task<SymmetricCryptoKey> MakeSendKeyAsync(byte[] keyMaterial);
|
||||||
// TODO(Jake): This isn't used, delete?
|
|
||||||
Task ClearKeysAsync(string userId = null);
|
|
||||||
Task<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null);
|
Task<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null);
|
||||||
Task<byte[]> RsaDecryptAsync(string encValue, byte[] privateKey = null);
|
Task<byte[]> RsaDecryptAsync(string encValue, byte[] privateKey = null);
|
||||||
Task<int> RandomNumberAsync(int min, int max);
|
Task<int> 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();
|
void ClearCache();
|
||||||
|
|
||||||
Task<SymmetricCryptoKey> GetEncKeyAsync(SymmetricCryptoKey key = null);
|
Task<SymmetricCryptoKey> GetEncKeyAsync(SymmetricCryptoKey key = null);
|
||||||
Task<SymmetricCryptoKey> GetKeyAsync(string userId = null);
|
Task<SymmetricCryptoKey> GetKeyAsync(string userId = null);
|
||||||
Task<bool> HasKeyAsync(string userId = null);
|
|
||||||
Task<Tuple<SymmetricCryptoKey, EncString>> MakeEncKeyAsync(SymmetricCryptoKey key);
|
Task<Tuple<SymmetricCryptoKey, EncString>> MakeEncKeyAsync(SymmetricCryptoKey key);
|
||||||
// TODO(Jake): This isn't used, delete
|
|
||||||
Task SetEncKeyAsync(string encKey);
|
Task SetEncKeyAsync(string encKey);
|
||||||
Task SetKeyAsync(SymmetricCryptoKey key);
|
Task SetKeyAsync(SymmetricCryptoKey key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var hashKey = await _cryptoService.HasKeyAsync();
|
var hashKey = await _cryptoService.HasUserKeyAsync();
|
||||||
if (!hashKey)
|
if (!hashKey)
|
||||||
{
|
{
|
||||||
throw new Exception("No key.");
|
throw new Exception("No key.");
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
return _decryptedCollectionCache;
|
return _decryptedCollectionCache;
|
||||||
}
|
}
|
||||||
var hasKey = await _cryptoService.HasKeyAsync();
|
var hasKey = await _cryptoService.HasUserKeyAsync();
|
||||||
if (!hasKey)
|
if (!hasKey)
|
||||||
{
|
{
|
||||||
throw new Exception("No key.");
|
throw new Exception("No key.");
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ namespace Bit.Core.Services
|
|||||||
return await StretchKeyAsync(pinKey) as PinKey;
|
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.SetUserKeyPinAsync(null, userId);
|
||||||
await _stateService.SetUserKeyPinEphemeralAsync(null, userId);
|
await _stateService.SetUserKeyPinEphemeralAsync(null, userId);
|
||||||
@@ -476,20 +476,6 @@ namespace Bit.Core.Services
|
|||||||
return new SymmetricCryptoKey(sendKey);
|
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<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null)
|
public async Task<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null)
|
||||||
{
|
{
|
||||||
if (publicKey == null)
|
if (publicKey == null)
|
||||||
@@ -711,7 +697,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
var obj = new EncryptedObject
|
var obj = new EncryptedObject
|
||||||
{
|
{
|
||||||
Key = await GetKeyForEncryptionAsync(key),
|
Key = key ?? await GetUserKeyWithLegacySupportAsync(),
|
||||||
Iv = await _cryptoFunctionService.RandomBytesAsync(16)
|
Iv = await _cryptoFunctionService.RandomBytesAsync(16)
|
||||||
};
|
};
|
||||||
obj.Data = await _cryptoFunctionService.AesEncryptAsync(data, obj.Iv, obj.Key.EncKey);
|
obj.Data = await _cryptoFunctionService.AesEncryptAsync(data, obj.Iv, obj.Key.EncKey);
|
||||||
@@ -728,7 +714,7 @@ namespace Bit.Core.Services
|
|||||||
private async Task<string> AesDecryptToUtf8Async(EncryptionType encType, string data, string iv, string mac,
|
private async Task<string> AesDecryptToUtf8Async(EncryptionType encType, string data, string iv, string mac,
|
||||||
SymmetricCryptoKey key)
|
SymmetricCryptoKey key)
|
||||||
{
|
{
|
||||||
var keyForEnc = await GetKeyForEncryptionAsync(key);
|
var keyForEnc = key ?? await GetUserKeyWithLegacySupportAsync();
|
||||||
var theKey = ResolveLegacyKey(encType, keyForEnc);
|
var theKey = ResolveLegacyKey(encType, keyForEnc);
|
||||||
if (theKey.MacKey != null && mac == null)
|
if (theKey.MacKey != null && mac == null)
|
||||||
{
|
{
|
||||||
@@ -782,7 +768,7 @@ namespace Bit.Core.Services
|
|||||||
SymmetricCryptoKey key)
|
SymmetricCryptoKey key)
|
||||||
{
|
{
|
||||||
|
|
||||||
var keyForEnc = await GetKeyForEncryptionAsync(key);
|
var keyForEnc = key ?? await GetUserKeyWithLegacySupportAsync();
|
||||||
var theKey = ResolveLegacyKey(encType, keyForEnc);
|
var theKey = ResolveLegacyKey(encType, keyForEnc);
|
||||||
if (theKey.MacKey != null && mac == null)
|
if (theKey.MacKey != null && mac == null)
|
||||||
{
|
{
|
||||||
@@ -820,19 +806,6 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task<UserKey> 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<SymmetricCryptoKey> GetKeyForEncryptionAsync(SymmetricCryptoKey key = null)
|
private async Task<SymmetricCryptoKey> GetKeyForEncryptionAsync(SymmetricCryptoKey key = null)
|
||||||
{
|
{
|
||||||
if (key != null)
|
if (key != null)
|
||||||
@@ -1159,35 +1132,8 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<bool> 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()
|
public void ClearCache()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
return _decryptedFolderCache;
|
return _decryptedFolderCache;
|
||||||
}
|
}
|
||||||
var hasKey = await _cryptoService.HasKeyAsync();
|
var hasKey = await _cryptoService.HasUserKeyAsync();
|
||||||
if (!hasKey)
|
if (!hasKey)
|
||||||
{
|
{
|
||||||
throw new Exception("No key.");
|
throw new Exception("No key.");
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ namespace Bit.Core.Services
|
|||||||
public async Task MigrateUser()
|
public async Task MigrateUser()
|
||||||
{
|
{
|
||||||
var organization = await GetManagingOrganization();
|
var organization = await GetManagingOrganization();
|
||||||
var key = await _cryptoService.GetKeyAsync();
|
var masterKey = await _cryptoService.GetMasterKeyAsync();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var keyConnectorRequest = new KeyConnectorUserKeyRequest(key.EncKeyB64);
|
var keyConnectorRequest = new KeyConnectorUserKeyRequest(masterKey.EncKeyB64);
|
||||||
await _apiService.PostUserKeyToKeyConnector(organization.KeyConnectorUrl, keyConnectorRequest);
|
await _apiService.PostUserKeyToKeyConnector(organization.KeyConnectorUrl, keyConnectorRequest);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task<List<GeneratedPasswordHistory>> GetHistoryAsync()
|
public async Task<List<GeneratedPasswordHistory>> GetHistoryAsync()
|
||||||
{
|
{
|
||||||
var hasKey = await _cryptoService.HasKeyAsync();
|
var hasKey = await _cryptoService.HasUserKeyAsync();
|
||||||
if (!hasKey)
|
if (!hasKey)
|
||||||
{
|
{
|
||||||
return new List<GeneratedPasswordHistory>();
|
return new List<GeneratedPasswordHistory>();
|
||||||
@@ -262,7 +262,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task AddHistoryAsync(string password, CancellationToken token = default(CancellationToken))
|
public async Task AddHistoryAsync(string password, CancellationToken token = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var hasKey = await _cryptoService.HasKeyAsync();
|
var hasKey = await _cryptoService.HasUserKeyAsync();
|
||||||
if (!hasKey)
|
if (!hasKey)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace Bit.Core.Services
|
|||||||
return _decryptedSendsCache;
|
return _decryptedSendsCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasKey = await _cryptoService.HasKeyAsync();
|
var hasKey = await _cryptoService.HasUserKeyAsync();
|
||||||
if (!hasKey)
|
if (!hasKey)
|
||||||
{
|
{
|
||||||
throw new Exception("No Key.");
|
throw new Exception("No Key.");
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task<bool> IsLockedAsync(string userId = null)
|
public async Task<bool> IsLockedAsync(string userId = null)
|
||||||
{
|
{
|
||||||
var hasKey = await _cryptoService.HasKeyAsync(userId);
|
var hasKey = await _cryptoService.HasUserKeyAsync(userId);
|
||||||
if (hasKey)
|
if (hasKey)
|
||||||
{
|
{
|
||||||
var biometricSet = await IsBiometricLockSetAsync(userId);
|
var biometricSet = await IsBiometricLockSetAsync(userId);
|
||||||
@@ -196,10 +196,10 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Task.WhenAll(
|
await Task.WhenAll(
|
||||||
_cryptoService.ClearKeyAsync(userId),
|
_cryptoService.ClearUserKeyAsync(userId),
|
||||||
|
_cryptoService.ClearMasterKeyAsync(userId),
|
||||||
_cryptoService.ClearOrgKeysAsync(true, userId),
|
_cryptoService.ClearOrgKeysAsync(true, userId),
|
||||||
_cryptoService.ClearKeyPairAsync(true, userId),
|
_cryptoService.ClearKeyPairAsync(true, userId));
|
||||||
_cryptoService.ClearEncKeyAsync(true, userId));
|
|
||||||
|
|
||||||
if (isActiveAccount)
|
if (isActiveAccount)
|
||||||
{
|
{
|
||||||
@@ -257,8 +257,7 @@ namespace Bit.Core.Services
|
|||||||
|
|
||||||
public async Task ClearAsync(string userId = null)
|
public async Task ClearAsync(string userId = null)
|
||||||
{
|
{
|
||||||
await _stateService.SetPinProtectedKeyAsync(null, userId);
|
await _cryptoService.ClearPinKeysAsync(userId);
|
||||||
await _stateService.SetProtectedPinAsync(null, userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int?> GetVaultTimeout(string userId = null)
|
public async Task<int?> GetVaultTimeout(string userId = null)
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ namespace Bit.Core.Test.Services
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var sendDataDict = sendDatas.ToDictionary(d => d.Id, d => d);
|
var sendDataDict = sendDatas.ToDictionary(d => d.Id, d => d);
|
||||||
sutProvider.GetDependency<ICryptoService>().HasKeyAsync().Returns(true);
|
sutProvider.GetDependency<ICryptoService>().HasUserKeyAsync().Returns(true);
|
||||||
ServiceContainer.Register("cryptoService", sutProvider.GetDependency<ICryptoService>());
|
ServiceContainer.Register("cryptoService", sutProvider.GetDependency<ICryptoService>());
|
||||||
sutProvider.GetDependency<II18nService>().StringComparer.Returns(StringComparer.CurrentCulture);
|
sutProvider.GetDependency<II18nService>().StringComparer.Returns(StringComparer.CurrentCulture);
|
||||||
sutProvider.GetDependency<IStateService>().GetActiveUserIdAsync().Returns(userId);
|
sutProvider.GetDependency<IStateService>().GetActiveUserIdAsync().Returns(userId);
|
||||||
|
|||||||
Reference in New Issue
Block a user