mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-12 08:08:25 +00:00
Merge pull request #666 from nobled/secstrings
Implement an mlock()'d string class for storing passphrases
This commit is contained in:
commit
a7120a3647
@ -1453,22 +1453,17 @@ Value walletpassphrase(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
|
throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
|
||||||
|
|
||||||
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
|
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
|
||||||
string strWalletPass;
|
SecureString strWalletPass;
|
||||||
strWalletPass.reserve(100);
|
strWalletPass.reserve(100);
|
||||||
mlock(&strWalletPass[0], strWalletPass.capacity());
|
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
|
||||||
strWalletPass = params[0].get_str();
|
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
||||||
|
strWalletPass = params[0].get_str().c_str();
|
||||||
|
|
||||||
if (strWalletPass.length() > 0)
|
if (strWalletPass.length() > 0)
|
||||||
{
|
{
|
||||||
if (!pwalletMain->Unlock(strWalletPass))
|
if (!pwalletMain->Unlock(strWalletPass))
|
||||||
{
|
|
||||||
fill(strWalletPass.begin(), strWalletPass.end(), '\0');
|
|
||||||
munlock(&strWalletPass[0], strWalletPass.capacity());
|
|
||||||
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
|
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
|
||||||
}
|
}
|
||||||
fill(strWalletPass.begin(), strWalletPass.end(), '\0');
|
|
||||||
munlock(&strWalletPass[0], strWalletPass.capacity());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"walletpassphrase <passphrase> <timeout>\n"
|
"walletpassphrase <passphrase> <timeout>\n"
|
||||||
@ -1493,15 +1488,15 @@ Value walletpassphrasechange(const Array& params, bool fHelp)
|
|||||||
if (!pwalletMain->IsCrypted())
|
if (!pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
|
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
|
||||||
|
|
||||||
string strOldWalletPass;
|
// TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
|
||||||
|
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
||||||
|
SecureString strOldWalletPass;
|
||||||
strOldWalletPass.reserve(100);
|
strOldWalletPass.reserve(100);
|
||||||
mlock(&strOldWalletPass[0], strOldWalletPass.capacity());
|
strOldWalletPass = params[0].get_str().c_str();
|
||||||
strOldWalletPass = params[0].get_str();
|
|
||||||
|
|
||||||
string strNewWalletPass;
|
SecureString strNewWalletPass;
|
||||||
strNewWalletPass.reserve(100);
|
strNewWalletPass.reserve(100);
|
||||||
mlock(&strNewWalletPass[0], strNewWalletPass.capacity());
|
strNewWalletPass = params[1].get_str().c_str();
|
||||||
strNewWalletPass = params[1].get_str();
|
|
||||||
|
|
||||||
if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
|
if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
@ -1509,17 +1504,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp)
|
|||||||
"Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
|
"Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
|
||||||
|
|
||||||
if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
|
if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
|
||||||
{
|
|
||||||
fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
|
|
||||||
fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
|
|
||||||
munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
|
|
||||||
munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
|
|
||||||
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
|
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
|
||||||
}
|
|
||||||
fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
|
|
||||||
fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
|
|
||||||
munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
|
|
||||||
munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
|
|
||||||
|
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
@ -1564,10 +1549,11 @@ Value encryptwallet(const Array& params, bool fHelp)
|
|||||||
throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
|
throw runtime_error("Not Yet Implemented: use GUI to encrypt wallet, not RPC command");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string strWalletPass;
|
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
|
||||||
|
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
||||||
|
SecureString strWalletPass;
|
||||||
strWalletPass.reserve(100);
|
strWalletPass.reserve(100);
|
||||||
mlock(&strWalletPass[0], strWalletPass.capacity());
|
strWalletPass = params[0].get_str().c_str();
|
||||||
strWalletPass = params[0].get_str();
|
|
||||||
|
|
||||||
if (strWalletPass.length() < 1)
|
if (strWalletPass.length() < 1)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
@ -1575,13 +1561,7 @@ Value encryptwallet(const Array& params, bool fHelp)
|
|||||||
"Encrypts the wallet with <passphrase>.");
|
"Encrypts the wallet with <passphrase>.");
|
||||||
|
|
||||||
if (!pwalletMain->EncryptWallet(strWalletPass))
|
if (!pwalletMain->EncryptWallet(strWalletPass))
|
||||||
{
|
|
||||||
fill(strWalletPass.begin(), strWalletPass.end(), '\0');
|
|
||||||
munlock(&strWalletPass[0], strWalletPass.capacity());
|
|
||||||
throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
|
throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
|
||||||
}
|
|
||||||
fill(strWalletPass.begin(), strWalletPass.end(), '\0');
|
|
||||||
munlock(&strWalletPass[0], strWalletPass.capacity());
|
|
||||||
|
|
||||||
// BDB seems to have a bad habit of writing old data into
|
// BDB seems to have a bad habit of writing old data into
|
||||||
// slack space in .dat files; that is bad if the old data is
|
// slack space in .dat files; that is bad if the old data is
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
bool CCrypter::SetKeyFromPassphrase(const std::string& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
|
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
|
||||||
{
|
{
|
||||||
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
|
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
|
||||||
return false;
|
return false;
|
||||||
|
@ -65,7 +65,7 @@ private:
|
|||||||
bool fKeySet;
|
bool fKeySet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool SetKeyFromPassphrase(const std::string &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
|
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
|
||||||
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
|
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
|
||||||
bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
|
bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
|
||||||
bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
|
bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
|
||||||
|
@ -71,16 +71,17 @@ void AskPassphraseDialog::setModel(WalletModel *model)
|
|||||||
|
|
||||||
void AskPassphraseDialog::accept()
|
void AskPassphraseDialog::accept()
|
||||||
{
|
{
|
||||||
std::string oldpass, newpass1, newpass2;
|
SecureString oldpass, newpass1, newpass2;
|
||||||
if(!model)
|
if(!model)
|
||||||
return;
|
return;
|
||||||
// TODO: mlock memory / munlock on return so they will not be swapped out, really need "mlockedstring" wrapper class to do this safely
|
|
||||||
oldpass.reserve(MAX_PASSPHRASE_SIZE);
|
oldpass.reserve(MAX_PASSPHRASE_SIZE);
|
||||||
newpass1.reserve(MAX_PASSPHRASE_SIZE);
|
newpass1.reserve(MAX_PASSPHRASE_SIZE);
|
||||||
newpass2.reserve(MAX_PASSPHRASE_SIZE);
|
newpass2.reserve(MAX_PASSPHRASE_SIZE);
|
||||||
oldpass.assign(ui->passEdit1->text().toStdString());
|
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
|
||||||
newpass1.assign(ui->passEdit2->text().toStdString());
|
// Alternately, find a way to make this input mlock()'d to begin with.
|
||||||
newpass2.assign(ui->passEdit3->text().toStdString());
|
oldpass.assign(ui->passEdit1->text().toStdString().c_str());
|
||||||
|
newpass1.assign(ui->passEdit2->text().toStdString().c_str());
|
||||||
|
newpass2.assign(ui->passEdit3->text().toStdString().c_str());
|
||||||
|
|
||||||
switch(mode)
|
switch(mode)
|
||||||
{
|
{
|
||||||
|
@ -200,7 +200,7 @@ WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WalletModel::setWalletEncrypted(bool encrypted, const std::string &passphrase)
|
bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase)
|
||||||
{
|
{
|
||||||
if(encrypted)
|
if(encrypted)
|
||||||
{
|
{
|
||||||
@ -214,7 +214,7 @@ bool WalletModel::setWalletEncrypted(bool encrypted, const std::string &passphra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WalletModel::setWalletLocked(bool locked, const std::string &passPhrase)
|
bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
|
||||||
{
|
{
|
||||||
if(locked)
|
if(locked)
|
||||||
{
|
{
|
||||||
@ -228,7 +228,7 @@ bool WalletModel::setWalletLocked(bool locked, const std::string &passPhrase)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WalletModel::changePassphrase(const std::string &oldPass, const std::string &newPass)
|
bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
|
||||||
{
|
{
|
||||||
bool retval;
|
bool retval;
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
CRITICAL_BLOCK(wallet->cs_wallet)
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#define WALLETMODEL_H
|
#define WALLETMODEL_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <string>
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
class AddressTableModel;
|
class AddressTableModel;
|
||||||
@ -72,10 +73,10 @@ public:
|
|||||||
SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients);
|
SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients);
|
||||||
|
|
||||||
// Wallet encryption
|
// Wallet encryption
|
||||||
bool setWalletEncrypted(bool encrypted, const std::string &passphrase);
|
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
|
||||||
// Passphrase only needed when unlocking
|
// Passphrase only needed when unlocking
|
||||||
bool setWalletLocked(bool locked, const std::string &passPhrase=std::string());
|
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
|
||||||
bool changePassphrase(const std::string &oldPass, const std::string &newPass);
|
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
|
||||||
|
|
||||||
// RAI object for unlocking wallet, returned by requestUnlock()
|
// RAI object for unlocking wallet, returned by requestUnlock()
|
||||||
class UnlockContext
|
class UnlockContext
|
||||||
|
@ -292,6 +292,10 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This is exactly like std::string, but with a custom allocator.
|
||||||
|
// (secure_allocator<> is defined in serialize.h)
|
||||||
|
typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::Unlock(const string& strWalletPassphrase)
|
bool CWallet::Unlock(const SecureString& strWalletPassphrase)
|
||||||
{
|
{
|
||||||
if (!IsLocked())
|
if (!IsLocked())
|
||||||
return false;
|
return false;
|
||||||
@ -63,7 +63,7 @@ bool CWallet::Unlock(const string& strWalletPassphrase)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase)
|
bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
|
||||||
{
|
{
|
||||||
bool fWasLocked = IsLocked();
|
bool fWasLocked = IsLocked();
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ public:
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CWallet::EncryptWallet(const string& strWalletPassphrase)
|
bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
{
|
{
|
||||||
if (IsCrypted())
|
if (IsCrypted())
|
||||||
return false;
|
return false;
|
||||||
|
@ -70,9 +70,9 @@ public:
|
|||||||
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
|
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
|
bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
|
||||||
|
|
||||||
bool Unlock(const std::string& strWalletPassphrase);
|
bool Unlock(const SecureString& strWalletPassphrase);
|
||||||
bool ChangeWalletPassphrase(const std::string& strOldWalletPassphrase, const std::string& strNewWalletPassphrase);
|
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
|
||||||
bool EncryptWallet(const std::string& strWalletPassphrase);
|
bool EncryptWallet(const SecureString& strWalletPassphrase);
|
||||||
|
|
||||||
bool AddToWallet(const CWalletTx& wtxIn);
|
bool AddToWallet(const CWalletTx& wtxIn);
|
||||||
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
|
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
|
||||||
|
Loading…
Reference in New Issue
Block a user