From 80932bbab0352a4cbe760b308b6722676595e120 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Fri, 6 Dec 2013 01:52:19 -0500 Subject: [PATCH] fix pubkey signature bug leftover from objectProcessorThread-related-changes --- src/class_objectProcessor.py | 12 ++++++++++-- src/class_singleWorker.py | 19 ++++++++----------- src/shared.py | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index e32d5a6d..0a2f2594 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -149,7 +149,7 @@ class objectProcessor(threading.Thread): print 'Ignoring getpubkey request because it is for one of my chan addresses. The other party should already have the pubkey.' return try: - lastPubkeySendTime = int(config.get( + lastPubkeySendTime = int(shared.config.get( myAddress, 'lastpubkeysendtime')) except: lastPubkeySendTime = 0 @@ -298,6 +298,15 @@ class objectProcessor(threading.Thread): self.possibleNewPubkey(ripe = ripe) if addressVersion == 4: + """ + There exist a function: shared.decryptAndCheckPubkeyPayload which does something almost + the same as this section of code. There are differences, however; one being that + decryptAndCheckPubkeyPayload requires that a cryptor object be created each time it is + run which is an expensive operation. This, on the other hand, keeps them saved in + the shared.neededPubkeys dictionary so that if an attacker sends us many + incorrectly-tagged pubkeys, which would force us to try to decrypt them, this code + would run and handle that event quite quickly. + """ if len(data) < 350: # sanity check. print '(within processpubkey) payloadLength less than 350. Sanity check failed.' return @@ -321,7 +330,6 @@ class objectProcessor(threading.Thread): print 'Pubkey decryption was unsuccessful.' return - readPosition = 0 bitfieldBehaviors = decryptedData[readPosition:readPosition + 4] readPosition += 4 diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 62cf8308..e76b75a0 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -260,7 +260,6 @@ class singleWorker(threading.Thread): payload = pack('>Q', (embeddedTime)) payload += encodeVarint(addressVersionNumber) # Address version number payload += encodeVarint(streamNumber) - dataToStoreInOurPubkeysTable = payload # used if this is a chan. We'll add more data further down. dataToEncrypt = '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki). @@ -291,8 +290,6 @@ class singleWorker(threading.Thread): dataToEncrypt += encodeVarint(shared.config.getint( myAddress, 'payloadlengthextrabytes')) - dataToStoreInOurPubkeysTable += dataToEncrypt # dataToStoreInOurPubkeysTable is used if this is a chan - signature = highlevelcrypto.sign(payload + dataToEncrypt, privSigningKeyHex) dataToEncrypt += encodeVarint(len(signature)) dataToEncrypt += signature @@ -337,10 +334,8 @@ class singleWorker(threading.Thread): myAddress, 'lastpubkeysendtime', str(int(time.time()))) with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - except: - # The user deleted the address out of the keys.dat file before this - # finished. - pass + except Exception as err: + logger.error('Error: Couldn\'t add the lastpubkeysendtime to the keys.dat file. Error message: %s' % err) def sendBroadcast(self): queryreturn = sqlQuery( @@ -686,7 +681,7 @@ class singleWorker(threading.Thread): ackdata, tr.translateText("MainWindow", "Doing work necessary to send message.")))) embeddedTime = pack('>Q', (int(time.time()) + random.randrange( - -300, 300))) # the current time plus or minus five minutes. We will use this time both for our message and for the ackdata packed within our message. + -300, 300))) # the current time plus or minus five minutes. if fromAddressVersionNumber == 2: payload = '\x01' # Message version. payload += encodeVarint(fromAddressVersionNumber) @@ -726,7 +721,7 @@ class singleWorker(threading.Thread): payload += encodeVarint(len(messageToTransmit)) payload += messageToTransmit fullAckPayload = self.generateFullAckMessage( - ackdata, toStreamNumber, embeddedTime) # The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out. + ackdata, toStreamNumber) # The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out. payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload signature = highlevelcrypto.sign(payload, privSigningKeyHex) @@ -795,7 +790,7 @@ class singleWorker(threading.Thread): fullAckPayload = '' else: fullAckPayload = self.generateFullAckMessage( - ackdata, toStreamNumber, embeddedTime) # The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out. + ackdata, toStreamNumber) # The fullAckPayload is a normal msg protocol message with the proof of work already completed that the receiver of this message can easily send out. payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload signature = highlevelcrypto.sign(payload, privSigningKeyHex) @@ -934,7 +929,9 @@ class singleWorker(threading.Thread): shared.UISignalQueue.put(('updateSentItemStatusByHash', (ripe, tr.translateText("MainWindow",'Sending public key request. Waiting for reply. Requested at %1').arg(unicode( strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) - def generateFullAckMessage(self, ackdata, toStreamNumber, embeddedTime): + def generateFullAckMessage(self, ackdata, toStreamNumber): + embeddedTime = pack('>Q', (int(time.time()) + random.randrange( + -300, 300))) # the current time plus or minus five minutes. payload = embeddedTime + encodeVarint(toStreamNumber) + ackdata target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) diff --git a/src/shared.py b/src/shared.py index 0f1f3690..b78bbd83 100644 --- a/src/shared.py +++ b/src/shared.py @@ -437,7 +437,7 @@ def decryptAndCheckPubkeyPayload(payload, address): print 'Pubkey decryption was UNsuccessful due to stream number mismatch. This shouldn\'t have happened.' return 'failed' readPosition += varintLength - signedData = payload[:readPosition] # Some of the signed data is not encrypted so let's keep it for now. + signedData = payload[8:readPosition] # Some of the signed data is not encrypted so let's keep it for now. toTag = payload[readPosition:readPosition+32] readPosition += 32 #for the tag encryptedData = payload[readPosition:]