sequentialize some methods

This commit is contained in:
Kyle Spearrin 2019-04-19 16:38:20 -04:00
parent c6ce3e9480
commit 7f2c265965
2 changed files with 116 additions and 66 deletions

View file

@ -37,6 +37,7 @@ namespace Bit.Core.Services
["google.com"] = new HashSet<string> { "script.google.com" } ["google.com"] = new HashSet<string> { "script.google.com" }
}; };
private readonly HttpClient _httpClient = new HttpClient(); private readonly HttpClient _httpClient = new HttpClient();
private Task<List<CipherView>> _getAllDecryptedTask;
public CipherService( public CipherService(
ICryptoService cryptoService, ICryptoService cryptoService,
@ -204,34 +205,49 @@ namespace Bit.Core.Services
return response?.ToList() ?? new List<Cipher>(); return response?.ToList() ?? new List<Cipher>();
} }
// TODO: sequentialize? public Task<List<CipherView>> GetAllDecryptedAsync()
public async Task<List<CipherView>> GetAllDecryptedAsync()
{ {
if(DecryptedCipherCache != null) if(DecryptedCipherCache != null)
{ {
return DecryptedCipherCache; return Task.FromResult(DecryptedCipherCache);
} }
var hashKey = await _cryptoService.HasKeyAsync(); if(_getAllDecryptedTask != null)
if(!hashKey)
{ {
throw new Exception("No key."); return _getAllDecryptedTask;
} }
var decCiphers = new List<CipherView>(); async Task<List<CipherView>> doTask()
async Task decryptAndAddCipherAsync(Cipher cipher)
{ {
var c = await cipher.DecryptAsync(); try
decCiphers.Add(c); {
var hashKey = await _cryptoService.HasKeyAsync();
if(!hashKey)
{
throw new Exception("No key.");
}
var decCiphers = new List<CipherView>();
async Task decryptAndAddCipherAsync(Cipher cipher)
{
var c = await cipher.DecryptAsync();
decCiphers.Add(c);
}
var tasks = new List<Task>();
var ciphers = await GetAllAsync();
foreach(var cipher in ciphers)
{
tasks.Add(decryptAndAddCipherAsync(cipher));
}
await Task.WhenAll(tasks);
decCiphers = decCiphers.OrderBy(c => c, new CipherLocaleComparer(_i18nService)).ToList();
DecryptedCipherCache = decCiphers;
return DecryptedCipherCache;
}
finally
{
}
} }
var tasks = new List<Task>(); _getAllDecryptedTask = doTask();
var ciphers = await GetAllAsync(); return _getAllDecryptedTask;
foreach(var cipher in ciphers)
{
tasks.Add(decryptAndAddCipherAsync(cipher));
}
await Task.WhenAll(tasks);
decCiphers = decCiphers.OrderBy(c => c, new CipherLocaleComparer(_i18nService)).ToList();
DecryptedCipherCache = decCiphers;
return DecryptedCipherCache;
} }
public async Task<List<CipherView>> GetAllDecryptedForGroupingAsync(string groupingId, bool folder = true) public async Task<List<CipherView>> GetAllDecryptedForGroupingAsync(string groupingId, bool folder = true)

View file

