Replaced old PasswordManager code with code using Botan's new PSK_Database

This greatly reduces the amount of encryption related code required. Thought
we still have todo our own key strenthening but this also is easier with Botan::PasswordHash.
This commit is contained in:
eelke 2018-11-04 11:24:13 +01:00
parent 1ae9a1151a
commit 6b9b602c64
4 changed files with 294 additions and 305 deletions

View file

@ -2,65 +2,100 @@
#define PASSWORDMANAGER_H
#include "Expected.h"
#include <botan/secmem.h>
#include <string>
#include <memory>
#include <botan/botan.h>
#include <botan/symkey.h>
#include <botan/pwdhash.h>
//#include <botan/botan.h>
//#include <botan/symkey.h>
#include <map>
struct StrengthenedKey {
Botan::SymmetricKey cipher_key;
Botan::SymmetricKey mac_key;
Botan::InitializationVector iv;
namespace Botan {
StrengthenedKey() {}
StrengthenedKey(const Botan::SymmetricKey &ck, const Botan::SymmetricKey &mk,
const Botan::InitializationVector &i)
: cipher_key(ck)
, mac_key(mk)
, iv(i)
{}
class Encrypted_PSK_Database_SQL;
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
};
// static PasswordManager create(const std::string &file_name);
PasswordManager() = default;
explicit PasswordManager(int iterations = 8192);
/** Unlocks the passwords of the connections.
*
* \return Normally it return a bool specifying if the password was accepted.
* on rare occasions it could return an error.
*/
Expected<bool> unlock(const std::string &master_password);
Expected<bool> changeMasterPassword(const std::string &master_password,
const std::string &new_master_password);
/** Forget master password
*/
void lock();
bool locked() const;
Expected<void> savePassword(const std::string &key, const std::string &password);
Expected<bool> getPassword(const std::string &key, std::string &out);
void openDatabase(std::shared_ptr<Botan::Sqlite3_Database> db, std::string passphrase);
void closeDatabase();
void set(const std::string &id, const std::string &passwd);
std::string get(const std::string &id, const std::string &passwd);
void remove(const std::string &id);
private:
int m_iterations;
Botan::AutoSeeded_RNG m_rng;
Botan::OctetString m_keySalt; // salt for generating crypto key
StrengthenedKey m_masterKey; // crypto key
Botan::OctetString m_hashSalt; // salt of the hash of the passphrase
Botan::OctetString m_masterHash; // hash for checking the passphrase
std::string m_passwordTableName = "psk_passwd";
std::string m_secretAlgoTableName = "psk_masterkey_algo";
std::unique_ptr<Botan::Encrypted_PSK_Database_SQL> m_pskDatabase;
using t_KeyPasswords = std::map<std::string, std::string>;
bool isPskStoreInitialized(std::shared_ptr<Botan::Sqlite3_Database> db);
void initializeNewPskStore(std::shared_ptr<Botan::Sqlite3_Database> db);
t_KeyPasswords m_store;
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(std::shared_ptr<Botan::Sqlite3_Database> db, const std::string &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(std::shared_ptr<Botan::Sqlite3_Database> db);
KeyStrengthener createKeyStrengthener();
static Botan::OctetString hashStrengthenedKey(const StrengthenedKey &key, const Botan::OctetString &salt);
};