async vault fetch and filter (search) tasks. Resolved singleton crypto issue around reuse of PaddedBufferedBlockCipher

This commit is contained in:
Kyle Spearrin 2016-07-11 19:36:39 -04:00
parent f9fd53c733
commit f0455aad74
2 changed files with 46 additions and 34 deletions

View file

@ -48,6 +48,7 @@ namespace Bit.App.Pages
public ListView ListView { get; set; }
public IEnumerable<VaultListPageModel.Site> Sites { get; set; } = new List<VaultListPageModel.Site>();
public IEnumerable<VaultListPageModel.Folder> Folders { get; set; } = new List<VaultListPageModel.Folder>();
public SearchBar Search { get; set; }
private void Init()
{
@ -77,18 +78,18 @@ namespace Bit.App.Pages
ListView.ItemSelected += SiteSelected;
var searchBar = new SearchBar
Search = new SearchBar
{
Placeholder = "Search vault...",
BackgroundColor = Color.FromHex("efeff4")
};
searchBar.TextChanged += SearchBar_TextChanged;
searchBar.SearchButtonPressed += SearchBar_SearchButtonPressed;
Search.TextChanged += SearchBar_TextChanged;
Search.SearchButtonPressed += SearchBar_SearchButtonPressed;
Title = _favorites ? AppResources.Favorites : AppResources.MyVault;
Content = new StackLayout
{
Children = { searchBar, ListView },
Children = { Search, ListView },
Spacing = 0
};
}
@ -112,6 +113,14 @@ namespace Bit.App.Pages
private void FilterResults(string searchFilter)
{
Task.Run(async () =>
{
await Task.Delay(300);
if(searchFilter != Search.Text)
{
return;
}
if(string.IsNullOrWhiteSpace(searchFilter))
{
LoadFolders(Sites);
@ -122,6 +131,7 @@ namespace Bit.App.Pages
var filteredSites = Sites.Where(s => s.Name.ToLower().Contains(searchFilter) || s.Username.ToLower().Contains(searchFilter));
LoadFolders(filteredSites);
}
});
}
protected async override void OnAppearing()
@ -150,6 +160,8 @@ namespace Bit.App.Pages
}
private async Task FetchAndLoadVaultAsync()
{
await Task.Run(async () =>
{
var foldersTask = _folderService.GetAllAsync();
var sitesTask = _favorites ? _siteService.GetAllAsync(true) : _siteService.GetAllAsync();
@ -162,6 +174,7 @@ namespace Bit.App.Pages
Sites = sites.Select(s => new VaultListPageModel.Site(s));
LoadFolders(Sites);
});
}
private void LoadFolders(IEnumerable<VaultListPageModel.Site> sites)

View file

@ -21,16 +21,13 @@ namespace Bit.App.Services
private const int Iterations = 5000;
private readonly Random _random = new Random();
private readonly PaddedBufferedBlockCipher _cipher;
private readonly ISecureStorageService _secureStorage;
private readonly CbcBlockCipher _aesBlockCipher;
private KeyParameter _keyParameter;
public CryptoService(ISecureStorageService secureStorage)
{
var engine = new AesEngine();
var blockCipher = new CbcBlockCipher(engine);
_cipher = new PaddedBufferedBlockCipher(blockCipher);
_aesBlockCipher = new CbcBlockCipher(new AesEngine());
_secureStorage = secureStorage;
}
@ -96,10 +93,11 @@ namespace Bit.App.Services
var iv = GenerateRandomInitializationVector();
var keyParamWithIV = new ParametersWithIV(_keyParameter, iv, 0, InitializationVectorSize);
_cipher.Init(true, keyParamWithIV);
var encryptedBytes = new byte[_cipher.GetOutputSize(plaintextBytes.Length)];
var length = _cipher.ProcessBytes(plaintextBytes, encryptedBytes, 0);
_cipher.DoFinal(encryptedBytes, length);
var cipher = new PaddedBufferedBlockCipher(_aesBlockCipher);
cipher.Init(true, keyParamWithIV);
var encryptedBytes = new byte[cipher.GetOutputSize(plaintextBytes.Length)];
var length = cipher.ProcessBytes(plaintextBytes, encryptedBytes, 0);
cipher.DoFinal(encryptedBytes, length);
return new CipherString(Convert.ToBase64String(iv), Convert.ToBase64String(encryptedBytes));
}
@ -119,10 +117,11 @@ namespace Bit.App.Services
try
{
var keyParamWithIV = new ParametersWithIV(_keyParameter, encyptedValue.InitializationVectorBytes, 0, InitializationVectorSize);
_cipher.Init(false, keyParamWithIV);
byte[] comparisonBytes = new byte[_cipher.GetOutputSize(encyptedValue.CipherTextBytes.Length)];
var length = _cipher.ProcessBytes(encyptedValue.CipherTextBytes, comparisonBytes, 0);
_cipher.DoFinal(comparisonBytes, length);
var cipher = new PaddedBufferedBlockCipher(_aesBlockCipher);
cipher.Init(false, keyParamWithIV);
byte[] comparisonBytes = new byte[cipher.GetOutputSize(encyptedValue.CipherTextBytes.Length)];
var length = cipher.ProcessBytes(encyptedValue.CipherTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
return Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length).TrimEnd('\0');
}
catch(Exception e)