Exemplo n.º 1
0
        /// <summary>
        /// Saves an encrypted string containing the CompositeKey information to the Password vault.
        /// </summary>
        /// <param name="dbPath">Database Path. This is the identification of the database, if database is moved or name is changed,
        /// New credentials must be created.</param>
        /// <param name="keyList">KeyList object containing the composite key information.</param>
        /// <param name="rResult">KeyCredential object used to sign a key to encrypt the compositekey information.</param>
        /// <returns>String representing the result of the operation. Success or the error thrown.</returns>
        internal static async Task <string> SaveKeys(string dbPath, KeyList keyList, KeyCredentialRetrievalResult rResult)
        {
            try
            {
                PasswordVault myVault   = new PasswordVault();
                String        encrypted = await Encrypt(Library.ConvertToPString(keyList), rResult);

                PasswordCredential newCredential = new PasswordCredential(dbPath, WinHelloUnlockExt.ProductName, encrypted);
                newCredential.RetrievePassword();
                myVault.Add(newCredential);
                return("Success");
            }
            catch (Exception ev)
            {
                return(ev.Message);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates the data for WinHelloUnlock to work.
        /// 1. A Key Credential to sign a cryptographic key.
        /// 2. A Password vault to save the data into
        /// 3. A Password Credential in which to save the encrypted data (using the signed cryptographic key).
        /// </summary>
        /// <param name="dbPath">Database path. This is the identity of the database, if Database is moved or renamed,
        /// WinHelloUnlock will not work and new data needs to be created.
        /// </param>
        /// <returns>True if all the data was saved successfully.</returns>
        internal static async Task <bool> CreateHelloData(string dbPath)
        {
            bool isHelloAvailable = await UWPLibrary.IsHelloAvailable();

            if (isHelloAvailable)
            {
                KeyCredentialCreationOption  optionNew       = KeyCredentialCreationOption.ReplaceExisting;
                KeyCredentialRetrievalResult retrievalResult = await UWPLibrary.CreateCredential(dbPath, optionNew);

                if (retrievalResult.Status == KeyCredentialStatus.Success)
                {
                    KeyList keyList    = Library.GetKeys(WinHelloUnlockExt.database);
                    string  resultSave = await UWPLibrary.SaveKeys(dbPath, keyList, retrievalResult);

                    if (resultSave == "Success")
                    {
                        MessageService.ShowInfo("Database Keys saved successfuly");
                        UWPLibrary.ck = KeePass.Program.MainForm.ActiveDatabase.MasterKey;
                        return(true);
                    }
                    else
                    {
                        if (resultSave.Substring(0, 20) == "Value cannot be null")
                        {
                            MessageService.ShowWarning("Error saving the composite key: MasterKey was null." +
                                                       " Verify that \"Remember master password (in encrypted form) of a database while it is open\" option under Tools/Options/Security" +
                                                       " is enabled, then lock and unlock the database.");
                        }
                        else
                        {
                            MessageService.ShowWarning("Error saving the composite key: " + resultSave);
                        }
                    }
                }
                else
                {
                    WinHelloErrors(retrievalResult.Status, "Error creating the credential: ");
                }
            }
            else
            {
                MessageService.ShowWarning("Windows Hello is NOT Available");
            }
            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Converts a KeyList object to a properly formatted ProtectedString
        /// </summary>
        /// <param name="keys">KeyList containing the composite key information.</param>
        /// <returns>ProtectedString containing KeyList information.</returns>
        internal static ProtectedString ConvertToPString(KeyList keys)
        {
            string div2 = WinHelloUnlockExt.ProductName + ",";
            string div  = WinHelloUnlockExt.ShortProductName + ",";

            if (keys.Pass == null || keys.KeyName == null || keys == null)
            {
                return(null);
            }
            ProtectedString pass = ProtectedString.EmptyEx;

            foreach (ProtectedString ps in keys.Pass)
            {
                pass += ps + div;
            }
            pass = pass.Remove(pass.Length - div.Length, div.Length);
            ProtectedString key = new ProtectedString(true, string.Join(div, keys.KeyName));

            key = key.Insert(key.Length, div2);
            return(key + pass);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Retrieves the CompositeKey information from the Password vault.
        /// </summary>
        /// <param name="dbPath">Database Path. This is the identification of the database, if database is moved or name is changed,
        /// New credentials must be created.</param>
        /// <param name="rResult">KeyCredential object used to sign a key to decrypt the compositekey information.</param>
        /// <returns>KeyList object with all the information to compose the CompositeKey.</returns>
        internal async static Task <KeyList> RetrieveKeys(string dbPath, KeyCredentialRetrievalResult rResult)
        {
            PasswordVault myVault       = new PasswordVault();
            var           newCredential = new PasswordCredential();

            try
            {
                newCredential = myVault.Retrieve(dbPath, WinHelloUnlockExt.ProductName);
                newCredential.RetrievePassword();
            }
            catch (Exception ev)
            {
                MessageService.ShowInfo("Not able to retrieve Composite Key from Microsoft Password Vault. " +
                                        "Maybe saving again will solve the problem. Message: " + ev.Message);
                return(new KeyList(null, null));
            }
            try
            {
                string          encrypted = newCredential.Password;
                ProtectedString decrypted = await Decrypt(encrypted, rResult);

                if (decrypted != null)
                {
                    KeyList Keys = Library.ConvertKeyList(decrypted);
                    decrypted = ProtectedString.EmptyEx;
                    return(Keys);
                }
                else
                {
                    return(new KeyList(null, null));
                }
            }
            catch (Exception ev)
            {
                MessageService.ShowInfo("Credential not retrieved: " + ev.Message);
                Debug.Write(ev.Message);
                return(new KeyList(null, null));
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates the data for WinHelloUnlock to work.
        /// 1. A Key Credential to sign a cryptographic key.
        /// 2. A Password vault to save the data into
        /// 3. A Password Credential in which to save the encrypted data (using the signed cryptographic key).
        /// </summary>
        /// <param name="dbPath">Database path. This is the identity of the database, if Database is moved or renamed,
        /// WinHelloUnlock will not work and new data needs to be created.
        /// </param>
        /// <returns>True if all the data was saved successfully.</returns>
        internal static async Task <bool> CreateHelloData(string dbPath)
        {
            bool isHelloAvailable = await UWPLibrary.IsHelloAvailable();

            if (isHelloAvailable)
            {
                KeyCredentialCreationOption  optionNew       = KeyCredentialCreationOption.ReplaceExisting;
                KeyCredentialRetrievalResult retrievalResult = await UWPLibrary.CreateCredential(dbPath, optionNew);

                if (retrievalResult.Status == KeyCredentialStatus.Success)
                {
                    KeyList keyList    = Library.GetKeys(WinHelloUnlockExt.database);
                    string  resultSave = await UWPLibrary.SaveKeys(dbPath, keyList, retrievalResult);

                    if (resultSave == "Success")
                    {
                        MessageService.ShowInfo("Database Keys saved successfuly");
                        UWPLibrary.ck = KeePass.Program.MainForm.ActiveDatabase.MasterKey;
                        return(true);
                    }
                    else
                    {
                        MessageService.ShowWarning("Error saving the composite key: " + resultSave);
                    }
                }
                else
                {
                    WinHelloErrors(retrievalResult.Status, "Error creating the credential: ");
                }
            }
            else
            {
                MessageService.ShowWarning("Windows Hello is NOT Available");
            }
            return(false);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Performs the actual unlock of the database
        /// </summary>
        /// <param name="ioInfo">IOConnectionInfo that represents the Database.</param>
        internal static async Task UnlockDatabase(IOConnectionInfo ioInfo, KeyPromptForm keyPromptForm)
        {
            string dbPath = Library.CharChange(ioInfo.Path);

            KeyCredentialRetrievalResult retrievalResult = await OpenCredential(dbPath);

            if (retrievalResult.Status == KeyCredentialStatus.Success) // If credential is successfully retrieved
            {
                KeyList keyList = await RetrieveKeys(dbPath, retrievalResult);

                CompositeKey compositeKey = Library.ConvertToComposite(keyList);

                // Composite Key is retrieved so the number of tries is augmented
                ++WinHelloUnlockExt.tries;

                if (compositeKey != null)                             // If there is actually a composite key
                {
                    if (Library.CheckMasterKey(ioInfo, compositeKey)) // If the composite key actually unlocks the database
                    {
                        // Unlock the database
                        Unlock(keyPromptForm, compositeKey);

                        // Check if the database was actually opened
                        string openedDBPath = WinHelloUnlockExt.Host.MainWindow.ActiveDatabase.IOConnectionInfo.Path;
                        if (openedDBPath != ioInfo.Path &&                  // If opened DB is not the same we are trying to open
                            WinHelloUnlockExt.updateCheckForm != null)      // and UpdateCheckForm is opened then the database was not opened because of that
                        {
                            // Using a global Composite key to test for changes
                            ck = compositeKey;

                            // Register an event handler to be able to unlock the database after updateCheckForm is closed
                            WinHelloUnlockExt.updateCheckForm.FormClosed += (object sender, FormClosedEventArgs e) =>
                                                                            UpdateFormClosedEventHandler(ioInfo);
                        }

                        if (WinHelloUnlockExt.isAutoTyping && WinHelloUnlockExt.LockAfterAutoType)
                        {
                            var _ = Task.Factory.StartNew(() => LockAfterAutoType());
                            //MessageService.ShowInfo("autotyping");
                        }
                    }
                    else // If composite key did not unlock the database prompt the user to delete the credentials
                    {
                        await Library.HandleMasterKeyChange(ioInfo, dbPath, true);
                    }
                }
                else // If compositeKey is null, open regular unlock prompt to unlock the database
                {
                    if (WinHelloUnlockExt.secureChaged)
                    {
                        KeePass.Program.Config.Security.MasterKeyOnSecureDesktop = true;
                        WinHelloUnlockExt.secureChaged = false;
                        Library.CloseFormWithResult(keyPromptForm, DialogResult.Cancel);
                        var _ = Task.Factory.StartNew(() => KeePass.Program.MainForm.OpenDatabase(ioInfo, null, true));
                    }
                    else
                    {
                        keyPromptForm.Visible = true;
                        keyPromptForm.Opacity = 1;
                    }
                }

                // Delete composite key data
                compositeKey = null;

                // Delete KeyList object
                keyList = new KeyList(null, null);
            }
            else
            {
                // If credentials were not successfully retrieved inform the user and open regular unlock prompt
                WinHelloErrors(retrievalResult.Status, "Error unlocking database: ");
                if (WinHelloUnlockExt.secureChaged)
                {
                    KeePass.Program.Config.Security.MasterKeyOnSecureDesktop = true;
                    WinHelloUnlockExt.secureChaged = false;
                    Library.CloseFormWithResult(keyPromptForm, DialogResult.Cancel);
                    var _ = Task.Factory.StartNew(() => KeePass.Program.MainForm.OpenDatabase(ioInfo, null, true));
                }
                else
                {
                    keyPromptForm.Visible = true;
                    keyPromptForm.Opacity = 1;
                }
            }
        }