From 7f2c265965610c7ba9d4af8f6e99823bf5dea3c1 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 19 Apr 2019 16:38:20 -0400 Subject: [PATCH] sequentialize some methods --- src/Core/Services/CipherService.cs | 56 ++++++++----- src/Core/Services/CryptoService.cs | 126 ++++++++++++++++++----------- 2 files changed, 116 insertions(+), 66 deletions(-) diff --git a/src/Core/Services/CipherService.cs b/src/Core/Services/CipherService.cs index c2aa742c3..f62ccc603 100644 --- a/src/Core/Services/CipherService.cs +++ b/src/Core/Services/CipherService.cs @@ -37,6 +37,7 @@ namespace Bit.Core.Services ["google.com"] = new HashSet { "script.google.com" } }; private readonly HttpClient _httpClient = new HttpClient(); + private Task> _getAllDecryptedTask; public CipherService( ICryptoService cryptoService, @@ -204,34 +205,49 @@ namespace Bit.Core.Services return response?.ToList() ?? new List(); } - // TODO: sequentialize? - public async Task> GetAllDecryptedAsync() + public Task> GetAllDecryptedAsync() { if(DecryptedCipherCache != null) { - return DecryptedCipherCache; + return Task.FromResult(DecryptedCipherCache); } - var hashKey = await _cryptoService.HasKeyAsync(); - if(!hashKey) + if(_getAllDecryptedTask != null) { - throw new Exception("No key."); + return _getAllDecryptedTask; } - var decCiphers = new List(); - async Task decryptAndAddCipherAsync(Cipher cipher) + async Task> doTask() { - var c = await cipher.DecryptAsync(); - decCiphers.Add(c); + try + { + var hashKey = await _cryptoService.HasKeyAsync(); + if(!hashKey) + { + throw new Exception("No key."); + } + var decCiphers = new List(); + async Task decryptAndAddCipherAsync(Cipher cipher) + { + var c = await cipher.DecryptAsync(); + decCiphers.Add(c); + } + var tasks = new List(); + 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(); - 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; + _getAllDecryptedTask = doTask(); + return _getAllDecryptedTask; } public async Task> GetAllDecryptedForGroupingAsync(string groupingId, bool folder = true) diff --git a/src/Core/Services/CryptoService.cs b/src/Core/Services/CryptoService.cs index f4b7dc08b..1ed9570ef 100644 --- a/src/Core/Services/CryptoService.cs +++ b/src/Core/Services/CryptoService.cs @@ -23,6 +23,8 @@ namespace Bit.Core.Services private byte[] _publicKey; private byte[] _privateKey; private Dictionary _orgKeys; + private Task _getEncKeysTask; + private Task> _getOrgKeysTask; private const string Keys_Key = "key"; private const string Keys_EncOrgKeys = "encOrgKeys"; @@ -113,46 +115,62 @@ namespace Bit.Core.Services return keyHash == null ? null : _keyHash; } - public async Task GetEncKeyAsync() + public Task GetEncKeyAsync() { if(_encKey != null) { - return _encKey; + return Task.FromResult(_encKey); } - var encKey = await _storageService.GetAsync(Keys_EncKey); - if(encKey == null) + if(_getEncKeysTask != null) { - return null; + return _getEncKeysTask; } + async Task doTask() + { + try + { + var encKey = await _storageService.GetAsync(Keys_EncKey); + if(encKey == null) + { + return null; + } - var key = await GetKeyAsync(); - if(key == null) - { - return null; - } + var key = await GetKeyAsync(); + if(key == null) + { + return null; + } - byte[] decEncKey = null; - var encKeyCipher = new CipherString(encKey); - if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_B64) - { - decEncKey = await DecryptToBytesAsync(encKeyCipher, key); - } - else if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64) - { - var newKey = await StretchKeyAsync(key); - decEncKey = await DecryptToBytesAsync(encKeyCipher, newKey); - } - else - { - throw new Exception("Unsupported encKey type."); - } + byte[] decEncKey = null; + var encKeyCipher = new CipherString(encKey); + if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_B64) + { + decEncKey = await DecryptToBytesAsync(encKeyCipher, key); + } + else if(encKeyCipher.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64) + { + var newKey = await StretchKeyAsync(key); + decEncKey = await DecryptToBytesAsync(encKeyCipher, newKey); + } + else + { + throw new Exception("Unsupported encKey type."); + } - if(decEncKey == null) - { - return null; + if(decEncKey == null) + { + return null; + } + _encKey = new SymmetricCryptoKey(decEncKey); + return _encKey; + } + finally + { + _getEncKeysTask = null; + } } - _encKey = new SymmetricCryptoKey(decEncKey); - return _encKey; + _getEncKeysTask = doTask(); + return _getEncKeysTask; } public async Task GetPublicKeyAsync() @@ -200,31 +218,47 @@ namespace Bit.Core.Services return HashPhrase(userFingerprint); } - public async Task> GetOrgKeysAsync() + public Task> GetOrgKeysAsync() { if(_orgKeys != null && _orgKeys.Count > 0) { - return _orgKeys; + return Task.FromResult(_orgKeys); } - var encOrgKeys = await _storageService.GetAsync>(Keys_EncOrgKeys); - if(encOrgKeys == null) + if(_getOrgKeysTask != null) { - return null; + return _getOrgKeysTask; } - var orgKeys = new Dictionary(); - var setKey = false; - foreach(var org in encOrgKeys) + async Task> doTask() { - var decValue = await RsaDecryptAsync(org.Value); - orgKeys.Add(org.Key, new SymmetricCryptoKey(decValue)); - setKey = true; - } + try + { + var encOrgKeys = await _storageService.GetAsync>(Keys_EncOrgKeys); + if(encOrgKeys == null) + { + return null; + } + var orgKeys = new Dictionary(); + 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) - { - _orgKeys = orgKeys; + if(setKey) + { + _orgKeys = orgKeys; + } + return _orgKeys; + } + finally + { + _getOrgKeysTask = null; + } } - return _orgKeys; + _getOrgKeysTask = doTask(); + return _getOrgKeysTask; } public async Task GetOrgKeyAsync(string orgId)