Async load database encrypted bytes to memory while entering password

This commit is contained in:
AlexVallat 2013-07-17 19:19:17 +01:00
parent 75297418c5
commit 689f468b8f
4 changed files with 47 additions and 19 deletions

View File

@ -162,17 +162,6 @@ namespace KeePassLib.Serialization
finally { CommonCleanUpRead(sSource, hashedStream); }
}
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[4096];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
output.Seek(0, SeekOrigin.Begin);
}
private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream)
{
hashedStream.Close();

View File

@ -94,7 +94,7 @@ namespace keepass2android
}
public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, String password, String keyfile, ProgressDialogStatusLogger status)
public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, MemoryStream databaseData, String password, String keyfile, ProgressDialogStatusLogger status)
{
PwDatabase pwDatabase = new PwDatabase();
@ -112,11 +112,12 @@ namespace keepass2android
throw new KeyFileException();
}
}
IFileStorage fileStorage = _app.GetFileStorage(iocInfo);
var filename = fileStorage.GetFilenameWithoutPathAndExt(iocInfo);
try
{
IFileStorage fileStorage = _app.GetFileStorage(iocInfo);
pwDatabase.Open(fileStorage.OpenFileForRead(iocInfo), fileStorage.GetFilenameWithoutPathAndExt(iocInfo), iocInfo, compositeKey, status);
pwDatabase.Open(databaseData, filename, iocInfo, compositeKey, status);
}
catch (Exception)
{
@ -125,7 +126,8 @@ namespace keepass2android
//if we don't get a password, we don't know whether this means "empty password" or "no password"
//retry without password:
compositeKey.RemoveUserKey(compositeKey.GetUserKey(typeof (KcpPassword)));
pwDatabase.Open(iocInfo, compositeKey, status);
databaseData.Seek(0, SeekOrigin.Begin);
pwDatabase.Open(databaseData, filename, iocInfo, compositeKey, status);
}
else throw;
}

View File

@ -16,21 +16,24 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using System.IO;
using KeePassLib.Serialization;
namespace keepass2android
{
public class LoadDb : RunnableOnFinish {
private readonly IOConnectionInfo _ioc;
private readonly MemoryStream _databaseData;
private readonly String _pass;
private readonly String _key;
private readonly IKp2aApp _app;
private readonly bool _rememberKeyfile;
public LoadDb(IKp2aApp app, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish)
public LoadDb(IKp2aApp app, IOConnectionInfo ioc, MemoryStream databaseData, String pass, String key, OnFinish finish): base(finish)
{
_app = app;
_ioc = ioc;
_databaseData = databaseData;
_pass = pass;
_key = key;
@ -44,7 +47,7 @@ namespace keepass2android
try
{
StatusLogger.UpdateMessage(UiStringKey.loading_database);
_app.GetDb().LoadData (_app, _ioc, _pass, _key, StatusLogger);
_app.GetDb().LoadData (_app, _ioc, _databaseData, _pass, _key, StatusLogger);
SaveFileData (_ioc, _key);
} catch (KeyFileException) {

View File

@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
@ -29,6 +30,9 @@ using Android.Text;
using Android.Content.PM;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using KeePassLib.Utility;
using MemoryStream = System.IO.MemoryStream;
namespace keepass2android
{
@ -331,6 +335,9 @@ namespace keepass2android
}
}
// Create task to kick off file loading while the user enters the password
var loadDbTask = new Task<MemoryStream>(LoadDbFile);
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
SetContentView(Resource.Layout.password);
@ -364,7 +371,7 @@ namespace keepass2android
App.Kp2a.GetDb().QuickUnlockKeyLength = int.Parse(_prefs.GetString(GetString(Resource.String.QuickUnlockLength_key), GetString(Resource.String.QuickUnlockLength_default)));
Handler handler = new Handler();
LoadDb task = new LoadDb(App.Kp2a, _ioConnection, pass, key, new AfterLoad(handler, this));
LoadDb task = new LoadDb(App.Kp2a, _ioConnection, loadDbTask.Result, pass, key, new AfterLoad(handler, this));
ProgressTask pt = new ProgressTask(App.Kp2a, this, task);
pt.Run();
};
@ -439,7 +446,34 @@ namespace keepass2android
RetrieveSettings();
loadDbTask.Start();
}
private MemoryStream LoadDbFile()
{
System.Diagnostics.Debug.WriteLine("LoadDbFile Started");
var fileStorage = App.Kp2a.GetFileStorage(_ioConnection);
var stream = fileStorage.OpenFileForRead(_ioConnection);
var memoryStream = stream as MemoryStream;
if (memoryStream == null)
{
// Read the file into memory
int capacity = 4096; // Default initial capacity, if stream can't report it.
if (stream.CanSeek)
{
capacity = (int)stream.Length;
System.Diagnostics.Debug.WriteLine("LoadDbFile, data size: " + capacity);
}
memoryStream = new MemoryStream(capacity);
MemUtil.CopyStream(stream, memoryStream);
stream.Close();
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
}
System.Diagnostics.Debug.WriteLine("LoadDbFile Done");
return memoryStream;
}
protected override void OnSaveInstanceState(Bundle outState)