Async load database encrypted bytes to memory while entering password
This commit is contained in:
		| @@ -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(); | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
| @@ -113,10 +113,11 @@ namespace keepass2android | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			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; | ||||
| 			} | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 AlexVallat
					AlexVallat