1
0
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:
Jacob Fink
2023-07-19 10:46:45 -04:00
parent 546bf8dcb1
commit c9a7c29190
12 changed files with 30 additions and 90 deletions

View File

@@ -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
{ {

View File

@@ -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();

View File

@@ -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);
} }

View File

@@ -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.");

View File

@@ -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.");

View File

@@ -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()
{ {

View File

@@ -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.");

View File

@@ -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)

View File

@@ -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;

View File

@@ -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.");

View File

@@ -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)

View File

@@ -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);