#include "PasswordManager.h" //#include //#include //#include //#include //#include //#include //#include //#include //#include //#include #include #include #include #include #include #include Botan::secure_vector PasswordManager::KeyStrengthener::derive(const std::string &passphrase) { Botan::secure_vector master_key(m_keySize); m_hasher->derive_key(master_key.data(), master_key.size(), passphrase.c_str(), passphrase.length(), m_salt.data(), m_salt.size()); return master_key; } void PasswordManager::KeyStrengthener::saveParams(std::shared_ptr db, const std::string &table_name) { auto sc = dynamic_cast(m_hasher.get()); size_t i1 = sc->N(); size_t i2 = sc->r(); size_t i3 = sc->p(); // SAVE parameters in database auto stmt = db->new_statement("INSERT INTO " + table_name + "(id, algo, i1, i2, i3, ks, salt) VALUES(?1, ?2, ?3, ?4, ?5)"); stmt->bind(1, 1); stmt->bind(2, "Scrypt"); stmt->bind(3, i1); stmt->bind(4, i2); stmt->bind(5, i3); stmt->bind(6, m_keySize); stmt->bind(7, Botan::base64_encode(m_salt)); stmt->spin(); } // ------------------------- void PasswordManager::openDatabase(std::shared_ptr db, std::string passphrase) { // std::string psk_db_file_name; // auto db = std::make_shared(psk_db_file_name); KeyStrengthener ks; // if (database exists) if (isPskStoreInitialized(db)) { ks = getKeyStrengthener(db); } else { initializeNewPskStore(db); ks = createKeyStrengthener(); ks.saveParams(db, m_secretAlgoTableName); } Botan::secure_vector master_key = ks.derive(passphrase); m_pskDatabase = std::make_unique(master_key, db, m_passwordTableName); } void PasswordManager::closeDatabase() { m_pskDatabase.reset(); } void PasswordManager::set(const std::string &id, const std::string &passwd) { if (m_pskDatabase) { } else { throw PasswordManagerLockedException(); } } std::string PasswordManager::get(const std::string &id, const std::string &passwd) { if (m_pskDatabase) { } else { throw PasswordManagerLockedException(); } } void PasswordManager::remove(const std::string &id) { if (m_pskDatabase) { } else { throw PasswordManagerLockedException(); } } void PasswordManager::initializeNewPskStore(std::shared_ptr db) { // Create tables // - psk_masterkey_algo // - psk_passwd std::string create_statement = "CREATE TABLE IF NOT EXISTS " + m_secretAlgoTableName + "( \n" " id INTEGER PRIMARY KEY \n" " algo TEXT \n" " i1 INTEGER \n" " i2 INTEGER \n" " i3 INTEGER \n" " ks INTEGER \n" " salt TEXT \n" ");"; db->create_table(create_statement); } bool PasswordManager::isPskStoreInitialized(std::shared_ptr db) { // Is the table with the secret data present and filled? auto stmt = db->new_statement("SELECT name FROM sqlite_master WHERE type='table' AND name=?1"); stmt->bind(1, m_secretAlgoTableName); bool ok = stmt->step(); if (ok) { auto stmt = db->new_statement("SELECT algo FROM " + m_secretAlgoTableName + " WHERE id=1"); return stmt->step(); } return false; } PasswordManager::KeyStrengthener PasswordManager::getKeyStrengthener(std::shared_ptr db) { auto stmt = db->new_statement("SELECT algo, i1, i2, i3, ks, salt FROM " + m_secretAlgoTableName + " WHERE id=1"); if (stmt->step()) { std::string algo = stmt->get_str(0); size_t i1 = boost::lexical_cast(stmt->get_str(1)); size_t i2 = boost::lexical_cast(stmt->get_str(2)); size_t i3 = boost::lexical_cast(stmt->get_str(3)); size_t ks = boost::lexical_cast(stmt->get_str(4)); auto pwh_fam = Botan::PasswordHashFamily::create(algo); return KeyStrengthener( pwh_fam->from_params(i1, i2, i3), Botan::base64_decode(stmt->get_str(5)), ks ); } else { } } PasswordManager::KeyStrengthener PasswordManager::createKeyStrengthener() { // std::unique_ptr pwh; size_t key_size = 64; Botan::secure_vector salt(key_size); Botan::AutoSeeded_RNG rng; rng.randomize(salt.data(), salt.size()); const std::string algo = "Scrypt"; auto pwh_fam = Botan::PasswordHashFamily::create(algo); return KeyStrengthener( pwh_fam->tune(key_size, std::chrono::seconds(2), 130), salt, key_size ); }