@ -23,6 +23,8 @@ namespace Bit.Core.Services
private byte[] _publicKey; private byte[] _publicKey;
private byte[] _privateKey; private byte[] _privateKey;
private Dictionary<string, SymmetricCryptoKey> _orgKeys; private Dictionary<string, SymmetricCryptoKey> _orgKeys;
private Task<SymmetricCryptoKey> _getEncKeysTask;
private Task<Dictionary<string, SymmetricCryptoKey>> _getOrgKeysTask;
private const string Keys_Key = "key"; private const string Keys_Key = "key";
private const string Keys_EncOrgKeys = "encOrgKeys"; private const string Keys_EncOrgKeys = "encOrgKeys";
@ -113,46 +115,62 @@ namespace Bit.Core.Services
return keyHash == null ? null : _keyHash; return keyHash == null ? null : _keyHash;
} }
public async Task<SymmetricCryptoKey> GetEncKeyAsync() public Task<SymmetricCryptoKey> GetEncKeyAsync()
{ {
if(_encKey != null) if(_encKey != null)
{ {
return _encKey; return Task.FromResult(_encKey);
} }
var encKey = await _storageService.GetAsync<string>(Keys_EncKey); if(_getEncKeysTask != null)
if(encKey == null)
{ {
return null; return _getEncKeysTask;
} }
async Task<SymmetricCryptoKey> doTask()
{
try
{
var encKey = await _storageService.GetAsync<string>(Keys_EncKey);
if(encKey == null)
{
return null;
}
var key = await GetKeyAsync(); var key = await GetKeyAsync();
if(key == null) if(key == null)
{ {
return null; return null;
} }
byte[] decEncKey = null; byte[] decEncKey = null;
var encKeyCipher = new CipherString(encKey); var encKeyCipher = new CipherString(encKey);
if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_B64) if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_B64)
{ {
decEncKey = await DecryptToBytesAsync(encKeyCipher, key); decEncKey = await DecryptToBytesAsync(encKeyCipher, key);
} }
else if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64) else if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64)
{ {
var newKey = await StretchKeyAsync(key); var newKey = await StretchKeyAsync(key);
decEncKey = await DecryptToBytesAsync(encKeyCipher, newKey); decEncKey = await DecryptToBytesAsync(encKeyCipher, newKey);
} }
else else
{ {
throw new Exception("Unsupported encKey type."); throw new Exception("Unsupported encKey type.");
} }
if(decEncKey == null) if(decEncKey == null)
{ {
return null; return null;
}
_encKey = new SymmetricCryptoKey(decEncKey);
return _encKey;
}
finally
{
_getEncKeysTask = null;
}
} }
_encKey = new SymmetricCryptoKey(decEncKey); _getEncKeysTask = doTask();
return _encKey; return _getEncKeysTask;
} }
public async Task<byte[]> GetPublicKeyAsync() public async Task<byte[]> GetPublicKeyAsync()
@ -200,31 +218,47 @@ namespace Bit.Core.Services
return HashPhrase(userFingerprint); return HashPhrase(userFingerprint);
} }
public async Task<Dictionary<string, SymmetricCryptoKey>> GetOrgKeysAsync() public Task<Dictionary<string, SymmetricCryptoKey>> GetOrgKeysAsync()
{ {
if(_orgKeys != null && _orgKeys.Count > 0) if(_orgKeys != null && _orgKeys.Count > 0)
{ {
return _orgKeys; return Task.FromResult(_orgKeys);
} }
var encOrgKeys = await _storageService.GetAsync<Dictionary<string, string>>(Keys_EncOrgKeys); if(_getOrgKeysTask != null)
if(encOrgKeys == null)
{ {
return null; return _getOrgKeysTask;
} }
var orgKeys = new Dictionary<string, SymmetricCryptoKey>(); async Task<Dictionary<string, SymmetricCryptoKey>> doTask()
var setKey = false;
foreach(var org in encOrgKeys)
{ {
var decValue = await RsaDecryptAsync(org.Value); try
orgKeys.Add(org.Key, new SymmetricCryptoKey(decValue)); {
setKey = true; var encOrgKeys = await _storageService.GetAsync<Dictionary<string, string>>(Keys_EncOrgKeys);
} if(encOrgKeys == null)
{
return null;
}
var orgKeys = new Dictionary<string, SymmetricCryptoKey>();
var setKey = false;
foreach(var org in encOrgKeys)
{
var decValue = await RsaDecryptAsync(org.Value);
orgKeys.Add(org.Key, new SymmetricCryptoKey(decValue));
setKey = true;
}
if(setKey) if(setKey)
{ {
_orgKeys = orgKeys; _orgKeys = orgKeys;
}
return _orgKeys;
}
finally
{
_getOrgKeysTask = null;
}
} }
return _orgKeys; _getOrgKeysTask = doTask();
return _getOrgKeysTask;
} }
public async Task<SymmetricCryptoKey> GetOrgKeyAsync(string orgId) public async Task<SymmetricCryptoKey> GetOrgKeyAsync(string orgId)