more v4 address work. Should be done.
This commit is contained in:
parent
79f6169803
commit
02ea2a50d3
|
@ -31,12 +31,12 @@ print 'Uncomment the next two lines to create a new random address with a slight
|
||||||
|
|
||||||
print 'Uncomment these next four lines to create new deterministic addresses.'
|
print 'Uncomment these next four lines to create new deterministic addresses.'
|
||||||
#passphrase = 'asdfasdfqwser'.encode('base64')
|
#passphrase = 'asdfasdfqwser'.encode('base64')
|
||||||
#jsonDeterministicAddresses = api.createDeterministicAddresses(passphrase, 2, 3, 1, False)
|
#jsonDeterministicAddresses = api.createDeterministicAddresses(passphrase, 2, 4, 1, False)
|
||||||
#print jsonDeterministicAddresses
|
#print jsonDeterministicAddresses
|
||||||
#print json.loads(jsonDeterministicAddresses)
|
#print json.loads(jsonDeterministicAddresses)
|
||||||
|
|
||||||
#print 'Uncomment this next line to print the first deterministic address that would be generated with the given passphrase. This will Not add it to the Bitmessage interface or the keys.dat file.'
|
#print 'Uncomment this next line to print the first deterministic address that would be generated with the given passphrase. This will Not add it to the Bitmessage interface or the keys.dat file.'
|
||||||
#print api.getDeterministicAddress('asdfasdfqwser'.encode('base64'),3,1)
|
#print api.getDeterministicAddress('asdfasdfqwser'.encode('base64'),4,1)
|
||||||
|
|
||||||
#print 'Uncomment this line to subscribe to an address. (You must use your own address, this one is invalid).'
|
#print 'Uncomment this line to subscribe to an address. (You must use your own address, this one is invalid).'
|
||||||
#print api.addSubscription('2D94G5d8yp237GGqAheoecBYpdehdT3dha','test sub'.encode('base64'))
|
#print api.addSubscription('2D94G5d8yp237GGqAheoecBYpdehdT3dha','test sub'.encode('base64'))
|
||||||
|
|
|
@ -182,7 +182,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
elif method == 'statusBar':
|
elif method == 'statusBar':
|
||||||
message, = params
|
message, = params
|
||||||
shared.UISignalQueue.put(('updateStatusBar', message))
|
shared.UISignalQueue.put(('updateStatusBar', message))
|
||||||
elif method == 'listAddresses':
|
elif method == 'listAddresses' or method == 'listAddresses2':
|
||||||
data = '{"addresses":['
|
data = '{"addresses":['
|
||||||
configSections = shared.config.sections()
|
configSections = shared.config.sections()
|
||||||
for addressInKeysFile in configSections:
|
for addressInKeysFile in configSections:
|
||||||
|
@ -196,7 +196,10 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
chan = shared.config.getboolean(addressInKeysFile, 'chan')
|
chan = shared.config.getboolean(addressInKeysFile, 'chan')
|
||||||
else:
|
else:
|
||||||
chan = False
|
chan = False
|
||||||
data += json.dumps({'label': shared.config.get(addressInKeysFile, 'label'), 'address': addressInKeysFile, 'stream':
|
label = shared.config.get(addressInKeysFile, 'label')
|
||||||
|
if method == listAddresses2:
|
||||||
|
label = label.encode('base64')
|
||||||
|
data += json.dumps({'label': label, 'address': addressInKeysFile, 'stream':
|
||||||
streamNumber, 'enabled': shared.config.getboolean(addressInKeysFile, 'enabled'), 'chan': chan}, indent=4, separators=(',', ': '))
|
streamNumber, 'enabled': shared.config.getboolean(addressInKeysFile, 'enabled'), 'chan': chan}, indent=4, separators=(',', ': '))
|
||||||
data += ']}'
|
data += ']}'
|
||||||
return data
|
return data
|
||||||
|
@ -276,7 +279,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
streamNumberForAddress = 1
|
streamNumberForAddress = 1
|
||||||
shared.addressGeneratorQueue.put((
|
shared.addressGeneratorQueue.put((
|
||||||
'createRandomAddress', 3, streamNumberForAddress, label, 1, "", eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes))
|
'createRandomAddress', 4, streamNumberForAddress, label, 1, "", eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes))
|
||||||
return shared.apiAddressGeneratorReturnQueue.get()
|
return shared.apiAddressGeneratorReturnQueue.get()
|
||||||
elif method == 'createDeterministicAddresses':
|
elif method == 'createDeterministicAddresses':
|
||||||
if len(params) == 0:
|
if len(params) == 0:
|
||||||
|
@ -341,9 +344,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
raise APIError(23, 'Bool expected in eighteenByteRipe, saw %s instead' % type(eighteenByteRipe))
|
raise APIError(23, 'Bool expected in eighteenByteRipe, saw %s instead' % type(eighteenByteRipe))
|
||||||
passphrase = self._decode(passphrase, "base64")
|
passphrase = self._decode(passphrase, "base64")
|
||||||
if addressVersionNumber == 0: # 0 means "just use the proper addressVersionNumber"
|
if addressVersionNumber == 0: # 0 means "just use the proper addressVersionNumber"
|
||||||
addressVersionNumber = 3
|
addressVersionNumber = 4
|
||||||
if addressVersionNumber != 3:
|
if addressVersionNumber != 3 and addressVersionNumber != 4:
|
||||||
raise APIError(2,'The address version number currently must be 3 (or 0 which means auto-select). ' + addressVersionNumber + ' isn\'t supported.')
|
raise APIError(2,'The address version number currently must be 3, 4, or 0 (which means auto-select). ' + addressVersionNumber + ' isn\'t supported.')
|
||||||
if streamNumber == 0: # 0 means "just use the most available stream"
|
if streamNumber == 0: # 0 means "just use the most available stream"
|
||||||
streamNumber = 1
|
streamNumber = 1
|
||||||
if streamNumber != 1:
|
if streamNumber != 1:
|
||||||
|
@ -374,8 +377,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
if len(passphrase) == 0:
|
if len(passphrase) == 0:
|
||||||
raise APIError(1, 'The specified passphrase is blank.')
|
raise APIError(1, 'The specified passphrase is blank.')
|
||||||
passphrase = self._decode(passphrase, "base64")
|
passphrase = self._decode(passphrase, "base64")
|
||||||
if addressVersionNumber != 3:
|
if addressVersionNumber != 3 and addressVersionNumber != 4:
|
||||||
raise APIError(2, 'The address version number currently must be 3. ' + addressVersionNumber + ' isn\'t supported.')
|
raise APIError(2, 'The address version number currently must be 3 or 4. ' + addressVersionNumber + ' isn\'t supported.')
|
||||||
if streamNumber != 1:
|
if streamNumber != 1:
|
||||||
raise APIError(3, ' The stream number must be 1. Others aren\'t supported.')
|
raise APIError(3, ' The stream number must be 1. Others aren\'t supported.')
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
|
@ -756,7 +759,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
print 'broadcasting inv within API command disseminatePubkey with hash:', inventoryHash.encode('hex')
|
print 'broadcasting inv within API command disseminatePubkey with hash:', inventoryHash.encode('hex')
|
||||||
shared.broadcastToSendDataQueues((
|
shared.broadcastToSendDataQueues((
|
||||||
streamNumber, 'advertiseobject', inventoryHash))
|
streamNumber, 'advertiseobject', inventoryHash))
|
||||||
elif method == 'getMessageDataByDestinationHash':
|
elif method == 'getMessageDataByDestinationHash' or method == 'getMessageDataByDestinationTag':
|
||||||
# Method will eventually be used by a particular Android app to
|
# Method will eventually be used by a particular Android app to
|
||||||
# select relevant messages. Do not yet add this to the api
|
# select relevant messages. Do not yet add this to the api
|
||||||
# doc.
|
# doc.
|
||||||
|
@ -764,24 +767,24 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
if len(params) != 1:
|
if len(params) != 1:
|
||||||
raise APIError(0, 'I need 1 parameter!')
|
raise APIError(0, 'I need 1 parameter!')
|
||||||
requestedHash, = params
|
requestedHash, = params
|
||||||
if len(requestedHash) != 40:
|
if len(requestedHash) != 32:
|
||||||
raise APIError(19, 'The length of hash should be 20 bytes (encoded in hex thus 40 characters).')
|
raise APIError(19, 'The length of hash should be 32 bytes (encoded in hex thus 64 characters).')
|
||||||
requestedHash = self._decode(requestedHash, "hex")
|
requestedHash = self._decode(requestedHash, "hex")
|
||||||
|
|
||||||
# This is not a particularly commonly used API function. Before we
|
# This is not a particularly commonly used API function. Before we
|
||||||
# use it we'll need to fill out a field in our inventory database
|
# use it we'll need to fill out a field in our inventory database
|
||||||
# which is blank by default (first20bytesofencryptedmessage).
|
# which is blank by default (first20bytesofencryptedmessage).
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
'''SELECT hash, payload FROM inventory WHERE first20bytesofencryptedmessage = '' and objecttype = 'msg' ; ''')
|
'''SELECT hash, payload FROM inventory WHERE tag = '' and objecttype = 'msg' ; ''')
|
||||||
with SqlBulkExecute() as sql:
|
with SqlBulkExecute() as sql:
|
||||||
for row in queryreturn:
|
for row in queryreturn:
|
||||||
hash, payload = row
|
hash, payload = row
|
||||||
readPosition = 16 # Nonce length + time length
|
readPosition = 16 # Nonce length + time length
|
||||||
readPosition += decodeVarint(payload[readPosition:readPosition+10])[1] # Stream Number length
|
readPosition += decodeVarint(payload[readPosition:readPosition+10])[1] # Stream Number length
|
||||||
t = (payload[readPosition:readPosition+20],hash)
|
t = (payload[readPosition:readPosition+32],hash)
|
||||||
sql.execute('''UPDATE inventory SET first20bytesofencryptedmessage=? WHERE hash=?; ''', *t)
|
sql.execute('''UPDATE inventory SET tag=? WHERE hash=?; ''', *t)
|
||||||
|
|
||||||
queryreturn = sqlQuery('''SELECT payload FROM inventory WHERE first20bytesofencryptedmessage = ?''',
|
queryreturn = sqlQuery('''SELECT payload FROM inventory WHERE tag = ?''',
|
||||||
requestedHash)
|
requestedHash)
|
||||||
data = '{"receivedMessageDatas":['
|
data = '{"receivedMessageDatas":['
|
||||||
for row in queryreturn:
|
for row in queryreturn:
|
||||||
|
@ -814,7 +817,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
networkStatus = 'connectedButHaveNotReceivedIncomingConnections'
|
networkStatus = 'connectedButHaveNotReceivedIncomingConnections'
|
||||||
else:
|
else:
|
||||||
networkStatus = 'connectedAndReceivingIncomingConnections'
|
networkStatus = 'connectedAndReceivingIncomingConnections'
|
||||||
return json.dumps({'networkConnections':len(shared.connectedHostsList),'numberOfMessagesProcessed':shared.numberOfMessagesProcessed, 'numberOfBroadcastsProcessed':shared.numberOfBroadcastsProcessed, 'numberOfPubkeysProcessed':shared.numberOfPubkeysProcessed, 'networkStatus':networkStatus}, indent=4, separators=(',', ': '))
|
return json.dumps({'networkConnections':len(shared.connectedHostsList),'numberOfMessagesProcessed':shared.numberOfMessagesProcessed, 'numberOfBroadcastsProcessed':shared.numberOfBroadcastsProcessed, 'numberOfPubkeysProcessed':shared.numberOfPubkeysProcessed, 'networkStatus':networkStatus, 'softwareName':'PyBitmessage','softwareVersion':shared.softwareVersion}, indent=4, separators=(',', ': '))
|
||||||
else:
|
else:
|
||||||
raise APIError(20, 'Invalid method: %s' % method)
|
raise APIError(20, 'Invalid method: %s' % method)
|
||||||
|
|
||||||
|
@ -862,7 +865,7 @@ class Main:
|
||||||
def start(self, daemon=False):
|
def start(self, daemon=False):
|
||||||
shared.daemon = daemon
|
shared.daemon = daemon
|
||||||
# is the application already running? If yes then exit.
|
# is the application already running? If yes then exit.
|
||||||
#thisapp = singleton.singleinstance() #todo: renable after testing.
|
thisapp = singleton.singleinstance()
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
||||||
# signal.signal(signal.SIGINT, signal.SIG_DFL)
|
# signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||||
|
|
|
@ -1133,8 +1133,15 @@ class MyForm(QtGui.QMainWindow):
|
||||||
else:
|
else:
|
||||||
streamNumberForAddress = int(
|
streamNumberForAddress = int(
|
||||||
self.regenerateAddressesDialogInstance.ui.lineEditStreamNumber.text())
|
self.regenerateAddressesDialogInstance.ui.lineEditStreamNumber.text())
|
||||||
addressVersionNumber = int(
|
try:
|
||||||
self.regenerateAddressesDialogInstance.ui.lineEditAddressVersionNumber.text())
|
addressVersionNumber = int(
|
||||||
|
self.regenerateAddressesDialogInstance.ui.lineEditAddressVersionNumber.text())
|
||||||
|
except:
|
||||||
|
QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate(
|
||||||
|
"MainWindow", "Your address version number must be a number: either 3 or 4."))
|
||||||
|
if addressVersionNumber < 3 or addressVersionNumber > 4:
|
||||||
|
QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate(
|
||||||
|
"MainWindow", "Your address version number must be either 3 or 4."))
|
||||||
# self.addressGenerator = addressGenerator()
|
# self.addressGenerator = addressGenerator()
|
||||||
# self.addressGenerator.setup(addressVersionNumber,streamNumberForAddress,"unused address",self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(),self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(),self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked())
|
# self.addressGenerator.setup(addressVersionNumber,streamNumberForAddress,"unused address",self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(),self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(),self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked())
|
||||||
# QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
# QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
||||||
|
@ -1153,7 +1160,7 @@ class MyForm(QtGui.QMainWindow):
|
||||||
"MainWindow", "You didn't enter a chan name."))
|
"MainWindow", "You didn't enter a chan name."))
|
||||||
return
|
return
|
||||||
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
shared.apiAddressGeneratorReturnQueue.queue.clear()
|
||||||
shared.addressGeneratorQueue.put(('createChan', 3, 1, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()))
|
shared.addressGeneratorQueue.put(('createChan', 4, 1, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()))
|
||||||
addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get()
|
addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get()
|
||||||
print 'addressGeneratorReturnValue', addressGeneratorReturnValue
|
print 'addressGeneratorReturnValue', addressGeneratorReturnValue
|
||||||
if len(addressGeneratorReturnValue) == 0:
|
if len(addressGeneratorReturnValue) == 0:
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'newaddressdialog.ui'
|
# Form implementation generated from reading ui file 'newaddressdialog.ui'
|
||||||
#
|
#
|
||||||
# Created: Thu Jun 13 20:12:21 2013
|
# Created: Sun Sep 15 23:53:31 2013
|
||||||
# by: PyQt4 UI code generator 4.10.1
|
# by: PyQt4 UI code generator 4.10.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ class Ui_NewAddressDialog(object):
|
||||||
self.radioButtonDeterministicAddress.setText(_translate("NewAddressDialog", "Use a passphrase to make addresses", None))
|
self.radioButtonDeterministicAddress.setText(_translate("NewAddressDialog", "Use a passphrase to make addresses", None))
|
||||||
self.checkBoxEighteenByteRipe.setText(_translate("NewAddressDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None))
|
self.checkBoxEighteenByteRipe.setText(_translate("NewAddressDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None))
|
||||||
self.groupBoxDeterministic.setTitle(_translate("NewAddressDialog", "Make deterministic addresses", None))
|
self.groupBoxDeterministic.setTitle(_translate("NewAddressDialog", "Make deterministic addresses", None))
|
||||||
self.label_9.setText(_translate("NewAddressDialog", "Address version number: 3", None))
|
self.label_9.setText(_translate("NewAddressDialog", "Address version number: 4", None))
|
||||||
self.label_8.setText(_translate("NewAddressDialog", "In addition to your passphrase, you must remember these numbers:", None))
|
self.label_8.setText(_translate("NewAddressDialog", "In addition to your passphrase, you must remember these numbers:", None))
|
||||||
self.label_6.setText(_translate("NewAddressDialog", "Passphrase", None))
|
self.label_6.setText(_translate("NewAddressDialog", "Passphrase", None))
|
||||||
self.label_11.setText(_translate("NewAddressDialog", "Number of addresses to make based on your passphrase:", None))
|
self.label_11.setText(_translate("NewAddressDialog", "Number of addresses to make based on your passphrase:", None))
|
||||||
|
@ -191,13 +191,3 @@ class Ui_NewAddressDialog(object):
|
||||||
self.radioButtonExisting.setText(_translate("NewAddressDialog", "Use the same stream as an existing address", None))
|
self.radioButtonExisting.setText(_translate("NewAddressDialog", "Use the same stream as an existing address", None))
|
||||||
self.label_4.setText(_translate("NewAddressDialog", "(saves you some bandwidth and processing power)", None))
|
self.label_4.setText(_translate("NewAddressDialog", "(saves you some bandwidth and processing power)", None))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
app = QtGui.QApplication(sys.argv)
|
|
||||||
NewAddressDialog = QtGui.QDialog()
|
|
||||||
ui = Ui_NewAddressDialog()
|
|
||||||
ui.setupUi(NewAddressDialog)
|
|
||||||
NewAddressDialog.show()
|
|
||||||
sys.exit(app.exec_())
|
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="label_9">
|
<widget class="QLabel" name="label_9">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Address version number: 3</string>
|
<string>Address version number: 4</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'regenerateaddresses.ui'
|
# Form implementation generated from reading ui file 'regenerateaddresses.ui'
|
||||||
#
|
#
|
||||||
# Created: Tue Apr 30 12:21:16 2013
|
# Created: Sun Sep 15 23:50:23 2013
|
||||||
# by: PyQt4 UI code generator 4.9.4
|
# by: PyQt4 UI code generator 4.10.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui
|
||||||
try:
|
try:
|
||||||
_fromUtf8 = QtCore.QString.fromUtf8
|
_fromUtf8 = QtCore.QString.fromUtf8
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
_fromUtf8 = lambda s: s
|
def _fromUtf8(s):
|
||||||
|
return s
|
||||||
|
|
||||||
|
try:
|
||||||
|
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||||
|
def _translate(context, text, disambig):
|
||||||
|
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||||
|
except AttributeError:
|
||||||
|
def _translate(context, text, disambig):
|
||||||
|
return QtGui.QApplication.translate(context, text, disambig)
|
||||||
|
|
||||||
class Ui_regenerateAddressesDialog(object):
|
class Ui_regenerateAddressesDialog(object):
|
||||||
def setupUi(self, regenerateAddressesDialog):
|
def setupUi(self, regenerateAddressesDialog):
|
||||||
|
@ -56,13 +65,14 @@ class Ui_regenerateAddressesDialog(object):
|
||||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||||
self.gridLayout.addWidget(self.label_2, 4, 0, 1, 1)
|
self.gridLayout.addWidget(self.label_2, 4, 0, 1, 1)
|
||||||
self.lineEditAddressVersionNumber = QtGui.QLineEdit(self.groupBox)
|
self.lineEditAddressVersionNumber = QtGui.QLineEdit(self.groupBox)
|
||||||
self.lineEditAddressVersionNumber.setEnabled(False)
|
self.lineEditAddressVersionNumber.setEnabled(True)
|
||||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
sizePolicy.setHeightForWidth(self.lineEditAddressVersionNumber.sizePolicy().hasHeightForWidth())
|
sizePolicy.setHeightForWidth(self.lineEditAddressVersionNumber.sizePolicy().hasHeightForWidth())
|
||||||
self.lineEditAddressVersionNumber.setSizePolicy(sizePolicy)
|
self.lineEditAddressVersionNumber.setSizePolicy(sizePolicy)
|
||||||
self.lineEditAddressVersionNumber.setMaximumSize(QtCore.QSize(31, 16777215))
|
self.lineEditAddressVersionNumber.setMaximumSize(QtCore.QSize(31, 16777215))
|
||||||
|
self.lineEditAddressVersionNumber.setText(_fromUtf8(""))
|
||||||
self.lineEditAddressVersionNumber.setObjectName(_fromUtf8("lineEditAddressVersionNumber"))
|
self.lineEditAddressVersionNumber.setObjectName(_fromUtf8("lineEditAddressVersionNumber"))
|
||||||
self.gridLayout.addWidget(self.lineEditAddressVersionNumber, 4, 1, 1, 1)
|
self.gridLayout.addWidget(self.lineEditAddressVersionNumber, 4, 1, 1, 1)
|
||||||
spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
|
@ -101,15 +111,14 @@ class Ui_regenerateAddressesDialog(object):
|
||||||
QtCore.QMetaObject.connectSlotsByName(regenerateAddressesDialog)
|
QtCore.QMetaObject.connectSlotsByName(regenerateAddressesDialog)
|
||||||
|
|
||||||
def retranslateUi(self, regenerateAddressesDialog):
|
def retranslateUi(self, regenerateAddressesDialog):
|
||||||
regenerateAddressesDialog.setWindowTitle(QtGui.QApplication.translate("regenerateAddressesDialog", "Regenerate Existing Addresses", None, QtGui.QApplication.UnicodeUTF8))
|
regenerateAddressesDialog.setWindowTitle(_translate("regenerateAddressesDialog", "Regenerate Existing Addresses", None))
|
||||||
self.groupBox.setTitle(QtGui.QApplication.translate("regenerateAddressesDialog", "Regenerate existing addresses", None, QtGui.QApplication.UnicodeUTF8))
|
self.groupBox.setTitle(_translate("regenerateAddressesDialog", "Regenerate existing addresses", None))
|
||||||
self.label_6.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "Passphrase", None, QtGui.QApplication.UnicodeUTF8))
|
self.label_6.setText(_translate("regenerateAddressesDialog", "Passphrase", None))
|
||||||
self.label_11.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "Number of addresses to make based on your passphrase:", None, QtGui.QApplication.UnicodeUTF8))
|
self.label_11.setText(_translate("regenerateAddressesDialog", "Number of addresses to make based on your passphrase:", None))
|
||||||
self.label_2.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "Address version Number:", None, QtGui.QApplication.UnicodeUTF8))
|
self.label_2.setText(_translate("regenerateAddressesDialog", "Address version number:", None))
|
||||||
self.lineEditAddressVersionNumber.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "3", None, QtGui.QApplication.UnicodeUTF8))
|
self.label_3.setText(_translate("regenerateAddressesDialog", "Stream number:", None))
|
||||||
self.label_3.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "Stream number:", None, QtGui.QApplication.UnicodeUTF8))
|
self.lineEditStreamNumber.setText(_translate("regenerateAddressesDialog", "1", None))
|
||||||
self.lineEditStreamNumber.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "1", None, QtGui.QApplication.UnicodeUTF8))
|
self.checkBoxEighteenByteRipe.setText(_translate("regenerateAddressesDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None))
|
||||||
self.checkBoxEighteenByteRipe.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None, QtGui.QApplication.UnicodeUTF8))
|
self.label_4.setText(_translate("regenerateAddressesDialog", "You must check (or not check) this box just like you did (or didn\'t) when you made your addresses the first time.", None))
|
||||||
self.label_4.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "You must check (or not check) this box just like you did (or didn\'t) when you made your addresses the first time.", None, QtGui.QApplication.UnicodeUTF8))
|
self.label.setText(_translate("regenerateAddressesDialog", "If you have previously made deterministic addresses but lost them due to an accident (like hard drive failure), you can regenerate them here. If you used the random number generator to make your addresses then this form will be of no use to you.", None))
|
||||||
self.label.setText(QtGui.QApplication.translate("regenerateAddressesDialog", "If you have previously made deterministic addresses but lost them due to an accident (like hard drive failure), you can regenerate them here. If you used the random number generator to make your addresses then this form will be of no use to you.", None, QtGui.QApplication.UnicodeUTF8))
|
|
||||||
|
|
||||||
|
|
|
@ -86,14 +86,14 @@
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Address version Number:</string>
|
<string>Address version number:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QLineEdit" name="lineEditAddressVersionNumber">
|
<widget class="QLineEdit" name="lineEditAddressVersionNumber">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>3</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -21,16 +21,23 @@ class addressGenerator(threading.Thread):
|
||||||
queueValue = shared.addressGeneratorQueue.get()
|
queueValue = shared.addressGeneratorQueue.get()
|
||||||
nonceTrialsPerByte = 0
|
nonceTrialsPerByte = 0
|
||||||
payloadLengthExtraBytes = 0
|
payloadLengthExtraBytes = 0
|
||||||
|
try:
|
||||||
|
numberOfNullBytesDemandedOnFrontOfRipeHash = shared.config.getint(
|
||||||
|
'bitmessagesettings', 'numberofnullbytesonaddress')
|
||||||
|
except:
|
||||||
|
numberOfNullBytesDemandedOnFrontOfRipeHash = 1 # the default
|
||||||
if queueValue[0] == 'createChan':
|
if queueValue[0] == 'createChan':
|
||||||
command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue
|
command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue
|
||||||
eighteenByteRipe = False
|
eighteenByteRipe = False
|
||||||
numberOfAddressesToMake = 1
|
numberOfAddressesToMake = 1
|
||||||
|
numberOfNullBytesDemandedOnFrontOfRipeHash = 1
|
||||||
elif queueValue[0] == 'joinChan':
|
elif queueValue[0] == 'joinChan':
|
||||||
command, chanAddress, label, deterministicPassphrase = queueValue
|
command, chanAddress, label, deterministicPassphrase = queueValue
|
||||||
eighteenByteRipe = False
|
eighteenByteRipe = False
|
||||||
addressVersionNumber = decodeAddress(chanAddress)[1]
|
addressVersionNumber = decodeAddress(chanAddress)[1]
|
||||||
streamNumber = decodeAddress(chanAddress)[2]
|
streamNumber = decodeAddress(chanAddress)[2]
|
||||||
numberOfAddressesToMake = 1
|
numberOfAddressesToMake = 1
|
||||||
|
numberOfNullBytesDemandedOnFrontOfRipeHash = 1
|
||||||
elif len(queueValue) == 7:
|
elif len(queueValue) == 7:
|
||||||
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue
|
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue
|
||||||
elif len(queueValue) == 9:
|
elif len(queueValue) == 9:
|
||||||
|
@ -51,6 +58,8 @@ class addressGenerator(threading.Thread):
|
||||||
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
|
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
|
||||||
if payloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
|
if payloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
|
||||||
payloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
payloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
|
||||||
|
if eighteenByteRipe:
|
||||||
|
numberOfNullBytesDemandedOnFrontOfRipeHash = 2
|
||||||
if command == 'createRandomAddress':
|
if command == 'createRandomAddress':
|
||||||
shared.UISignalQueue.put((
|
shared.UISignalQueue.put((
|
||||||
'updateStatusBar', tr.translateText("MainWindow", "Generating one new address")))
|
'updateStatusBar', tr.translateText("MainWindow", "Generating one new address")))
|
||||||
|
@ -77,12 +86,8 @@ class addressGenerator(threading.Thread):
|
||||||
ripe.update(sha.digest())
|
ripe.update(sha.digest())
|
||||||
# print 'potential ripe.digest',
|
# print 'potential ripe.digest',
|
||||||
# ripe.digest().encode('hex')
|
# ripe.digest().encode('hex')
|
||||||
if eighteenByteRipe:
|
if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
|
||||||
if ripe.digest()[:2] == '\x00\x00':
|
break
|
||||||
break
|
|
||||||
else:
|
|
||||||
if ripe.digest()[:1] == '\x00':
|
|
||||||
break
|
|
||||||
print 'Generated address with ripe digest:', ripe.digest().encode('hex')
|
print 'Generated address with ripe digest:', ripe.digest().encode('hex')
|
||||||
print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'addresses per second before finding one with the correct ripe-prefix.'
|
print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'addresses per second before finding one with the correct ripe-prefix.'
|
||||||
address = encodeAddress(addressVersionNumber, streamNumber, ripe.digest())
|
address = encodeAddress(addressVersionNumber, streamNumber, ripe.digest())
|
||||||
|
@ -177,12 +182,8 @@ class addressGenerator(threading.Thread):
|
||||||
ripe.update(sha.digest())
|
ripe.update(sha.digest())
|
||||||
# print 'potential ripe.digest',
|
# print 'potential ripe.digest',
|
||||||
# ripe.digest().encode('hex')
|
# ripe.digest().encode('hex')
|
||||||
if eighteenByteRipe:
|
if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
|
||||||
if ripe.digest()[:2] == '\x00\x00':
|
break
|
||||||
break
|
|
||||||
else:
|
|
||||||
if ripe.digest()[:1] == '\x00':
|
|
||||||
break
|
|
||||||
|
|
||||||
print 'ripe.digest', ripe.digest().encode('hex')
|
print 'ripe.digest', ripe.digest().encode('hex')
|
||||||
print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'keys per second.'
|
print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'keys per second.'
|
||||||
|
|
|
@ -502,6 +502,10 @@ class receiveDataThread(threading.Thread):
|
||||||
print 'ECDSA verify failed', err
|
print 'ECDSA verify failed', err
|
||||||
return
|
return
|
||||||
# verify passed
|
# verify passed
|
||||||
|
fromAddress = encodeAddress(
|
||||||
|
sendersAddressVersion, sendersStream, ripe.digest())
|
||||||
|
with shared.printLock:
|
||||||
|
print 'fromAddress:', fromAddress
|
||||||
|
|
||||||
# Let's store the public key in case we want to reply to this person.
|
# Let's store the public key in case we want to reply to this person.
|
||||||
# We don't have the correct nonce or time (which would let us
|
# We don't have the correct nonce or time (which would let us
|
||||||
|
@ -515,16 +519,11 @@ class receiveDataThread(threading.Thread):
|
||||||
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + data[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + data[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
||||||
int(time.time()),
|
int(time.time()),
|
||||||
'yes')
|
'yes')
|
||||||
# shared.workerQueue.put(('newpubkey',(sendersAddressVersion,sendersStream,ripe.digest())))
|
|
||||||
# This will check to see whether we happen to be awaiting this
|
# This will check to see whether we happen to be awaiting this
|
||||||
# pubkey in order to send a message. If we are, it will do the
|
# pubkey in order to send a message. If we are, it will do the
|
||||||
# POW and send it.
|
# POW and send it.
|
||||||
self.possibleNewPubkey(ripe.digest())
|
self.possibleNewPubkey(ripe=ripe.digest())
|
||||||
|
|
||||||
fromAddress = encodeAddress(
|
|
||||||
sendersAddressVersion, sendersStream, ripe.digest())
|
|
||||||
with shared.printLock:
|
|
||||||
print 'fromAddress:', fromAddress
|
|
||||||
|
|
||||||
if messageEncodingType == 2:
|
if messageEncodingType == 2:
|
||||||
subject, body = self.decodeType2Message(message)
|
subject, body = self.decodeType2Message(message)
|
||||||
|
@ -665,7 +664,7 @@ class receiveDataThread(threading.Thread):
|
||||||
# This will check to see whether we happen to be awaiting this
|
# This will check to see whether we happen to be awaiting this
|
||||||
# pubkey in order to send a message. If we are, it will do the POW
|
# pubkey in order to send a message. If we are, it will do the POW
|
||||||
# and send it.
|
# and send it.
|
||||||
self.possibleNewPubkey(ripe.digest())
|
self.possibleNewPubkey(ripe=ripe.digest())
|
||||||
|
|
||||||
fromAddress = encodeAddress(
|
fromAddress = encodeAddress(
|
||||||
sendersAddressVersion, sendersStream, ripe.digest())
|
sendersAddressVersion, sendersStream, ripe.digest())
|
||||||
|
@ -713,38 +712,29 @@ class receiveDataThread(threading.Thread):
|
||||||
cleartextStreamNumber, cleartextStreamNumberLength = decodeVarint(
|
cleartextStreamNumber, cleartextStreamNumberLength = decodeVarint(
|
||||||
data[readPosition:readPosition + 10])
|
data[readPosition:readPosition + 10])
|
||||||
readPosition += cleartextStreamNumberLength
|
readPosition += cleartextStreamNumberLength
|
||||||
tag = data[readPostion:readPosition+32]
|
embeddedTag = data[readPosition:readPosition+32]
|
||||||
readPosition += 32
|
readPosition += 32
|
||||||
if tag not in shared.MyECSubscriptionCryptorObjects.items():
|
if embeddedTag not in shared.MyECSubscriptionCryptorObjects:
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'We\'re not interested in this broadcast.'
|
print 'We\'re not interested in this broadcast.'
|
||||||
return
|
return
|
||||||
initialDecryptionSuccessful = False
|
# We are interested in this broadcast because of its tag.
|
||||||
for key, cryptorObject in shared.MyECSubscriptionCryptorObjects.items():
|
cryptorObject = shared.MyECSubscriptionCryptorObjects[embeddedTag]
|
||||||
try:
|
try:
|
||||||
decryptedData = cryptorObject.decrypt(data[readPosition:])
|
decryptedData = cryptorObject.decrypt(data[readPosition:])
|
||||||
toRipe = key # This is the RIPE hash of the sender's pubkey. We need this below to compare to the RIPE hash of the sender's address to verify that it was encrypted by with their key rather than some other key.
|
print 'EC decryption successful'
|
||||||
initialDecryptionSuccessful = True
|
except Exception as err:
|
||||||
print 'EC decryption successful using key associated with ripe hash:', key.encode('hex')
|
|
||||||
break
|
|
||||||
except Exception as err:
|
|
||||||
pass
|
|
||||||
# print 'cryptorObject.decrypt Exception:', err
|
|
||||||
if not initialDecryptionSuccessful:
|
|
||||||
# This is not a broadcast I am interested in.
|
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'Length of time program spent failing to decrypt this v2 broadcast:', time.time() - self.messageProcessingStartTime, 'seconds.'
|
print 'Broadcast version 3 decryption Unsuccessful.'
|
||||||
|
|
||||||
return
|
return
|
||||||
# At this point this is a broadcast I have decrypted and thus am
|
|
||||||
# interested in.
|
|
||||||
signedBroadcastVersion, readPosition = decodeVarint(
|
signedBroadcastVersion, readPosition = decodeVarint(
|
||||||
decryptedData[:10])
|
decryptedData[:10])
|
||||||
beginningOfPubkeyPosition = readPosition # used when we add the pubkey to our pubkey table
|
beginningOfPubkeyPosition = readPosition # used when we add the pubkey to our pubkey table
|
||||||
sendersAddressVersion, sendersAddressVersionLength = decodeVarint(
|
sendersAddressVersion, sendersAddressVersionLength = decodeVarint(
|
||||||
decryptedData[readPosition:readPosition + 9])
|
decryptedData[readPosition:readPosition + 9])
|
||||||
if sendersAddressVersion < 2 or sendersAddressVersion > 3:
|
if sendersAddressVersion < 4:
|
||||||
print 'Cannot decode senderAddressVersion other than 2 or 3. Assuming the sender isn\'t being silly, you should upgrade Bitmessage because this message shall be ignored.'
|
print 'Cannot decode senderAddressVersion less than 4 for broadcast version number 3. Assuming the sender isn\'t being silly, you should upgrade Bitmessage because this message shall be ignored.'
|
||||||
return
|
return
|
||||||
readPosition += sendersAddressVersionLength
|
readPosition += sendersAddressVersionLength
|
||||||
sendersStream, sendersStreamLength = decodeVarint(
|
sendersStream, sendersStreamLength = decodeVarint(
|
||||||
|
@ -774,11 +764,14 @@ class receiveDataThread(threading.Thread):
|
||||||
|
|
||||||
sha = hashlib.new('sha512')
|
sha = hashlib.new('sha512')
|
||||||
sha.update(sendersPubSigningKey + sendersPubEncryptionKey)
|
sha.update(sendersPubSigningKey + sendersPubEncryptionKey)
|
||||||
ripe = hashlib.new('ripemd160')
|
ripeHasher = hashlib.new('ripemd160')
|
||||||
ripe.update(sha.digest())
|
ripeHasher.update(sha.digest())
|
||||||
|
calculatedRipe = ripeHasher.digest()
|
||||||
|
|
||||||
if toRipe != ripe.digest():
|
calculatedTag = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
print 'The encryption key used to encrypt this message doesn\'t match the keys inbedded in the message itself. Ignoring message.'
|
sendersAddressVersion) + encodeVarint(sendersStream) + calculatedRipe).digest()).digest()[32:]
|
||||||
|
if calculatedTag != embeddedTag:
|
||||||
|
print 'The tag and encryption key used to encrypt this message doesn\'t match the keys inbedded in the message itself. Ignoring message.'
|
||||||
return
|
return
|
||||||
messageEncodingType, messageEncodingTypeLength = decodeVarint(
|
messageEncodingType, messageEncodingTypeLength = decodeVarint(
|
||||||
decryptedData[readPosition:readPosition + 9])
|
decryptedData[readPosition:readPosition + 9])
|
||||||
|
@ -806,24 +799,23 @@ class receiveDataThread(threading.Thread):
|
||||||
return
|
return
|
||||||
# verify passed
|
# verify passed
|
||||||
|
|
||||||
# Let's store the public key in case we want to reply to this
|
|
||||||
# person.
|
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
|
||||||
ripe.digest(),
|
|
||||||
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
|
||||||
int(time.time()),
|
|
||||||
'yes')
|
|
||||||
# shared.workerQueue.put(('newpubkey',(sendersAddressVersion,sendersStream,ripe.digest())))
|
|
||||||
# This will check to see whether we happen to be awaiting this
|
|
||||||
# pubkey in order to send a message. If we are, it will do the POW
|
|
||||||
# and send it.
|
|
||||||
self.possibleNewPubkey(ripe.digest())
|
|
||||||
|
|
||||||
fromAddress = encodeAddress(
|
fromAddress = encodeAddress(
|
||||||
sendersAddressVersion, sendersStream, ripe.digest())
|
sendersAddressVersion, sendersStream, calculatedRipe)
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'fromAddress:', fromAddress
|
print 'fromAddress:', fromAddress
|
||||||
|
|
||||||
|
# Let's store the public key in case we want to reply to this person.
|
||||||
|
sqlExecute(
|
||||||
|
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
||||||
|
calculatedRipe,
|
||||||
|
'\x00\x00\x00\x00\x00\x00\x00\x01' + decryptedData[beginningOfPubkeyPosition:endOfPubkeyPosition],
|
||||||
|
int(time.time()),
|
||||||
|
'yes')
|
||||||
|
# This will check to see whether we happen to be awaiting this
|
||||||
|
# pubkey in order to send a message. If we are, it will do the
|
||||||
|
# POW and send it.
|
||||||
|
self.possibleNewPubkey(address = fromAddress)
|
||||||
|
|
||||||
if messageEncodingType == 2:
|
if messageEncodingType == 2:
|
||||||
subject, body = self.decodeType2Message(message)
|
subject, body = self.decodeType2Message(message)
|
||||||
elif messageEncodingType == 1:
|
elif messageEncodingType == 1:
|
||||||
|
@ -861,8 +853,6 @@ class receiveDataThread(threading.Thread):
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'Time spent processing this interesting broadcast:', time.time() - self.messageProcessingStartTime
|
print 'Time spent processing this interesting broadcast:', time.time() - self.messageProcessingStartTime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# We have received a msg message.
|
# We have received a msg message.
|
||||||
def recmsg(self, data):
|
def recmsg(self, data):
|
||||||
self.messageProcessingStartTime = time.time()
|
self.messageProcessingStartTime = time.time()
|
||||||
|
@ -999,7 +989,7 @@ class receiveDataThread(threading.Thread):
|
||||||
if sendersAddressVersionNumber == 0:
|
if sendersAddressVersionNumber == 0:
|
||||||
print 'Cannot understand sendersAddressVersionNumber = 0. Ignoring message.'
|
print 'Cannot understand sendersAddressVersionNumber = 0. Ignoring message.'
|
||||||
return
|
return
|
||||||
if sendersAddressVersionNumber >= 4:
|
if sendersAddressVersionNumber > 4:
|
||||||
print 'Sender\'s address version number', sendersAddressVersionNumber, 'not yet supported. Ignoring message.'
|
print 'Sender\'s address version number', sendersAddressVersionNumber, 'not yet supported. Ignoring message.'
|
||||||
return
|
return
|
||||||
if len(decryptedData) < 170:
|
if len(decryptedData) < 170:
|
||||||
|
@ -1074,21 +1064,32 @@ class receiveDataThread(threading.Thread):
|
||||||
sha.update(pubSigningKey + pubEncryptionKey)
|
sha.update(pubSigningKey + pubEncryptionKey)
|
||||||
ripe = hashlib.new('ripemd160')
|
ripe = hashlib.new('ripemd160')
|
||||||
ripe.update(sha.digest())
|
ripe.update(sha.digest())
|
||||||
# Let's store the public key in case we want to reply to this
|
|
||||||
# person.
|
|
||||||
sqlExecute(
|
|
||||||
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
|
||||||
ripe.digest(),
|
|
||||||
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
|
||||||
int(time.time()),
|
|
||||||
'yes')
|
|
||||||
# shared.workerQueue.put(('newpubkey',(sendersAddressVersionNumber,sendersStreamNumber,ripe.digest())))
|
|
||||||
# This will check to see whether we happen to be awaiting this
|
|
||||||
# pubkey in order to send a message. If we are, it will do the POW
|
|
||||||
# and send it.
|
|
||||||
self.possibleNewPubkey(ripe.digest())
|
|
||||||
fromAddress = encodeAddress(
|
fromAddress = encodeAddress(
|
||||||
sendersAddressVersionNumber, sendersStreamNumber, ripe.digest())
|
sendersAddressVersionNumber, sendersStreamNumber, ripe.digest())
|
||||||
|
# Let's store the public key in case we want to reply to this
|
||||||
|
# person.
|
||||||
|
if sendersAddressVersionNumber <= 3:
|
||||||
|
sqlExecute(
|
||||||
|
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
||||||
|
ripe.digest(),
|
||||||
|
'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' + '\xFF\xFF\xFF\xFF' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
||||||
|
int(time.time()),
|
||||||
|
'yes')
|
||||||
|
# This will check to see whether we happen to be awaiting this
|
||||||
|
# pubkey in order to send a message. If we are, it will do the POW
|
||||||
|
# and send it.
|
||||||
|
self.possibleNewPubkey(ripe=ripe.digest())
|
||||||
|
elif sendersAddressVersionNumber >= 4:
|
||||||
|
sqlExecute(
|
||||||
|
'''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
||||||
|
ripe.digest(),
|
||||||
|
'\x00\x00\x00\x00\x00\x00\x00\x01' + decryptedData[messageVersionLength:endOfThePublicKeyPosition],
|
||||||
|
int(time.time()),
|
||||||
|
'yes')
|
||||||
|
# This will check to see whether we happen to be awaiting this
|
||||||
|
# pubkey in order to send a message. If we are, it will do the POW
|
||||||
|
# and send it.
|
||||||
|
self.possibleNewPubkey(address = fromAddress)
|
||||||
# If this message is bound for one of my version 3 addresses (or
|
# If this message is bound for one of my version 3 addresses (or
|
||||||
# higher), then we must check to make sure it meets our demanded
|
# higher), then we must check to make sure it meets our demanded
|
||||||
# proof of work requirement.
|
# proof of work requirement.
|
||||||
|
@ -1240,18 +1241,36 @@ class receiveDataThread(threading.Thread):
|
||||||
else:
|
else:
|
||||||
return '[' + mailingListName + '] ' + subject
|
return '[' + mailingListName + '] ' + subject
|
||||||
|
|
||||||
def possibleNewPubkey(self, toRipe):
|
# We have inserted a pubkey into our pubkey table which we received from a
|
||||||
if toRipe in shared.neededPubkeys:
|
# pubkey, msg, or broadcast message. It might be one that we have been
|
||||||
print 'We have been awaiting the arrival of this pubkey.'
|
# waiting for. Let's check.
|
||||||
del shared.neededPubkeys[toRipe]
|
def possibleNewPubkey(self, ripe=None, address=None):
|
||||||
sqlExecute(
|
# For address versions <= 3, we wait on a key with the correct ripe hash
|
||||||
'''UPDATE sent SET status='doingmsgpow' WHERE toripe=? AND (status='awaitingpubkey' or status='doingpubkeypow') and folder='sent' ''',
|
if ripe != None:
|
||||||
toRipe)
|
if ripe in shared.neededPubkeys:
|
||||||
shared.workerQueue.put(('sendmessage', ''))
|
print 'We have been awaiting the arrival of this pubkey.'
|
||||||
else:
|
del shared.neededPubkeys[ripe]
|
||||||
with shared.printLock:
|
sqlExecute(
|
||||||
print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', toRipe.encode('hex')
|
'''UPDATE sent SET status='doingmsgpow' WHERE toripe=? AND (status='awaitingpubkey' or status='doingpubkeypow') and folder='sent' ''',
|
||||||
|
ripe)
|
||||||
|
shared.workerQueue.put(('sendmessage', ''))
|
||||||
|
else:
|
||||||
|
with shared.printLock:
|
||||||
|
print 'We don\'t need this pub key. We didn\'t ask for it. Pubkey hash:', ripe.encode('hex')
|
||||||
|
# For address versions >= 4, we wait on a pubkey with the correct tag.
|
||||||
|
# Let us create the tag from the address and see if we were waiting
|
||||||
|
# for it.
|
||||||
|
elif address != None:
|
||||||
|
status, addressVersion, streamNumber, ripe = decodeAddress(address)
|
||||||
|
tag = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
|
addressVersion) + encodeVarint(streamNumber) + ripe).digest()).digest()[32:]
|
||||||
|
if tag in shared.neededPubkeys:
|
||||||
|
print 'We have been awaiting the arrival of this pubkey.'
|
||||||
|
del shared.neededPubkeys[tag]
|
||||||
|
sqlExecute(
|
||||||
|
'''UPDATE sent SET status='doingmsgpow' WHERE toripe=? AND (status='awaitingpubkey' or status='doingpubkeypow') and folder='sent' ''',
|
||||||
|
ripe)
|
||||||
|
shared.workerQueue.put(('sendmessage', ''))
|
||||||
|
|
||||||
# We have received a pubkey
|
# We have received a pubkey
|
||||||
def recpubkey(self, data):
|
def recpubkey(self, data):
|
||||||
|
@ -1322,7 +1341,7 @@ class receiveDataThread(threading.Thread):
|
||||||
|
|
||||||
self.processpubkey(data)
|
self.processpubkey(data)
|
||||||
|
|
||||||
lengthOfTimeWeShouldUseToProcessThisMessage = .2
|
lengthOfTimeWeShouldUseToProcessThisMessage = .1
|
||||||
sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \
|
sleepTime = lengthOfTimeWeShouldUseToProcessThisMessage - \
|
||||||
(time.time() - self.pubkeyProcessingStartTime)
|
(time.time() - self.pubkeyProcessingStartTime)
|
||||||
if sleepTime > 0 and doTimingAttackMitigation:
|
if sleepTime > 0 and doTimingAttackMitigation:
|
||||||
|
@ -1400,7 +1419,7 @@ class receiveDataThread(threading.Thread):
|
||||||
# This will also update the embeddedTime.
|
# This will also update the embeddedTime.
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
||||||
# shared.workerQueue.put(('newpubkey',(addressVersion,streamNumber,ripe)))
|
# shared.workerQueue.put(('newpubkey',(addressVersion,streamNumber,ripe)))
|
||||||
self.possibleNewPubkey(ripe)
|
self.possibleNewPubkey(ripe = ripe)
|
||||||
if addressVersion == 3:
|
if addressVersion == 3:
|
||||||
if len(data) < 170: # sanity check.
|
if len(data) < 170: # sanity check.
|
||||||
print '(within processpubkey) payloadLength less than 170. Sanity check failed.'
|
print '(within processpubkey) payloadLength less than 170. Sanity check failed.'
|
||||||
|
@ -1456,7 +1475,7 @@ class receiveDataThread(threading.Thread):
|
||||||
t = (ripe, data, embeddedTime, 'no')
|
t = (ripe, data, embeddedTime, 'no')
|
||||||
# This will also update the embeddedTime.
|
# This will also update the embeddedTime.
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
||||||
self.possibleNewPubkey(ripe)
|
self.possibleNewPubkey(ripe = ripe)
|
||||||
|
|
||||||
if addressVersion == 4:
|
if addressVersion == 4:
|
||||||
print 'length of v4 pubkey:', len(data)
|
print 'length of v4 pubkey:', len(data)
|
||||||
|
@ -1470,13 +1489,8 @@ class receiveDataThread(threading.Thread):
|
||||||
if tag not in shared.neededPubkeys:
|
if tag not in shared.neededPubkeys:
|
||||||
with shared.printLock:
|
with shared.printLock:
|
||||||
print 'We don\'t need this v4 pubkey. We didn\'t ask for it.'
|
print 'We don\'t need this v4 pubkey. We didn\'t ask for it.'
|
||||||
print 'tag is', repr(tag)
|
|
||||||
print 'shared.neededPubkeys is', repr(shared.neededPubkeys)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
with shared.printLock:
|
|
||||||
print 'We have been awaiting the arrival of this pubkey.'
|
|
||||||
|
|
||||||
# Let us try to decrypt the pubkey
|
# Let us try to decrypt the pubkey
|
||||||
cryptorObject = shared.neededPubkeys[tag]
|
cryptorObject = shared.neededPubkeys[tag]
|
||||||
try:
|
try:
|
||||||
|
@ -1543,10 +1557,12 @@ class receiveDataThread(threading.Thread):
|
||||||
t = (ripe, signedData, embeddedTime, 'yes')
|
t = (ripe, signedData, embeddedTime, 'yes')
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
||||||
|
|
||||||
sqlExecute(
|
fromAddress = encodeAddress(addressVersion, streamNumber, ripe)
|
||||||
'''UPDATE sent SET status='doingmsgpow' WHERE toripe=? AND (status='awaitingpubkey' or status='doingpubkeypow') and folder='sent' ''',
|
# That this point we know that we have been waiting on this pubkey.
|
||||||
ripe)
|
# This function will command the workerThread to start work on
|
||||||
shared.workerQueue.put(('sendmessage', ''))
|
# the messages that require it.
|
||||||
|
self.possibleNewPubkey(address = fromAddress)
|
||||||
|
|
||||||
|
|
||||||
# We have received a getpubkey message
|
# We have received a getpubkey message
|
||||||
def recgetpubkey(self, data):
|
def recgetpubkey(self, data):
|
||||||
|
|
|
@ -125,7 +125,7 @@ class singleCleaner(threading.Thread):
|
||||||
shared.inventorySets[streamNumber].add(row[0])
|
shared.inventorySets[streamNumber].add(row[0])
|
||||||
with shared.inventoryLock:
|
with shared.inventoryLock:
|
||||||
for hash, storedValue in shared.inventory.items():
|
for hash, storedValue in shared.inventory.items():
|
||||||
objectType, streamNumber, payload, receivedTime = storedValue
|
objectType, streamNumber, payload, receivedTime, tag = storedValue
|
||||||
if streamNumber in shared.inventorySets:
|
if streamNumber in shared.inventorySets:
|
||||||
shared.inventorySets[streamNumber].add(hash)
|
shared.inventorySets[streamNumber].add(hash)
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ class singleListener(threading.Thread):
|
||||||
def run(self):
|
def run(self):
|
||||||
while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
|
while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
#helper_bootstrap.dns()
|
helper_bootstrap.dns()
|
||||||
# We typically don't want to accept incoming connections if the user is using a
|
# We typically don't want to accept incoming connections if the user is using a
|
||||||
# SOCKS proxy, unless they have configured otherwise. If they eventually select
|
# SOCKS proxy, unless they have configured otherwise. If they eventually select
|
||||||
# proxy 'none' or configure SOCKS listening then this will start listening for
|
# proxy 'none' or configure SOCKS listening then this will start listening for
|
||||||
|
|
|
@ -31,8 +31,6 @@ class singleWorker(threading.Thread):
|
||||||
if toAddressVersionNumber <= 3 :
|
if toAddressVersionNumber <= 3 :
|
||||||
shared.neededPubkeys[toripe] = 0
|
shared.neededPubkeys[toripe] = 0
|
||||||
elif toAddressVersionNumber >= 4:
|
elif toAddressVersionNumber >= 4:
|
||||||
with shared.printLock:
|
|
||||||
print 'Loading our list of needed pubkeys...'
|
|
||||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe).digest()).digest()
|
toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe).digest()).digest()
|
||||||
privEncryptionKey = doubleHashOfAddressData[:32] # Note that this is the first half of the sha512 hash.
|
privEncryptionKey = doubleHashOfAddressData[:32] # Note that this is the first half of the sha512 hash.
|
||||||
|
@ -134,13 +132,6 @@ class singleWorker(threading.Thread):
|
||||||
trialValue, nonce = proofofwork.run(target, initialHash)
|
trialValue, nonce = proofofwork.run(target, initialHash)
|
||||||
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
|
||||||
payload = pack('>Q', nonce) + payload
|
payload = pack('>Q', nonce) + payload
|
||||||
"""t = (hash,payload,embeddedTime,'no')
|
|
||||||
shared.sqlLock.acquire()
|
|
||||||
shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''')
|
|
||||||
shared.sqlSubmitQueue.put(t)
|
|
||||||
queryreturn = shared.sqlReturnQueue.get()
|
|
||||||
shared.sqlSubmitQueue.put('commit')
|
|
||||||
shared.sqlLock.release()"""
|
|
||||||
|
|
||||||
inventoryHash = calculateInventoryHash(payload)
|
inventoryHash = calculateInventoryHash(payload)
|
||||||
objectType = 'pubkey'
|
objectType = 'pubkey'
|
||||||
|
@ -256,6 +247,7 @@ class singleWorker(threading.Thread):
|
||||||
payload = pack('>Q', (embeddedTime))
|
payload = pack('>Q', (embeddedTime))
|
||||||
payload += encodeVarint(addressVersionNumber) # Address version number
|
payload += encodeVarint(addressVersionNumber) # Address version number
|
||||||
payload += encodeVarint(streamNumber)
|
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).
|
dataToEncrypt = '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki).
|
||||||
|
|
||||||
|
@ -278,7 +270,6 @@ class singleWorker(threading.Thread):
|
||||||
privSigningKeyHex).decode('hex')
|
privSigningKeyHex).decode('hex')
|
||||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||||
privEncryptionKeyHex).decode('hex')
|
privEncryptionKeyHex).decode('hex')
|
||||||
|
|
||||||
dataToEncrypt += pubSigningKey[1:]
|
dataToEncrypt += pubSigningKey[1:]
|
||||||
dataToEncrypt += pubEncryptionKey[1:]
|
dataToEncrypt += pubEncryptionKey[1:]
|
||||||
|
|
||||||
|
@ -286,25 +277,28 @@ class singleWorker(threading.Thread):
|
||||||
myAddress, 'noncetrialsperbyte'))
|
myAddress, 'noncetrialsperbyte'))
|
||||||
dataToEncrypt += encodeVarint(shared.config.getint(
|
dataToEncrypt += encodeVarint(shared.config.getint(
|
||||||
myAddress, 'payloadlengthextrabytes'))
|
myAddress, 'payloadlengthextrabytes'))
|
||||||
|
|
||||||
|
dataToStoreInOurPubkeysTable += dataToEncrypt # dataToStoreInOurPubkeysTable is used if this is a chan
|
||||||
|
|
||||||
signature = highlevelcrypto.sign(payload + dataToEncrypt, privSigningKeyHex)
|
signature = highlevelcrypto.sign(payload + dataToEncrypt, privSigningKeyHex)
|
||||||
dataToEncrypt += encodeVarint(len(signature))
|
dataToEncrypt += encodeVarint(len(signature))
|
||||||
dataToEncrypt += signature
|
dataToEncrypt += signature
|
||||||
|
|
||||||
# Let us encrypt the necessary data. We will use a hash of the data
|
|
||||||
# contained in an address as a decryption key. This way in order to
|
|
||||||
# read the public keys in a pubkey message, a node must know the address
|
|
||||||
# first. We'll also tag, unencrypted, the pubkey with part of the hash
|
|
||||||
# so that nodes know which pubkey object to try to decrypt when they
|
|
||||||
# want to send a message.
|
|
||||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
|
||||||
addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()
|
|
||||||
payload += doubleHashOfAddressData[32:] # the tag
|
|
||||||
privEncryptionKey = doubleHashOfAddressData[:32]
|
|
||||||
pubEncryptionKey = pointMult(privEncryptionKey)
|
|
||||||
payload += highlevelcrypto.encrypt(
|
|
||||||
dataToEncrypt, pubEncryptionKey.encode('hex'))
|
|
||||||
|
|
||||||
if not shared.safeConfigGetBoolean(myAddress, 'chan'):
|
if not shared.safeConfigGetBoolean(myAddress, 'chan'):
|
||||||
|
# Let us encrypt the necessary data. We will use a hash of the data
|
||||||
|
# contained in an address as a decryption key. This way in order to
|
||||||
|
# read the public keys in a pubkey message, a node must know the address
|
||||||
|
# first. We'll also tag, unencrypted, the pubkey with part of the hash
|
||||||
|
# so that nodes know which pubkey object to try to decrypt when they
|
||||||
|
# want to send a message.
|
||||||
|
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
|
addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()
|
||||||
|
payload += doubleHashOfAddressData[32:] # the tag
|
||||||
|
privEncryptionKey = doubleHashOfAddressData[:32]
|
||||||
|
pubEncryptionKey = pointMult(privEncryptionKey)
|
||||||
|
payload += highlevelcrypto.encrypt(
|
||||||
|
dataToEncrypt, pubEncryptionKey.encode('hex'))
|
||||||
|
|
||||||
# Do the POW for this pubkey message
|
# Do the POW for this pubkey message
|
||||||
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
|
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
|
||||||
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||||
|
@ -330,9 +324,10 @@ class singleWorker(threading.Thread):
|
||||||
# network but rather will only store it in our pubkeys table so that
|
# network but rather will only store it in our pubkeys table so that
|
||||||
# we can send messages to "ourselves".
|
# we can send messages to "ourselves".
|
||||||
if shared.safeConfigGetBoolean(myAddress, 'chan'):
|
if shared.safeConfigGetBoolean(myAddress, 'chan'):
|
||||||
|
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''',
|
||||||
hash,
|
hash,
|
||||||
payload,
|
dataToStoreInOurPubkeysTable,
|
||||||
embeddedTime,
|
embeddedTime,
|
||||||
'yes')
|
'yes')
|
||||||
shared.config.set(
|
shared.config.set(
|
||||||
|
@ -374,14 +369,21 @@ class singleWorker(threading.Thread):
|
||||||
pubEncryptionKey = highlevelcrypto.privToPub(
|
pubEncryptionKey = highlevelcrypto.privToPub(
|
||||||
privEncryptionKeyHex).decode('hex')
|
privEncryptionKeyHex).decode('hex')
|
||||||
|
|
||||||
|
print 'embedding pubEncryptionKey:', pubEncryptionKey.encode('hex')
|
||||||
|
|
||||||
payload = pack('>Q', (int(time.time()) + random.randrange(
|
payload = pack('>Q', (int(time.time()) + random.randrange(
|
||||||
-300, 300))) # the current time plus or minus five minutes
|
-300, 300))) # the current time plus or minus five minutes
|
||||||
payload += encodeVarint(2) # broadcast version
|
if addressVersionNumber <= 3:
|
||||||
|
payload += encodeVarint(2) # broadcast version
|
||||||
|
else:
|
||||||
|
payload += encodeVarint(3) # broadcast version
|
||||||
payload += encodeVarint(streamNumber)
|
payload += encodeVarint(streamNumber)
|
||||||
if addressVersionNumber >= 4:
|
if addressVersionNumber >= 4:
|
||||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()).digest()
|
addressVersionNumber) + encodeVarint(streamNumber) + ripe).digest()).digest()
|
||||||
payload += doubleHashOfAddressData[32:] # the tag
|
payload += doubleHashOfAddressData[32:] # the tag
|
||||||
|
print 'embeddedTag is', doubleHashOfAddressData[32:].encode('hex')
|
||||||
|
print 'embeddedTag is', repr(doubleHashOfAddressData[32:])
|
||||||
|
|
||||||
if addressVersionNumber <= 3:
|
if addressVersionNumber <= 3:
|
||||||
dataToEncrypt = encodeVarint(2) # broadcast version
|
dataToEncrypt = encodeVarint(2) # broadcast version
|
||||||
|
@ -476,80 +478,35 @@ class singleWorker(threading.Thread):
|
||||||
else:
|
else:
|
||||||
# We have not yet sent a request for the pubkey
|
# We have not yet sent a request for the pubkey
|
||||||
needToRequestPubkey = True
|
needToRequestPubkey = True
|
||||||
if toAddressVersion >= 4:
|
if toAddressVersion >= 4: # If we are trying to send to address version >= 4 then the needed pubkey might be encrypted in the inventory.
|
||||||
# We might have the pubkey in the inventory and need to decrypt it and put it in the pubkeys table.
|
# If we have it we'll need to decrypt it and put it in the pubkeys table.
|
||||||
queryreturn = sqlQuery(
|
queryreturn = sqlQuery(
|
||||||
'''SELECT payload FROM inventory WHERE objecttype='pubkey' and tag=? ''', toTag)
|
'''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.
|
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:
|
for row in queryreturn:
|
||||||
data, = row
|
data, = row
|
||||||
readPosition = 8 # for the nonce
|
if shared.decryptAndCheckPubkeyPayload(data[8:], toaddress) == 'successful':
|
||||||
readPosition += 8 # for the time
|
needToRequestPubkey = False
|
||||||
readPosition += 1 # for the address version number
|
print 'debug. successfully decrypted and checked pubkey from sql inventory.' #testing
|
||||||
streamNumber, varintLength = decodeVarint(
|
sqlExecute(
|
||||||
data[readPosition:readPosition + 10])
|
'''UPDATE sent SET status='doingmsgpow' WHERE toaddress=? AND status='msgqueued' ''',
|
||||||
readPosition += varintLength
|
toaddress)
|
||||||
signedData = data[8:readPosition] # Some of the signed data is not encrypted so let's keep it for now.
|
break
|
||||||
readPosition += 32 #for the tag
|
else: # There was something wrong with this pubkey even though it had the correct tag- almost certainly because of malicious behavior or a badly programmed client.
|
||||||
encryptedData = data[readPosition:]
|
|
||||||
# Let us try to decrypt the pubkey
|
|
||||||
privEncryptionKey = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+ripe).digest()).digest()[:32]
|
|
||||||
cryptorObject = highlevelcrypto.makeCryptor(privEncryptionKey.encode('hex'))
|
|
||||||
try:
|
|
||||||
decryptedData = cryptorObject.decrypt(encryptedData)
|
|
||||||
except:
|
|
||||||
# Someone must have encrypted some data with a different key
|
|
||||||
# but tagged it with a tag for which we are watching.
|
|
||||||
with shared.printLock:
|
|
||||||
print 'Pubkey decryption was UNsuccessful.'
|
|
||||||
continue
|
continue
|
||||||
print 'Pubkey decryption successful'
|
if needToRequestPubkey: # Obviously we had no success looking in the sql inventory. Let's look through the memory inventory.
|
||||||
readPosition = 4 # bypass the behavior bitfield
|
with shared.inventoryLock:
|
||||||
publicSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
for hash, storedValue in shared.inventory.items():
|
||||||
# Is it possible for a public key to be invalid such that trying to
|
objectType, streamNumber, payload, receivedTime, tag = storedValue
|
||||||
# encrypt or sign with it will cause an error? If it is, we should
|
if objectType == 'pubkey' and tag == toTag:
|
||||||
# probably test these keys here.
|
result = shared.decryptAndCheckPubkeyPayload(payload[8:], toaddress) #if valid, this function also puts it in the pubkeys table.
|
||||||
readPosition += 64
|
if result == 'successful':
|
||||||
publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
print 'debug. successfully decrypted and checked pubkey from memory inventory.'
|
||||||
readPosition += 64
|
needToRequestPubkey = False
|
||||||
specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint(
|
sqlExecute(
|
||||||
decryptedData[readPosition:readPosition + 10])
|
'''UPDATE sent SET status='doingmsgpow' WHERE toaddress=? AND status='msgqueued' ''',
|
||||||
readPosition += specifiedNonceTrialsPerByteLength
|
toaddress)
|
||||||
specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint(
|
break
|
||||||
decryptedData[readPosition:readPosition + 10])
|
|
||||||
readPosition += specifiedPayloadLengthExtraBytesLength
|
|
||||||
signedData += decryptedData[:readPosition]
|
|
||||||
signatureLength, signatureLengthLength = decodeVarint(
|
|
||||||
decryptedData[readPosition:readPosition + 10])
|
|
||||||
readPosition += signatureLengthLength
|
|
||||||
signature = decryptedData[readPosition:readPosition + signatureLength]
|
|
||||||
try:
|
|
||||||
if not highlevelcrypto.verify(signedData, signature, publicSigningKey.encode('hex')):
|
|
||||||
print 'ECDSA verify failed (within processpubkey)'
|
|
||||||
continue
|
|
||||||
print 'ECDSA verify passed (within processpubkey)'
|
|
||||||
except Exception as err:
|
|
||||||
print 'ECDSA verify failed (within processpubkey)', err
|
|
||||||
continue
|
|
||||||
|
|
||||||
sha = hashlib.new('sha512')
|
|
||||||
sha.update(publicSigningKey + publicEncryptionKey)
|
|
||||||
ripeHasher = hashlib.new('ripemd160')
|
|
||||||
ripeHasher.update(sha.digest())
|
|
||||||
ripe = ripeHasher.digest()
|
|
||||||
|
|
||||||
# We need to make sure that the tag on the outside of the encryption
|
|
||||||
# is the one generated from hashing these particular keys.
|
|
||||||
if toTag != hashlib.sha512(hashlib.sha512(encodeVarint(addressVersion) + encodeVarint(streamNumber) + ripe).digest()).digest()[32:]:
|
|
||||||
with shared.printLock:
|
|
||||||
print 'Someone was trying to act malicious: tag doesn\'t match the keys in this pubkey message. Ignoring it.'
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
print 'Tag successfully matches keys in pubkey message' # testing. Will remove soon.
|
|
||||||
|
|
||||||
t = (ripe, signedData, embeddedTime, 'yes')
|
|
||||||
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
|
||||||
needToRequestPubkey == False
|
|
||||||
if needToRequestPubkey:
|
if needToRequestPubkey:
|
||||||
sqlExecute(
|
sqlExecute(
|
||||||
'''UPDATE sent SET status='doingpubkeypow' WHERE toaddress=? AND status='msgqueued' ''',
|
'''UPDATE sent SET status='doingpubkeypow' WHERE toaddress=? AND status='msgqueued' ''',
|
||||||
|
@ -808,7 +765,7 @@ class singleWorker(threading.Thread):
|
||||||
payload += encodeVarint(len(signature))
|
payload += encodeVarint(len(signature))
|
||||||
payload += signature
|
payload += signature
|
||||||
|
|
||||||
|
print 'using pubEncryptionKey:', pubEncryptionKeyBase256.encode('hex')
|
||||||
# We have assembled the data that will be encrypted.
|
# We have assembled the data that will be encrypted.
|
||||||
try:
|
try:
|
||||||
encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex'))
|
encrypted = highlevelcrypto.encrypt(payload,"04"+pubEncryptionKeyBase256.encode('hex'))
|
||||||
|
|
|
@ -11,15 +11,14 @@ def createDefaultKnownNodes(appdata):
|
||||||
############## Stream 1 ################
|
############## Stream 1 ################
|
||||||
stream1 = {}
|
stream1 = {}
|
||||||
|
|
||||||
"""stream1[shared.Peer('85.171.174.131', 8444)] = int(time.time())
|
stream1[shared.Peer('85.171.174.131', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('23.28.68.159', 8444)] = int(time.time())
|
stream1[shared.Peer('23.28.68.159', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('66.108.210.240', 8444)] = int(time.time())
|
stream1[shared.Peer('66.108.210.240', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('204.236.246.212', 8444)] = int(time.time())
|
stream1[shared.Peer('204.236.246.212', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('78.81.56.239', 8444)] = int(time.time())
|
stream1[shared.Peer('78.81.56.239', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('122.60.235.157', 8444)] = int(time.time())
|
stream1[shared.Peer('122.60.235.157', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('204.236.246.212', 8444)] = int(time.time())
|
stream1[shared.Peer('204.236.246.212', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('24.98.219.109', 8444)] = int(time.time())"""
|
stream1[shared.Peer('24.98.219.109', 8444)] = int(time.time())
|
||||||
stream1[shared.Peer('12.34.56.78', 8444)] = int(time.time())
|
|
||||||
|
|
||||||
|
|
||||||
############# Stream 2 #################
|
############# Stream 2 #################
|
||||||
|
|
|
@ -5,7 +5,7 @@ lengthOfTimeToLeaveObjectsInInventory = 237600 # Equals two days and 18 hours.
|
||||||
lengthOfTimeToHoldOnToAllPubkeys = 2419200 # Equals 4 weeks. You could make this longer if you want but making it shorter would not be advisable because there is a very small possibility that it could keep you from obtaining a needed pubkey for a period of time.
|
lengthOfTimeToHoldOnToAllPubkeys = 2419200 # Equals 4 weeks. You could make this longer if you want but making it shorter would not be advisable because there is a very small possibility that it could keep you from obtaining a needed pubkey for a period of time.
|
||||||
maximumAgeOfObjectsThatIAdvertiseToOthers = 216000 # Equals two days and 12 hours
|
maximumAgeOfObjectsThatIAdvertiseToOthers = 216000 # Equals two days and 12 hours
|
||||||
maximumAgeOfNodesThatIAdvertiseToOthers = 10800 # Equals three hours
|
maximumAgeOfNodesThatIAdvertiseToOthers = 10800 # Equals three hours
|
||||||
useVeryEasyProofOfWorkForTesting = True # If you set this to True while on the normal network, you won't be able to send or sometimes receive messages.
|
useVeryEasyProofOfWorkForTesting = False # If you set this to True while on the normal network, you won't be able to send or sometimes receive messages.
|
||||||
|
|
||||||
|
|
||||||
# Libraries.
|
# Libraries.
|
||||||
|
@ -391,6 +391,88 @@ def isBitSetWithinBitfield(fourByteString, n):
|
||||||
x, = unpack('>L', fourByteString)
|
x, = unpack('>L', fourByteString)
|
||||||
return x & 2**n != 0
|
return x & 2**n != 0
|
||||||
|
|
||||||
|
def decryptAndCheckPubkeyPayload(payload, address):
|
||||||
|
status, addressVersion, streamNumber, ripe = decodeAddress(address)
|
||||||
|
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
|
||||||
|
addressVersion) + encodeVarint(streamNumber) + ripe).digest()).digest()
|
||||||
|
# this function expects that the nonce is Not included in payload.
|
||||||
|
readPosition = 8 # for the time
|
||||||
|
embeddedVersionNumber, varintLength = decodeVarint(
|
||||||
|
payload[readPosition:readPosition + 10])
|
||||||
|
if embeddedVersionNumber != addressVersion:
|
||||||
|
with shared.printLock:
|
||||||
|
print 'Pubkey decryption was UNsuccessful due to address version mismatch. This shouldn\'t have happened.'
|
||||||
|
return 'failed'
|
||||||
|
readPosition += varintLength
|
||||||
|
embeddedStreamNumber, varintLength = decodeVarint(
|
||||||
|
payload[readPosition:readPosition + 10])
|
||||||
|
if embeddedStreamNumber != streamNumber:
|
||||||
|
with shared.printLock:
|
||||||
|
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.
|
||||||
|
toTag = payload[readPosition:readPosition+32]
|
||||||
|
readPosition += 32 #for the tag
|
||||||
|
encryptedData = payload[readPosition:]
|
||||||
|
# Let us try to decrypt the pubkey
|
||||||
|
privEncryptionKey = doubleHashOfAddressData[:32]
|
||||||
|
cryptorObject = highlevelcrypto.makeCryptor(privEncryptionKey.encode('hex'))
|
||||||
|
try:
|
||||||
|
decryptedData = cryptorObject.decrypt(encryptedData)
|
||||||
|
except:
|
||||||
|
# Someone must have encrypted some data with a different key
|
||||||
|
# but tagged it with a tag for which we are watching.
|
||||||
|
with shared.printLock:
|
||||||
|
print 'Pubkey decryption was UNsuccessful. This shouldn\'t have happened.'
|
||||||
|
return 'failed'
|
||||||
|
print 'Pubkey decryption successful'
|
||||||
|
readPosition = 4 # bypass the behavior bitfield
|
||||||
|
publicSigningKey = '\x04' + decryptedData[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, we should
|
||||||
|
# probably test these keys here.
|
||||||
|
readPosition += 64
|
||||||
|
publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
|
||||||
|
readPosition += 64
|
||||||
|
specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint(
|
||||||
|
decryptedData[readPosition:readPosition + 10])
|
||||||
|
readPosition += specifiedNonceTrialsPerByteLength
|
||||||
|
specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint(
|
||||||
|
decryptedData[readPosition:readPosition + 10])
|
||||||
|
readPosition += specifiedPayloadLengthExtraBytesLength
|
||||||
|
signedData += decryptedData[:readPosition]
|
||||||
|
signatureLength, signatureLengthLength = decodeVarint(
|
||||||
|
decryptedData[readPosition:readPosition + 10])
|
||||||
|
readPosition += signatureLengthLength
|
||||||
|
signature = decryptedData[readPosition:readPosition + signatureLength]
|
||||||
|
try:
|
||||||
|
if not highlevelcrypto.verify(signedData, signature, publicSigningKey.encode('hex')):
|
||||||
|
print 'ECDSA verify failed (within decryptAndCheckPubkeyPayload).'
|
||||||
|
return 'failed'
|
||||||
|
print 'ECDSA verify passed (within decryptAndCheckPubkeyPayload)'
|
||||||
|
except Exception as err:
|
||||||
|
print 'ECDSA verify failed (within decryptAndCheckPubkeyPayload)', err
|
||||||
|
return 'failed'
|
||||||
|
|
||||||
|
sha = hashlib.new('sha512')
|
||||||
|
sha.update(publicSigningKey + publicEncryptionKey)
|
||||||
|
ripeHasher = hashlib.new('ripemd160')
|
||||||
|
ripeHasher.update(sha.digest())
|
||||||
|
embeddedRipe = ripeHasher.digest()
|
||||||
|
|
||||||
|
if embeddedRipe != ripe:
|
||||||
|
# Although this pubkey object had the tag were were looking for and was
|
||||||
|
# encrypted with the correct encryption key, it doesn't contain the
|
||||||
|
# correct keys. Someone is either being malicious or using buggy software.
|
||||||
|
with shared.printLock:
|
||||||
|
print 'Pubkey decryption was UNsuccessful due to RIPE mismatch. This shouldn\'t have happened.'
|
||||||
|
return 'failed'
|
||||||
|
|
||||||
|
t = (ripe, signedData, int(time.time()), 'yes')
|
||||||
|
sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?)''', *t)
|
||||||
|
return 'successful'
|
||||||
|
|
||||||
Peer = collections.namedtuple('Peer', ['host', 'port'])
|
Peer = collections.namedtuple('Peer', ['host', 'port'])
|
||||||
|
|
||||||
helper_startup.loadConfig()
|
helper_startup.loadConfig()
|
||||||
|
|
Reference in New Issue
Block a user