From fa5fefbd3f4c60fcfdad605917b57a6470e25500 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 6 Nov 2019 11:04:35 +0200 Subject: [PATCH 1/2] Fixed performance issue on large values of "Password iterations" When user try to open files with large values of "Password iterations", the interface does not freeze, but it becomes unclickable. When saving files, there will be the same effect. --- Crypto Notepad/AES.cs | 221 +++++++++++++++-------------- Crypto Notepad/ExRichTextBox.cs | 19 +++ Crypto Notepad/MainForm.cs | 242 +++++++++++++++++++++++--------- Crypto Notepad/MainForm.resx | 10 +- 4 files changed, 318 insertions(+), 174 deletions(-) diff --git a/Crypto Notepad/AES.cs b/Crypto Notepad/AES.cs index acefefc..3488722 100644 --- a/Crypto Notepad/AES.cs +++ b/Crypto Notepad/AES.cs @@ -4,6 +4,7 @@ using System.Text; using System.Windows.Forms; using System.Collections.Generic; +using System.Threading.Tasks; namespace Crypto_Notepad { @@ -40,7 +41,8 @@ private bool ReadData(byte[] rawData, int offset, ref byte[] dataOut) bool foundData = false; // Push data to buffer - for (int i = offset; i < rawData.Length; i++) { + for (int i = offset; i < rawData.Length; i++) + { if (rawData[i] == nullTerminator) { foundData = true; break; } else { buffer.Add(rawData[i]); } } @@ -112,138 +114,145 @@ private static byte[] GenerateSecureNonZeroByteArray(int length) return result; } - public static string Encrypt(string plainText, string password, + public static async Task Encrypt(string plainText, string password, string salt = null, string hashAlgorithm = "SHA1", int passwordIterations = 2, int keySize = 256) { - if (string.IsNullOrEmpty(plainText)) - return null; - if (string.IsNullOrEmpty(password)) - return null; + return await Task.Run(() => + { + if (string.IsNullOrEmpty(plainText)) + return null; + if (string.IsNullOrEmpty(password)) + return null; - byte[] plainTextBytes; - byte[] saltValueBytes; + byte[] plainTextBytes; + byte[] saltValueBytes; - // In case user wants a random salt or salt is null/empty for some other reason - if (string.IsNullOrEmpty(salt)) - { - saltValueBytes = new byte[64]; // Nice and long - saltValueBytes = GenerateSecureNonZeroByteArray(saltValueBytes.Length); - } - else - { - saltValueBytes = Encoding.ASCII.GetBytes(salt); - } + // In case user wants a random salt or salt is null/empty for some other reason + if (string.IsNullOrEmpty(salt)) + { + saltValueBytes = new byte[64]; // Nice and long + saltValueBytes = GenerateSecureNonZeroByteArray(saltValueBytes.Length); + } + else + { + saltValueBytes = Encoding.ASCII.GetBytes(salt); + } - plainTextBytes = Encoding.UTF8.GetBytes(plainText); + plainTextBytes = Encoding.UTF8.GetBytes(plainText); - PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes - (password, saltValueBytes, hashAlgorithm, passwordIterations); + PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes + (password, saltValueBytes, hashAlgorithm, passwordIterations); - // Null password; adds *some* memory dump protection - password = null; + // Null password; adds *some* memory dump protection + password = null; - byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); - RijndaelManaged symmetricKey = new RijndaelManaged(); - symmetricKey.Mode = CipherMode.CBC; + byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); + RijndaelManaged symmetricKey = new RijndaelManaged(); + symmetricKey.Mode = CipherMode.CBC; - // Generate IV - symmetricKey.IV = GenerateSecureNonZeroByteArray(symmetricKey.IV.Length); + // Generate IV + symmetricKey.IV = GenerateSecureNonZeroByteArray(symmetricKey.IV.Length); - byte[] cipherTextBytes = null; + byte[] cipherTextBytes = null; - using (MemoryStream memStream = new MemoryStream()) - { - AESMetadata.WriteMetadata(memStream, symmetricKey.IV, saltValueBytes); + using (MemoryStream memStream = new MemoryStream()) + { + AESMetadata.WriteMetadata(memStream, symmetricKey.IV, saltValueBytes); - using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor - (keyBytes, symmetricKey.IV)) - { - using (CryptoStream cryptoStream = new CryptoStream - (memStream, encryptor, CryptoStreamMode.Write)) - { - cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); - cryptoStream.FlushFinalBlock(); - cipherTextBytes = memStream.ToArray(); - memStream.Close(); - cryptoStream.Close(); - - } - } - } + using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor + (keyBytes, symmetricKey.IV)) + { + using (CryptoStream cryptoStream = new CryptoStream + (memStream, encryptor, CryptoStreamMode.Write)) + { + cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); + cryptoStream.FlushFinalBlock(); + cipherTextBytes = memStream.ToArray(); + memStream.Close(); + cryptoStream.Close(); - symmetricKey.Dispose(); - derivedPassword.Dispose(); - return Convert.ToBase64String(cipherTextBytes); + } + } + } + + symmetricKey.Dispose(); + derivedPassword.Dispose(); + return Convert.ToBase64String(cipherTextBytes); + }); } - public static string Decrypt(string cipherText, string password, string salt = "Kosher", + public static async Task Decrypt(string cipherText, string password, string salt = "Kosher", string hashAlgorithm = "SHA1", int passwordIterations = 2, int keySize = 256) { - if (string.IsNullOrEmpty(cipherText)) - return null; - if (string.IsNullOrEmpty(password)) - return null; - - byte[] initialVectorBytes; - byte[] saltValueBytes; - byte[] cipherTextBytes = Convert.FromBase64String(cipherText); - - // Extract metadata from file - AESMetadata metadata = new AESMetadata(); - if (!metadata.GetMetadata(cipherTextBytes)) + return await Task.Run(() => { - // Metadata parsing error - DialogResult result = MessageBox.Show("Unable to parse file metadata.\nAttempt to open anyway?\n(May result in a \'Incorrect Key\' error if the salt is wrong.)", - "Missing or Corrupted Metadata", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk); - if (result == DialogResult.Yes) + if (string.IsNullOrEmpty(cipherText)) + return null; + if (string.IsNullOrEmpty(password)) + return null; + + byte[] initialVectorBytes; + byte[] saltValueBytes; + byte[] cipherTextBytes = Convert.FromBase64String(cipherText); + + // Extract metadata from file + AESMetadata metadata = new AESMetadata(); + if (!metadata.GetMetadata(cipherTextBytes)) { - // Default initialization vector from builds v1.1.2 and older - const string default_IV = "16CHARSLONG12345"; - - initialVectorBytes = Encoding.ASCII.GetBytes(default_IV); - saltValueBytes = Encoding.ASCII.GetBytes(salt); - } - else { return null; } - } - else - { - saltValueBytes = metadata.Salt; - initialVectorBytes = metadata.InitialVector; - metadata.DeleteMetadataFromBuffer(ref cipherTextBytes); - } - - PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes - (password, saltValueBytes, hashAlgorithm, passwordIterations); - byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); - - RijndaelManaged symmetricKey = new RijndaelManaged(); - symmetricKey.Mode = CipherMode.CBC; - - byte[] plainTextBytes = new byte[cipherTextBytes.Length]; - int byteCount = 0; - - using (MemoryStream memStream = new MemoryStream(cipherTextBytes)) - { - using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor - (keyBytes, initialVectorBytes)) - { - using (CryptoStream cryptoStream - = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read)) + // Metadata parsing error + DialogResult result = MessageBox.Show("Unable to parse file metadata.\nAttempt to open anyway?\n(May result in a \'Incorrect Key\' error if the salt is wrong.)", + "Missing or Corrupted Metadata", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk); + if (result == DialogResult.Yes) { - byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); - memStream.Close(); - cryptoStream.Close(); + // Default initialization vector from builds v1.1.2 and older + const string default_IV = "16CHARSLONG12345"; + + initialVectorBytes = Encoding.ASCII.GetBytes(default_IV); + saltValueBytes = Encoding.ASCII.GetBytes(salt); } + else { return null; } + } + else + { + saltValueBytes = metadata.Salt; + initialVectorBytes = metadata.InitialVector; + metadata.DeleteMetadataFromBuffer(ref cipherTextBytes); } - symmetricKey.Dispose(); - } + PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes + (password, saltValueBytes, hashAlgorithm, passwordIterations); + byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); - derivedPassword.Dispose(); - return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount); + RijndaelManaged symmetricKey = new RijndaelManaged(); + symmetricKey.Mode = CipherMode.CBC; + + byte[] plainTextBytes = new byte[cipherTextBytes.Length]; + int byteCount = 0; + + using (MemoryStream memStream = new MemoryStream(cipherTextBytes)) + { + using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor + (keyBytes, initialVectorBytes)) + { + using (CryptoStream cryptoStream + = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read)) + { + byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); + memStream.Close(); + cryptoStream.Close(); + } + } + + symmetricKey.Dispose(); + } + + derivedPassword.Dispose(); + + return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount); + }); } } } diff --git a/Crypto Notepad/ExRichTextBox.cs b/Crypto Notepad/ExRichTextBox.cs index 4f95ed4..f76f6cd 100644 --- a/Crypto Notepad/ExRichTextBox.cs +++ b/Crypto Notepad/ExRichTextBox.cs @@ -99,5 +99,24 @@ private static Rectangle GetFormattingRect(this TextBoxBase textbox) return rect; } } + + public static class RichTextBoxExtensions + { + [DllImport("user32.dll")] + private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); + private const int WM_SETREDRAW = 0x0b; + + public static void SuspendDrawing(this RichTextBox richTextBox) + { + SendMessage(richTextBox.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero); + } + + public static void ResumeDrawing(this RichTextBox richTextBox) + { + SendMessage(richTextBox.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero); + richTextBox.Invalidate(); + } + } + } diff --git a/Crypto Notepad/MainForm.cs b/Crypto Notepad/MainForm.cs index e18df3c..e9e8b7d 100644 --- a/Crypto Notepad/MainForm.cs +++ b/Crypto Notepad/MainForm.cs @@ -66,17 +66,21 @@ static string SizeSuffix(long value) return string.Format("{0:n1} {1}", dValue, SizeSuffixes[i]); } - private void DecryptAES() + private async Task DecryptAES() { - EnterKeyForm enterKeyForm = new EnterKeyForm - { - Owner = this - }; + EnterKeyForm enterKeyForm = new EnterKeyForm(); + enterKeyForm.Owner = this; enterKeyForm.ShowDialog(); - + richTextBox.SuspendDrawing(); + UseWaitCursor = true; if (!PublicVar.okPressed) { PublicVar.openFileName = Path.GetFileName(filePath); + mainMenu.Enabled = true; + toolbarPanel.Enabled = true; + richTextBox.ReadOnly = false; + UseWaitCursor = false; + richTextBox.ResumeDrawing(); return; } if (searchPanel.Visible) @@ -85,38 +89,65 @@ private void DecryptAES() } try { - string opnfile = File.ReadAllText(openFileDialog.FileName); + using (StreamReader reader = File.OpenText(openFileDialog.FileName)) + { + mainMenu.Enabled = false; + toolbarPanel.Enabled = false; + richTextBox.ReadOnly = true; + string openedFileText = await reader.ReadToEndAsync(); + richTextBox.Text = await AES.Decrypt(openedFileText, TypedPassword.Value, null, settings.HashAlgorithm, + Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); ; + } + string NameWithotPath = Path.GetFileName(openFileDialog.FileName); - string de; - de = AES.Decrypt(opnfile, TypedPassword.Value, null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); - richTextBox.Text = de; Text = PublicVar.appName + " – " + NameWithotPath; filePath = openFileDialog.FileName; PublicVar.openFileName = Path.GetFileName(openFileDialog.FileName); PublicVar.encryptionKey.Set(TypedPassword.Value); TypedPassword.Value = null; StatusPanelFileInfo(); + mainMenu.Enabled = true; + toolbarPanel.Enabled = true; + richTextBox.ReadOnly = false; + UseWaitCursor = false; + richTextBox.ResumeDrawing(); } - catch (CryptographicException) + catch (Exception ex) { - using (new CenterWinDialog(this)) + if (ex is FormatException | ex is CryptographicException) { - TypedPassword.Value = null; - DialogResult dialogResult = MessageBox.Show(this, "Invalid key!", PublicVar.appName, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); - if (dialogResult == DialogResult.Retry) + PublicVar.okPressed = false; + if (Visible) { - DecryptAES(); PublicVar.messageBoxCenterParent = true; } - if (dialogResult == DialogResult.Cancel) + using (new CenterWinDialog(this)) { - PublicVar.openFileName = Path.GetFileName(filePath); + TypedPassword.Value = null; + DialogResult dialogResult = MessageBox.Show(this, "Invalid key!", PublicVar.appName, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); + if (dialogResult == DialogResult.Retry) + { + await DecryptAES(); + } + if (dialogResult == DialogResult.Cancel) + { + PublicVar.openFileName = Path.GetFileName(filePath); + mainMenu.Enabled = true; + toolbarPanel.Enabled = true; + richTextBox.ReadOnly = false; + UseWaitCursor = false; + richTextBox.ResumeDrawing(); + if (!Visible) + { + Application.Exit(); + } + } } } } } - private void OpenAsotiations() + private async void OpenAsotiations() { EnterKeyForm enterKeyForm = new EnterKeyForm { @@ -128,7 +159,8 @@ private void OpenAsotiations() openFileDialog.FileName = Path.GetFullPath(args[1]); if (fileExtension != ".cnp") { - DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (res == DialogResult.No) { string opnfile = File.ReadAllText(args[1]); @@ -140,10 +172,10 @@ private void OpenAsotiations() return; } } - DecryptAES(); + await DecryptAES(); } - private void SendTo() + private async void SendTo() { EnterKeyForm enterKeyForm = new EnterKeyForm { @@ -155,7 +187,8 @@ private void SendTo() PublicVar.openFileName = Path.GetFileName(argsPath); if (fileExtension != ".cnp") { - DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (res == DialogResult.No) { string opnfile = File.ReadAllText(argsPath); @@ -167,41 +200,40 @@ private void SendTo() return; } } - DecryptAES(); + await DecryptAES(); } - private void ContextMenuEncryptReplace() + private async void ContextMenuEncryptReplace() { - DialogResult res = MessageBox.Show(this, "This action will delete the source file and replace it with encrypted version", PublicVar.appName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); + DialogResult res = MessageBox.Show(this, "This action will delete the source file and replace it with encrypted version", PublicVar.appName, + MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (res == DialogResult.Cancel) { Environment.Exit(0); } - string opnfile = File.ReadAllText(args[1]); - richTextBox.Text = opnfile; + richTextBox.Text = File.ReadAllText(args[1]); PublicVar.openFileName = Path.GetFileName(args[1]); - string newFile = Path.GetDirectoryName(args[1]) + @"\" + Path.GetFileNameWithoutExtension(args[1]) + ".cnp"; + string newFileName = Path.GetDirectoryName(args[1]) + @"\" + Path.GetFileNameWithoutExtension(args[1]) + ".cnp"; EnterKeyForm enterKeyForm = new EnterKeyForm { Owner = this }; enterKeyForm.ShowDialog(); File.Delete(args[1]); - string noenc = richTextBox.Text; - string en; - en = AES.Encrypt(richTextBox.Text, TypedPassword.Value, null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); - richTextBox.Text = en; - using (StreamWriter writer = new StreamWriter(newFile)) + string unencryptedText = richTextBox.Text; + string encryptedText = await AES.Encrypt(richTextBox.Text, TypedPassword.Value, null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), + Convert.ToInt32(settings.KeySize)); + using (StreamWriter writer = new StreamWriter(newFileName)) { - writer.Write(richTextBox.Text); + writer.Write(encryptedText); writer.Close(); } PublicVar.encryptionKey.Set(TypedPassword.Value); TypedPassword.Value = null; - filePath = newFile; - PublicVar.openFileName = Path.GetFileName(newFile); + filePath = newFileName; + PublicVar.openFileName = Path.GetFileName(newFileName); Text = PublicVar.appName + " – " + PublicVar.openFileName; - richTextBox.Text = noenc; + richTextBox.Text = unencryptedText; StatusPanelFileInfo(); richTextBox.Modified = false; } @@ -243,6 +275,10 @@ private void SaveConfirm() { messageBoxText = "Save file: " + "\"" + PublicVar.openFileName + "\"" + " with a new key? "; } + if (Visible) + { + PublicVar.messageBoxCenterParent = true; + } using (new CenterWinDialog(this)) { DialogResult res = MessageBox.Show(this, messageBoxText, PublicVar.appName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); @@ -280,7 +316,8 @@ private void CheckForUpdates(bool autoCheck) { using (new CenterWinDialog(this)) { - DialogResult res = MessageBox.Show(this, "New version is available. Install it now?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + DialogResult res = MessageBox.Show(this, "New version is available. Install it now?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (res == DialogResult.Yes) { File.WriteAllBytes(exePath + "Ionic.Zip.dll", Resources.Ionic_Zip); @@ -324,7 +361,8 @@ private void CheckForUpdates(bool autoCheck) } else { - MessageBox.Show(this, "Checking for updates failed:\nConnection lost or the server is busy.", PublicVar.appName, MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show(this, "Checking for updates failed:\nConnection lost or the server is busy.", PublicVar.appName, + MessageBoxButtons.OK, MessageBoxIcon.Error); } } }); @@ -411,20 +449,33 @@ private void StatusPanelTimer_Tick(object sender, EventArgs e) statusPanelTimer.Stop(); } - private void UnlockFile() + private async Task UnlockFile() { try { + richTextBox.SuspendDrawing(); + UseWaitCursor = true; + fileLockedPanel.Enabled = false; TypedPassword.Value = fileLockedKeyTextBox.Text; - string opnfile = File.ReadAllText(filePath); - string de = AES.Decrypt(opnfile, TypedPassword.Value, null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); + mainMenu.Enabled = false; + toolbarPanel.Enabled = false; + using (StreamReader reader = File.OpenText(openFileDialog.FileName)) + { + string openedFileText = await reader.ReadToEndAsync(); + richTextBox.Text = await AES.Decrypt(openedFileText, TypedPassword.Value, null, settings.HashAlgorithm, + Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); ; + } fileLockedPanel.Visible = false; - richTextBox.Text = de; richTextBox.SelectionStart = caretPos; PublicVar.encryptionKey.Set(TypedPassword.Value); TypedPassword.Value = null; richTextBox.Focus(); StatusPanelFileInfo(); + richTextBox.ResumeDrawing(); + UseWaitCursor = false; + fileLockedPanel.Enabled = true; + mainMenu.Enabled = true; + toolbarPanel.Enabled = true; } catch (Exception ex) { @@ -437,6 +488,9 @@ private void UnlockFile() DialogResult dialogResult = MessageBox.Show(this, "Invalid key!", PublicVar.appName, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); if (dialogResult == DialogResult.Retry) { + UseWaitCursor = false; + richTextBox.ResumeDrawing(); + fileLockedPanel.Enabled = true; fileLockedKeyTextBox.Text = ""; fileLockedKeyTextBox.Focus(); } @@ -446,6 +500,9 @@ private void UnlockFile() Text = PublicVar.appName; filePath = ""; PublicVar.openFileName = ""; + UseWaitCursor = false; + richTextBox.ResumeDrawing(); + fileLockedPanel.Enabled = true; } } } @@ -705,8 +762,15 @@ private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) DialogResult res = MessageBox.Show(this, messageBoxText, PublicVar.appName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (res == DialogResult.Yes) { + Hide(); trayIcon.Visible = false; - SaveMainMenu_Click(this, new EventArgs()); + using (StreamWriter writer = new StreamWriter(filePath)) + { + string enc = ""; + Task.Run(async () => { enc = await AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); }).Wait(); + writer.Write(enc); + writer.Close(); + } } if (res == DialogResult.Cancel) { @@ -725,6 +789,10 @@ private void MainForm_Shown(object sender, EventArgs e) if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + "Crypto Notepad.settings")) { + if (Visible) + { + PublicVar.messageBoxCenterParent = true; + } using (new CenterWinDialog(this)) { DialogResult res = MessageBox.Show(this, "Enable automatic update check?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); @@ -819,7 +887,7 @@ private void RichTextBox_LinkClicked(object sender, LinkClickedEventArgs e) } } - private void RichTextBox_DragDrop(object sender, DragEventArgs e) + private async void RichTextBox_DragDrop(object sender, DragEventArgs e) { SaveConfirm(); if (cancelPressed) @@ -843,7 +911,8 @@ private void RichTextBox_DragDrop(object sender, DragEventArgs e) } using (new CenterWinDialog(this)) { - DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (res == DialogResult.No) { string opnfile = File.ReadAllText(openFileDialog.FileName); @@ -856,7 +925,7 @@ private void RichTextBox_DragDrop(object sender, DragEventArgs e) } } } - DecryptAES(); + await DecryptAES(); } } } @@ -908,7 +977,8 @@ private void StatusPanelLabel_Click(object sender, EventArgs e) string exePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + @"\"; using (new CenterWinDialog(this)) { - DialogResult res = MessageBox.Show(this, "New version is available. Install it now?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + DialogResult res = MessageBox.Show(this, "New version is available. Install it now?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (res == DialogResult.Yes) { File.WriteAllBytes(exePath + "Ionic.Zip.dll", Resources.Ionic_Zip); @@ -971,7 +1041,7 @@ private void NewMainMenu_Click(object sender, EventArgs e) TypedPassword.Value = null; } - private void OpenMainMenu_Click(object sender, EventArgs e) + private async void OpenMainMenu_Click(object sender, EventArgs e) { SaveConfirm(); if (cancelPressed) @@ -985,9 +1055,14 @@ private void OpenMainMenu_Click(object sender, EventArgs e) PublicVar.openFileName = Path.GetFileName(openFileDialog.FileName); if (!openFileDialog.FileName.Contains(".cnp")) { + if (Visible) + { + PublicVar.messageBoxCenterParent = true; + } using (new CenterWinDialog(this)) { - DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Information); + DialogResult res = MessageBox.Show(this, "Try to decrypt \"" + PublicVar.openFileName + "\" file?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (res == DialogResult.No) { string opnfile = File.ReadAllText(openFileDialog.FileName); @@ -1000,31 +1075,41 @@ private void OpenMainMenu_Click(object sender, EventArgs e) } } } - DecryptAES(); + await DecryptAES(); richTextBox.Modified = false; } } - private void SaveMainMenu_Click(object sender, EventArgs e) + private async void SaveMainMenu_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(PublicVar.encryptionKey.Get())) { SaveAsMainMenu_Click(this, new EventArgs()); return; } - string enc = AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); + mainMenu.Enabled = false; + toolbarPanel.Enabled = false; + richTextBox.ReadOnly = true; + richTextBox.SuspendDrawing(); + UseWaitCursor = true; using (StreamWriter writer = new StreamWriter(filePath)) { - writer.Write(enc); + writer.Write(await AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, + Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize))); writer.Close(); } richTextBox.Modified = false; PublicVar.keyChanged = false; StatusPanelMessage("save"); StatusPanelFileInfo(); + richTextBox.ResumeDrawing(); + UseWaitCursor = false; + mainMenu.Enabled = true; + toolbarPanel.Enabled = true; + richTextBox.ReadOnly = false; } - private void SaveAsMainMenu_Click(object sender, EventArgs e) + private async void SaveAsMainMenu_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(filePath)) { @@ -1058,7 +1143,8 @@ private void SaveAsMainMenu_Click(object sender, EventArgs e) TypedPassword.Value = PublicVar.encryptionKey.Get(); } filePath = saveFileDialog.FileName; - string enc = AES.Encrypt(richTextBox.Text, TypedPassword.Value, null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); + string enc = await AES.Encrypt(richTextBox.Text, TypedPassword.Value, null, settings.HashAlgorithm, + Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize)); using (StreamWriter writer = new StreamWriter(filePath)) { writer.Write(enc); @@ -1075,11 +1161,28 @@ private void SaveAsMainMenu_Click(object sender, EventArgs e) private async void SaveCloseFileMainMenu_Click(object sender, EventArgs e) { + //using (StreamWriter writer = new StreamWriter(filePath)) + //{ + // writer.Write(AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, + // Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize))); + // writer.Close(); + //} + + mainMenu.Enabled = false; + toolbarPanel.Enabled = false; + richTextBox.SuspendDrawing(); + UseWaitCursor = true; using (StreamWriter writer = new StreamWriter(filePath)) { - writer.Write(AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize))); + writer.Write(await AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, + Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize))); writer.Close(); } + richTextBox.ResumeDrawing(); + UseWaitCursor = false; + mainMenu.Enabled = true; + toolbarPanel.Enabled = true; + richTextBox.ReadOnly = false; PublicVar.encryptionKey.Set(null); richTextBox.Clear(); PublicVar.openFileName = ""; @@ -1101,7 +1204,8 @@ private void DeleteFileToolStripMenuItem_Click(object sender, EventArgs e) { using (new CenterWinDialog(this)) { - if (MessageBox.Show(this, "Delete file: " + "\"" + filePath + "\"" + " ?", PublicVar.appName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + if (MessageBox.Show(this, "Delete file: " + "\"" + filePath + "\"" + " ?", PublicVar.appName, + MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { File.Delete(filePath); richTextBox.Clear(); @@ -1289,9 +1393,21 @@ private void ChangeKeyMainMenu_Click(object sender, EventArgs e) changeKeyForm.ShowDialog(this); } - private void LockMainMenu_Click(object sender, EventArgs e) + private async void LockMainMenu_Click(object sender, EventArgs e) { - SaveMainMenu_Click(this, new EventArgs()); + //SaveMainMenu_Click(this, new EventArgs()); + mainMenu.Enabled = false; + toolbarPanel.Enabled = false; + richTextBox.SuspendDrawing(); + UseWaitCursor = true; + using (StreamWriter writer = new StreamWriter(filePath)) + { + writer.Write(await AES.Encrypt(richTextBox.Text, PublicVar.encryptionKey.Get(), null, settings.HashAlgorithm, + Convert.ToInt32(settings.PasswordIterations), Convert.ToInt32(settings.KeySize))); + writer.Close(); + } + richTextBox.ResumeDrawing(); + UseWaitCursor = false; fileLockedPanel.Visible = true; } @@ -1696,9 +1812,9 @@ private void FileLockedPanel_VisibleChanged(object sender, EventArgs e) } } - private void FileLockedOkButton_Click(object sender, EventArgs e) + private async void FileLockedOkButton_Click(object sender, EventArgs e) { - UnlockFile(); + await UnlockFile(); } private void FileLockedCloseButton_MouseClick(object sender, MouseEventArgs e) diff --git a/Crypto Notepad/MainForm.resx b/Crypto Notepad/MainForm.resx index 63b73e3..b9cbf15 100644 --- a/Crypto Notepad/MainForm.resx +++ b/Crypto Notepad/MainForm.resx @@ -121,7 +121,7 @@ 17, 17 - 676, 17 + 533, 17 127, 17 @@ -146,7 +146,7 @@ - 1112, 17 + 969, 17 @@ -290,13 +290,13 @@ - 904, 17 + 761, 17 - 1017, 17 + 874, 17 - 800, 17 + 657, 17 From 5412d089cd85daa0d18858ffca49aa2e9da91bce Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 6 Nov 2019 11:05:18 +0200 Subject: [PATCH 2/2] Disabled "modified" tooltip when file is locked --- Crypto Notepad/MainForm.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Crypto Notepad/MainForm.cs b/Crypto Notepad/MainForm.cs index e9e8b7d..a4c7197 100644 --- a/Crypto Notepad/MainForm.cs +++ b/Crypto Notepad/MainForm.cs @@ -1790,6 +1790,7 @@ private void FileLockedPanel_VisibleChanged(object sender, EventArgs e) richTextBox.Clear(); StatusPanelTextInfo(); statusPanelModifiedLabel.Text = "Modified"; + statusPanelModifiedLabel.ToolTipText = null; statusPanelSizeLabel.Text = "Size"; fileLockedKeyTextBox.Focus(); }