def has_pubkey_for(address, decodedAddress): # Can return True or False # If we need the public key for our own address or a chan, # we can compute it from the private key if shared.config.has_section(address): return True # This is not an address where we know the private key. # See if we already have the public key in our database: _, toAddressVersion, toStreamNumber, toRipe = decodedAddress queryReturn = sqlQuery( "SELECT hash FROM pubkeys WHERE hash=? AND addressversion=?", toRipe, toAddressVersion) if queryReturn != []: return True if toAddressVersion >= 4: # If we are trying to send to address version >= 4 then the needed pubkey might be encrypted in the inventory. # If we have it we'll need to decrypt it and put it in the pubkeys table. _, toTag = compute_priv_encryption_key_and_tag(toAddressVersion, toStreamNumber, toRipe) queryreturn = sqlQuery( '''SELECT payload FROM inventory WHERE objecttype='pubkey' and tag=? ''', toTag) if queryreturn != []: # if there was a pubkey in our inventory with the correct tag, we need to try to decrypt it. for row in queryreturn: data, = row if shared.decryptAndCheckPubkeyPayload( data, address) == 'successful': return True with shared.inventoryLock: for hash, storedValue in shared.inventory.items(): objectType, streamNumber, payload, receivedTime, tag = storedValue if objectType == 'pubkey' and tag == toTag: result = shared.decryptAndCheckPubkeyPayload( payload, address ) #if valid, this function also puts it in the pubkeys table. if result == 'successful': return True # We don't have the public key in our database. return False
def has_pubkey_for(address, decodedAddress): # Can return True or False # If we need the public key for our own address or a chan, # we can compute it from the private key if shared.config.has_section( address ): return True # This is not an address where we know the private key. # See if we already have the public key in our database: _, toAddressVersion, toStreamNumber, toRipe = decodedAddress queryReturn = sqlQuery( "SELECT hash FROM pubkeys WHERE hash=? AND addressversion=?", toRipe, toAddressVersion) if queryReturn != []: return True if toAddressVersion >= 4: # If we are trying to send to address version >= 4 then the needed pubkey might be encrypted in the inventory. # If we have it we'll need to decrypt it and put it in the pubkeys table. _, toTag = compute_priv_encryption_key_and_tag(toAddressVersion, toStreamNumber, toRipe) queryreturn = sqlQuery( '''SELECT payload FROM inventory WHERE objecttype='pubkey' and tag=? ''', toTag) if queryreturn != []: # if there was a pubkey in our inventory with the correct tag, we need to try to decrypt it. for row in queryreturn: data, = row if shared.decryptAndCheckPubkeyPayload(data, address) == 'successful': return True with shared.inventoryLock: for hash, storedValue in shared.inventory.items(): objectType, streamNumber, payload, receivedTime, tag = storedValue if objectType == 'pubkey' and tag == toTag: result = shared.decryptAndCheckPubkeyPayload(payload, address) #if valid, this function also puts it in the pubkeys table. if result == 'successful': return True # We don't have the public key in our database. return False
def processpubkey(self, data): pubkeyProcessingStartTime = time.time() shared.numberOfPubkeysProcessed += 1 shared.UISignalQueue.put(('updateNumberOfPubkeysProcessed', 'no data')) embeddedTime, = unpack('>Q', data[8:16]) readPosition = 20 # bypass the nonce, time, and object type addressVersion, varintLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varintLength streamNumber, varintLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varintLength if addressVersion == 0: logger.debug( '(Within processpubkey) addressVersion of 0 doesn\'t make sense.' ) return if addressVersion > 4 or addressVersion == 1: logger.info( 'This version of Bitmessage cannot handle version %s addresses.' % addressVersion) return if addressVersion == 2: if len( data ) < 146: # sanity check. This is the minimum possible length. logger.debug( '(within processpubkey) payloadLength less than 146. Sanity check failed.' ) return bitfieldBehaviors = data[readPosition:readPosition + 4] readPosition += 4 publicSigningKey = data[readPosition:readPosition + 64] # Is it possible for a public key to be invalid such that trying to # encrypt or sign with it will cause an error? If it is, it would # be easiest to test them here. readPosition += 64 publicEncryptionKey = data[readPosition:readPosition + 64] if len(publicEncryptionKey) < 64: logger.debug( 'publicEncryptionKey length less than 64. Sanity check failed.' ) return readPosition += 64 dataToStore = data[ 20:readPosition] # The data we'll store in the pubkeys table. sha = hashlib.new('sha512') sha.update('\x04' + publicSigningKey + '\x04' + publicEncryptionKey) ripeHasher = hashlib.new('ripemd160') ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() logger.info( 'within recpubkey, addressVersion: %s, streamNumber: %s \n\ ripe %s\n\ publicSigningKey in hex: %s\n\ publicEncryptionKey in hex: %s' % (addressVersion, streamNumber, ripe.encode('hex'), publicSigningKey.encode('hex'), publicEncryptionKey.encode('hex'))) queryreturn = sqlQuery( '''SELECT usedpersonally FROM pubkeys WHERE hash=? AND addressversion=? AND usedpersonally='yes' ''', ripe, addressVersion) if queryreturn != []: # if this pubkey is already in our database and if we have used it personally: logger.info( 'We HAVE used this pubkey personally. Updating time.') t = (ripe, addressVersion, dataToStore, int(time.time()), 'yes') else: logger.info( 'We have NOT used this pubkey personally. Inserting in database.' ) t = (ripe, addressVersion, dataToStore, int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(ripe=ripe) if addressVersion == 3: if len(data) < 170: # sanity check. logger.warning( '(within processpubkey) payloadLength less than 170. Sanity check failed.' ) return bitfieldBehaviors = data[readPosition:readPosition + 4] readPosition += 4 publicSigningKey = '\x04' + data[readPosition:readPosition + 64] readPosition += 64 publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64] readPosition += 64 specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += specifiedNonceTrialsPerByteLength specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += specifiedPayloadLengthExtraBytesLength endOfSignedDataPosition = readPosition dataToStore = data[ 20:readPosition] # The data we'll store in the pubkeys table. signatureLength, signatureLengthLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += signatureLengthLength signature = data[readPosition:readPosition + signatureLength] if highlevelcrypto.verify(data[8:endOfSignedDataPosition], signature, publicSigningKey.encode('hex')): logger.debug('ECDSA verify passed (within processpubkey)') else: logger.warning('ECDSA verify failed (within processpubkey)') return sha = hashlib.new('sha512') sha.update(publicSigningKey + publicEncryptionKey) ripeHasher = hashlib.new('ripemd160') ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() logger.info( 'within recpubkey, addressVersion: %s, streamNumber: %s \n\ ripe %s\n\ publicSigningKey in hex: %s\n\ publicEncryptionKey in hex: %s' % (addressVersion, streamNumber, ripe.encode('hex'), publicSigningKey.encode('hex'), publicEncryptionKey.encode('hex'))) queryreturn = sqlQuery( '''SELECT usedpersonally FROM pubkeys WHERE hash=? AND addressversion=? AND usedpersonally='yes' ''', ripe, addressVersion) if queryreturn != []: # if this pubkey is already in our database and if we have used it personally: logger.info( 'We HAVE used this pubkey personally. Updating time.') t = (ripe, addressVersion, dataToStore, int(time.time()), 'yes') else: logger.info( 'We have NOT used this pubkey personally. Inserting in database.' ) t = (ripe, addressVersion, dataToStore, int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(ripe=ripe) if addressVersion == 4: if len(data) < 350: # sanity check. logger.debug( '(within processpubkey) payloadLength less than 350. Sanity check failed.' ) return tag = data[readPosition:readPosition + 32] if tag not in shared.neededPubkeys: logger.info( 'We don\'t need this v4 pubkey. We didn\'t ask for it.') return # Let us try to decrypt the pubkey toAddress, cryptorObject = shared.neededPubkeys[tag] if shared.decryptAndCheckPubkeyPayload(data, toAddress) == 'successful': # At this point we know that we have been waiting on this pubkey. # This function will command the workerThread to start work on # the messages that require it. self.possibleNewPubkey(address=toAddress) # Display timing data timeRequiredToProcessPubkey = time.time() - pubkeyProcessingStartTime logger.debug('Time required to process this pubkey: %s' % timeRequiredToProcessPubkey)
def processpubkey(self, data): pubkeyProcessingStartTime = time.time() shared.numberOfPubkeysProcessed += 1 shared.UISignalQueue.put(( 'updateNumberOfPubkeysProcessed', 'no data')) embeddedTime, = unpack('>Q', data[8:16]) readPosition = 20 # bypass the nonce, time, and object type addressVersion, varintLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varintLength streamNumber, varintLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varintLength if addressVersion == 0: logger.debug('(Within processpubkey) addressVersion of 0 doesn\'t make sense.') return if addressVersion > 4 or addressVersion == 1: logger.info('This version of Bitmessage cannot handle version %s addresses.' % addressVersion) return if addressVersion == 2: if len(data) < 146: # sanity check. This is the minimum possible length. logger.debug('(within processpubkey) payloadLength less than 146. Sanity check failed.') return bitfieldBehaviors = data[readPosition:readPosition + 4] readPosition += 4 publicSigningKey = data[readPosition:readPosition + 64] # Is it possible for a public key to be invalid such that trying to # encrypt or sign with it will cause an error? If it is, it would # be easiest to test them here. readPosition += 64 publicEncryptionKey = data[readPosition:readPosition + 64] if len(publicEncryptionKey) < 64: logger.debug('publicEncryptionKey length less than 64. Sanity check failed.') return readPosition += 64 dataToStore = data[20:readPosition] # The data we'll store in the pubkeys table. sha = hashlib.new('sha512') sha.update( '\x04' + publicSigningKey + '\x04' + publicEncryptionKey) ripeHasher = hashlib.new('ripemd160') ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() logger.debug('within recpubkey, addressVersion: %s, streamNumber: %s \n\ ripe %s\n\ publicSigningKey in hex: %s\n\ publicEncryptionKey in hex: %s' % (addressVersion, streamNumber, ripe.encode('hex'), publicSigningKey.encode('hex'), publicEncryptionKey.encode('hex') ) ) address = encodeAddress(addressVersion, streamNumber, ripe) queryreturn = sqlQuery( '''SELECT usedpersonally FROM pubkeys WHERE address=? AND usedpersonally='yes' ''', address) if queryreturn != []: # if this pubkey is already in our database and if we have used it personally: logger.info('We HAVE used this pubkey personally. Updating time.') t = (address, addressVersion, dataToStore, int(time.time()), 'yes') else: logger.info('We have NOT used this pubkey personally. Inserting in database.') t = (address, addressVersion, dataToStore, int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(address) if addressVersion == 3: if len(data) < 170: # sanity check. logger.warning('(within processpubkey) payloadLength less than 170. Sanity check failed.') return bitfieldBehaviors = data[readPosition:readPosition + 4] readPosition += 4 publicSigningKey = '\x04' + data[readPosition:readPosition + 64] readPosition += 64 publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64] readPosition += 64 specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += specifiedNonceTrialsPerByteLength specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += specifiedPayloadLengthExtraBytesLength endOfSignedDataPosition = readPosition dataToStore = data[20:readPosition] # The data we'll store in the pubkeys table. signatureLength, signatureLengthLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += signatureLengthLength signature = data[readPosition:readPosition + signatureLength] if highlevelcrypto.verify(data[8:endOfSignedDataPosition], signature, publicSigningKey.encode('hex')): logger.debug('ECDSA verify passed (within processpubkey)') else: logger.warning('ECDSA verify failed (within processpubkey)') return sha = hashlib.new('sha512') sha.update(publicSigningKey + publicEncryptionKey) ripeHasher = hashlib.new('ripemd160') ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() logger.debug('within recpubkey, addressVersion: %s, streamNumber: %s \n\ ripe %s\n\ publicSigningKey in hex: %s\n\ publicEncryptionKey in hex: %s' % (addressVersion, streamNumber, ripe.encode('hex'), publicSigningKey.encode('hex'), publicEncryptionKey.encode('hex') ) ) address = encodeAddress(addressVersion, streamNumber, ripe) queryreturn = sqlQuery('''SELECT usedpersonally FROM pubkeys WHERE address=? AND usedpersonally='yes' ''', address) if queryreturn != []: # if this pubkey is already in our database and if we have used it personally: logger.info('We HAVE used this pubkey personally. Updating time.') t = (address, addressVersion, dataToStore, int(time.time()), 'yes') else: logger.info('We have NOT used this pubkey personally. Inserting in database.') t = (address, addressVersion, dataToStore, int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(address) if addressVersion == 4: if len(data) < 350: # sanity check. logger.debug('(within processpubkey) payloadLength less than 350. Sanity check failed.') return tag = data[readPosition:readPosition + 32] if tag not in shared.neededPubkeys: logger.info('We don\'t need this v4 pubkey. We didn\'t ask for it.') return # Let us try to decrypt the pubkey toAddress, cryptorObject = shared.neededPubkeys[tag] if shared.decryptAndCheckPubkeyPayload(data, toAddress) == 'successful': # At this point we know that we have been waiting on this pubkey. # This function will command the workerThread to start work on # the messages that require it. self.possibleNewPubkey(toAddress) # Display timing data timeRequiredToProcessPubkey = time.time( ) - pubkeyProcessingStartTime logger.debug('Time required to process this pubkey: %s' % timeRequiredToProcessPubkey)
def processpubkey(self, data): pubkeyProcessingStartTime = time.time() shared.numberOfPubkeysProcessed += 1 embeddedTime, = unpack('>Q', data[8:16]) readPosition = 20 # bypass the nonce, time, and object type addressVersion, varintLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varintLength streamNumber, varintLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += varintLength if addressVersion == 0: return if addressVersion > 4 or addressVersion == 1: return if addressVersion == 2: if len(data) < 146: # sanity check. This is the minimum possible length. return bitfieldBehaviors = data[readPosition:readPosition + 4] readPosition += 4 publicSigningKey = data[readPosition:readPosition + 64] # Is it possible for a public key to be invalid such that trying to # encrypt or sign with it will cause an error? If it is, it would # be easiest to test them here. readPosition += 64 publicEncryptionKey = data[readPosition:readPosition + 64] if len(publicEncryptionKey) < 64: return readPosition += 64 dataToStore = data[20:readPosition] # The data we'll store in the pubkeys table. sha = hashlib.new('sha512') sha.update( '\x04' + publicSigningKey + '\x04' + publicEncryptionKey) ripeHasher = hashlib.new('ripemd160') ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() address = encodeAddress(addressVersion, streamNumber, ripe) if address not in shared.hadPubkeys.keys(): # if this pubkey is already in our database and if we have used it personally: t = (address, addressVersion, dataToStore, int(time.time()), 'no') shared.hadPubkeys[address] = t shared.savePubkeyToFile() self.possibleNewPubkey(address) print "Received a pubkey for version 2 address:%s" % address if addressVersion == 3: if len(data) < 170: # sanity check. return bitfieldBehaviors = data[readPosition:readPosition + 4] readPosition += 4 publicSigningKey = '\x04' + data[readPosition:readPosition + 64] readPosition += 64 publicEncryptionKey = '\x04' + data[readPosition:readPosition + 64] readPosition += 64 specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += specifiedNonceTrialsPerByteLength specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += specifiedPayloadLengthExtraBytesLength endOfSignedDataPosition = readPosition dataToStore = data[20:readPosition] # The data we'll store in the pubkeys table. signatureLength, signatureLengthLength = decodeVarint( data[readPosition:readPosition + 10]) readPosition += signatureLengthLength signature = data[readPosition:readPosition + signatureLength] if not highlevelcrypto.verify(data[8:endOfSignedDataPosition], signature, publicSigningKey.encode('hex')): return sha = hashlib.new('sha512') sha.update(publicSigningKey + publicEncryptionKey) ripeHasher = hashlib.new('ripemd160') ripeHasher.update(sha.digest()) ripe = ripeHasher.digest() address = encodeAddress(addressVersion, streamNumber, ripe) if address not in shared.hadPubkeys.keys(): t = (address, addressVersion, dataToStore, int(time.time()), 'no') shared.hadPubkeys[address] = t shared.savePubkeyToFile() self.possibleNewPubkey(address) print "Received a pubkey for version 3 address:%s" % address if addressVersion == 4: if len(data) < 350: # sanity check. return tag = data[readPosition:readPosition + 32] if tag not in shared.neededPubkeys: return # Let us try to decrypt the pubkey toAddress, cryptorObject = shared.neededPubkeys[tag] if shared.decryptAndCheckPubkeyPayload(data, toAddress) == 'successful': # At this point we know that we have been waiting on this pubkey. # This function will command the workerThread to start work on # the messages that require it. self.possibleNewPubkey(toAddress) # Display timing data timeRequiredToProcessPubkey = time.time( ) - pubkeyProcessingStartTime