Skip to content

Commit

Permalink
only unlocks needed address entries when signing
Browse files Browse the repository at this point in the history
slight change on recovery tool
  • Loading branch information
goatpig committed Mar 10, 2014
1 parent 75f44cf commit 724d226
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 22 deletions.
15 changes: 13 additions & 2 deletions armoryengine/PyBtcWallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ def __init__(self):

#for progress dialog
self.mainWnd = None
self.parent = None

#############################################################################
def getWalletVersion(self):
Expand Down Expand Up @@ -2553,8 +2554,8 @@ def signTxDistProposal(self, txdp, hashcode=1):
return

# If the wallet is locked, we better bail now
if self.isLocked:
raise WalletLockError("Cannot sign Tx when wallet is locked!")
if self.isLocked is True and self.kdfKey is None:
raise WalletLockError('Cannot sign tx without unlocking wallet')

numInputs = len(txdp.pytxObj.inputs)
wltAddr = []
Expand All @@ -2574,6 +2575,14 @@ def signTxDistProposal(self, txdp, hashcode=1):
wltAddr.append( (self.addrMap[addr], index, addrIdx) )
break

for entry in wltAddr:
addr = entry[0]
if not isinstance(addr.binPrivKey32_Plain, SecureBinaryData) or addr.binPrivKey32_Plain.getSize() != 32:
#if the private key was not craeted, just unlock the whole wallet
if addr.createPrivKeyNextUnlock:
self.unlock(secureKdfOutput=self.kdfKey)
else:
addr.unlock(self.kdfKey)

# WltAddr now contains a list of every input we can sign for, and the
# PyBtcAddress object that can be used to sign it. Let's do it.
Expand All @@ -2590,6 +2599,7 @@ def signTxDistProposal(self, txdp, hashcode=1):
if self.kdfKey:
addrObj.unlock(self.kdfKey)
else:
self.lock()
raise WalletLockError('Cannot sign tx without unlocking wallet')

if not addrObj.hasPubKey():
Expand Down Expand Up @@ -2635,6 +2645,7 @@ def signTxDistProposal(self, txdp, hashcode=1):
else:
LOGERROR('Unknown txOut script type')

self.lock()

prevHighestIndex = self.highestUsedChainIndex
if prevHighestIndex<maxChainIndex:
Expand Down
6 changes: 2 additions & 4 deletions armoryengine/PyBtcWalletRecovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ def ProcessWallet(self, WalletPath=None, Wallet=None, Passphrase=None, Mode='Bar
sleep(0.1)

if ProgDlg.GotPassphrase == 1:
Passphrase = ProgDlg.Passphrase
ProgDlg.Passphrase = None
SecurePassphrase = ProgDlg.Passphrase.copy()
ProgDlg.Passphrase.destroy()
else:
if rmode==5:
self.WO = 1
Expand All @@ -379,8 +379,6 @@ def ProcessWallet(self, WalletPath=None, Wallet=None, Passphrase=None, Mode='Bar
#if the wallet uses encryption, unlock ROOT and verify it
if toRecover.isLocked and self.WO==0:
self.useEnc=1
SecurePassphrase = SecureBinaryData(Passphrase)
Passphrase = None
if not toRecover.kdf:
SecurePassphrase.destroy()
return self.BuildLogFile(-10, ProgDlg, returnError)
Expand Down
18 changes: 9 additions & 9 deletions qtdialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,19 +289,19 @@ def changeScramble(self):
def acceptPassphrase(self):

self.securePassphrase = SecureBinaryData(str(self.edtPasswd.text()))
self.edtPasswd.setText('')

if self.returnResult:
self.accept()
return

try:
self.wlt.unlock(securePassphrase=self.securePassphrase)

if self.returnPassphrase == False:
self.edtPasswd.setText('')
self.wlt.unlock(securePassphrase=self.securePassphrase)
self.securePassphrase.destroy()
else:
self.wlt.lock() #if we are trying to recover the plain passphrase, make sure the wallet is locked
self.wlt.verifyPassphrase(self.securePassphrase)

self.securePassphrase.destroy()
self.accept()
except PassphraseError:
QMessageBox.critical(self, 'Invalid Passphrase', \
Expand Down Expand Up @@ -12230,18 +12230,18 @@ def AskUnlock(self, wll):
def PromptPassphrase(self):
dlg = DlgUnlockWallet(self.wll, self, self.parent, "Enter Passphrase", returnPassphrase=True)

self.Passphrase = None
self.GotPassphrase = 0
if dlg.exec_():
#grab plain passphrase
self.Passphrase = ''
if dlg.Accepted == 1:
self.Passphrase = str(dlg.edtPasswd.text())
dlg.edtPasswd.setText('')
self.Passphrase = dlg.securePassphrase.copy()
dlg.securePassphrase.destroy()
self.GotPassphrase = 1
else: self.GotPassphrase = -1
return
else:
self.GotPassphrase = -1
return

def Kill(self):
if self.main: self.emit(SIGNAL('Exit'))
Expand Down
36 changes: 29 additions & 7 deletions ui/TxFrames.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,13 +605,25 @@ def createTxAndBroadcast(self):
else:
try:
if self.wlt.isLocked:
unlockdlg = DlgUnlockWallet(self.wlt, self, self.main, 'Send Transaction')
if not unlockdlg.exec_():
Passphrase = None

unlockdlg = DlgUnlockWallet(self.wlt, self, self.main, 'Send Transaction', returnPassphrase=True)
if unlockdlg.exec_():
if unlockdlg.Accepted == 1:
Passphrase = unlockdlg.securePassphrase.copy()
unlockdlg.securePassphrase.destroy()

if Passphrase is None or self.wlt.kdf is None:
QMessageBox.critical(self.parent(), 'Wallet is Locked', \
'Cannot sign transaction while your wallet is locked. ', \
QMessageBox.Ok)
return

else:
self.wlt.kdfKey = self.wlt.kdf.DeriveKey(Passphrase)
Passphrase.destroy()

self.wlt.mainWnd = self.main
self.wlt.parent = self

commentStr = ''
if len(self.comments) == 1:
Expand Down Expand Up @@ -1527,12 +1539,22 @@ def signTx(self):


if self.wlt.useEncryption and self.wlt.isLocked:
dlg = DlgUnlockWallet(self.wlt, self.parent(), self.main, 'Sign Transaction')
if not dlg.exec_():
QMessageBox.warning(self, 'Wallet is Locked', \
'Cannot sign transaction while your wallet is locked!', \
Passphrase = None

unlockdlg = DlgUnlockWallet(self.wlt, self, self.main, 'Send Transaction', returnPassphrase=True)
if unlockdlg.exec_():
if unlockdlg.Accepted == 1:
Passphrase = unlockdlg.securePassphrase.copy()
unlockdlg.securePassphrase.destroy()

if Passphrase is None or self.wlt.kdf is None:
QMessageBox.critical(self.parent(), 'Wallet is Locked', \
'Cannot sign transaction while your wallet is locked. ', \
QMessageBox.Ok)
return
else:
self.wlt.kdfKey = self.wlt.kdf.DeriveKey(Passphrase)
Passphrase.destroy()

newTxdp = self.wlt.signTxDistProposal(self.txdpObj)
self.wlt.advanceHighestIndex()
Expand Down

0 comments on commit 724d226

Please sign in to comment.