From 53a222a7da547bfe95736c5ffdf0ce29edfcc4b4 Mon Sep 17 00:00:00 2001 From: Toni Date: Tue, 11 Nov 2025 12:20:35 +0100 Subject: [PATCH] handle invalid passwords --- src/crypto.h | 2 +- src/mainwindow.cc | 34 ++++++++++++++++++++++++---------- src/vault.cc | 11 ++++++++++- src/vault.h | 2 +- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/crypto.h b/src/crypto.h index bbf784f..39ad7ff 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -59,4 +59,4 @@ derive_key_argon2id(const std::string &password, return key; } -}; // namespace Crypto \ No newline at end of file +}; // namespace Crypto diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 01c8123..8325e2c 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -1,5 +1,6 @@ // TODO: actual fs #include "mainwindow.h" +#include "crypto.h" #include #include #include @@ -41,13 +42,23 @@ MainWindow::MainWindow(QWidget *parent) QCoreApplication::processEvents(); static Botan::AutoSeeded_RNG rng; - auto salt_sv = rng.random_vec(16); - std::vector salt(salt_sv.begin(), salt_sv.end()); + auto salt = rng.random_array<16>(); + + auto key = Crypto::derive_key_argon2id(password.toStdString(), salt); + auto check_nonce = rng.random_array<24>(); + + const std::string content = "LETSGO"; + Botan::secure_vector content_sv(content.begin(), content.end()); + auto check_ciphertext = + Crypto::encrypt_xchacha20_poly1305(content_sv, key, check_nonce); std::ofstream create(path.toStdString(), std::ios::binary); create.write("DULL", 4); create.write(to_char_ptr(&VERSION), sizeof(VERSION)); create.write(to_char_ptr(salt.data()), 16); + + create.write(to_char_ptr(check_nonce.data()), 24); + create.write(to_char_ptr(check_ciphertext.data()), 22); create.close(); m_vault = @@ -71,16 +82,19 @@ MainWindow::MainWindow(QWidget *parent) return; } - // TODO: check if password valid - ui->statusbar->showMessage("Opening the vault..."); QCoreApplication::processEvents(); - m_vault = - std::make_unique(path.toStdString(), password.toStdString()); - reload_fs_tree(); - - ui->statusbar->clearMessage(); + try { + m_vault = + std::make_unique(path.toStdString(), password.toStdString()); + reload_fs_tree(); + ui->statusbar->clearMessage(); + } catch (const Botan::Invalid_Authentication_Tag &e) { + QMessageBox::critical(this, "Error", "Invalid password."); + ui->statusbar->clearMessage(); + return; + } }); connect( @@ -287,4 +301,4 @@ void MainWindow::dropEvent(QDropEvent *event) { reload_fs_tree(); event->acceptProposedAction(); -} \ No newline at end of file +} diff --git a/src/vault.cc b/src/vault.cc index 4469e2e..2883d57 100644 --- a/src/vault.cc +++ b/src/vault.cc @@ -21,6 +21,15 @@ Vault::Vault(std::string path, const std::string &password) ASSERT(m_file.read(to_char_ptr(salt.data()), 16)); m_key = Crypto::derive_key_argon2id(password, salt); + + std::array check_nonce{}; + ASSERT(m_file.read(to_char_ptr(check_nonce.data()), 24)); + + Botan::secure_vector check_ciphertext; + check_ciphertext.resize(22); + ASSERT(m_file.read(to_char_ptr(check_ciphertext.data()), 22)); + + Crypto::decrypt_xchacha20_poly1305(check_ciphertext, m_key, check_nonce); } std::vector Vault::read_file_headers() { @@ -193,4 +202,4 @@ std::optional Vault::read_file_header() { return std::nullopt; } return header; -} \ No newline at end of file +} diff --git a/src/vault.h b/src/vault.h index 89fee85..30a4d5b 100644 --- a/src/vault.h +++ b/src/vault.h @@ -7,7 +7,7 @@ #include constexpr i16 VERSION = 1; -constexpr u64 AFTER_HEADER_OFFSET = 22; +constexpr u64 AFTER_HEADER_OFFSET = 68; // !!! REMEMBER TO UPDATE entry_total_size IN Vault::delete_file struct FileHeader {