The password manager uses strong encryption using a key derived from the passphrase using scrypt key strengthening algorithm. This ensures encryption is performed using a strong key and that brute forcing the passphrase is time consuming. If the user loses his passphrase no recovery is possible.
114 lines
2.7 KiB
C++
114 lines
2.7 KiB
C++
#ifndef PASSWORDMANAGER_H
|
|
#define PASSWORDMANAGER_H
|
|
|
|
#include "Expected.h"
|
|
#include <QSqlDatabase>
|
|
#include <botan/secmem.h>
|
|
#include <string>
|
|
#include <memory>
|
|
|
|
#include <botan/pwdhash.h>
|
|
|
|
|
|
//#include <botan/botan.h>
|
|
//#include <botan/symkey.h>
|
|
|
|
#include <map>
|
|
|
|
namespace Botan {
|
|
|
|
class Encrypted_PSK_Database;
|
|
//class Sqlite3_Database;
|
|
class PasswordHash;
|
|
|
|
}
|
|
|
|
class PasswordManagerException: public std::exception {
|
|
public:
|
|
using std::exception::exception; //(char const* const _Message);
|
|
};
|
|
|
|
class PasswordManagerLockedException: public PasswordManagerException {
|
|
public:
|
|
using PasswordManagerException::PasswordManagerException;
|
|
|
|
};
|
|
|
|
class PasswordManager {
|
|
public:
|
|
enum Result {
|
|
Ok,
|
|
Locked,
|
|
Error
|
|
};
|
|
|
|
PasswordManager();
|
|
~PasswordManager();
|
|
|
|
/** Check if it has been initialized before.
|
|
*
|
|
* If returns false then use createDatabase to set it up
|
|
* else use openDatabase to get access.
|
|
*/
|
|
bool initialized(QSqlDatabase &db);
|
|
bool createDatabase(QSqlDatabase &db, QString passphrase);
|
|
bool openDatabase(QSqlDatabase &db, QString passphrase);
|
|
void closeDatabase();
|
|
bool locked() const;
|
|
|
|
void set(const std::string &id, const std::string &passwd);
|
|
bool get(const std::string &id, std::string &password);
|
|
void remove(const std::string &id);
|
|
private:
|
|
QString m_passwordTableName = "psk_passwd";
|
|
QString m_secretAlgoTableName = "psk_masterkey_algo";
|
|
QString m_secretHashTableName = "psk_masterkey_hash";
|
|
std::unique_ptr<Botan::Encrypted_PSK_Database> m_pskDatabase;
|
|
|
|
bool isPskStoreInitialized(QSqlDatabase& db);
|
|
void initializeNewPskStore(QSqlDatabase &db);
|
|
|
|
class KeyStrengthener {
|
|
public:
|
|
KeyStrengthener() = default;
|
|
KeyStrengthener(std::unique_ptr<Botan::PasswordHash> hasher, Botan::secure_vector<uint8_t> salt, size_t keysize)
|
|
: m_hasher (std::move(hasher))
|
|
, m_salt (std::move(salt))
|
|
, m_keySize(keysize)
|
|
{}
|
|
|
|
KeyStrengthener(const KeyStrengthener&) = delete;
|
|
KeyStrengthener& operator=(const KeyStrengthener &) = delete;
|
|
|
|
KeyStrengthener(KeyStrengthener &&rhs)
|
|
: m_hasher (std::move(rhs.m_hasher))
|
|
, m_salt (std::move(rhs.m_salt))
|
|
, m_keySize(rhs.m_keySize)
|
|
{}
|
|
|
|
KeyStrengthener& operator=(KeyStrengthener &&rhs)
|
|
{
|
|
if (&rhs != this) {
|
|
m_hasher = std::move(rhs.m_hasher);
|
|
m_salt = std::move(rhs.m_salt);
|
|
m_keySize = rhs.m_keySize;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
Botan::secure_vector<uint8_t> derive(const std::string &passphrase);
|
|
void saveParams(QSqlDatabase &db, const QString &table_name);
|
|
private:
|
|
std::unique_ptr<Botan::PasswordHash> m_hasher;
|
|
Botan::secure_vector<uint8_t> m_salt;
|
|
size_t m_keySize;
|
|
};
|
|
|
|
/// Get PasswordHash from parameters in database
|
|
KeyStrengthener getKeyStrengthener(QSqlDatabase &db);
|
|
KeyStrengthener createKeyStrengthener();
|
|
|
|
};
|
|
|
|
|
|
#endif // PASSWORDMANAGER_H
|