Esempio n. 1
0
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)
Esempio n. 5
0
    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