introducing signed aliases
This commit is contained in:
@@ -588,7 +588,7 @@ class BitcoinGUI:
|
|||||||
r = r.strip()
|
r = r.strip()
|
||||||
if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', r):
|
if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', r):
|
||||||
try:
|
try:
|
||||||
to_address = self.wallet.get_alias(r)
|
to_address = self.wallet.read_alias(r)[0]
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
if to_address:
|
if to_address:
|
||||||
@@ -807,22 +807,43 @@ class BitcoinGUI:
|
|||||||
entry.set_text('')
|
entry.set_text('')
|
||||||
|
|
||||||
|
|
||||||
|
def question(self,msg):
|
||||||
|
dialog = gtk.MessageDialog( self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, msg)
|
||||||
|
dialog.show()
|
||||||
|
result = dialog.run()
|
||||||
|
dialog.destroy()
|
||||||
|
return result == gtk.RESPONSE_OK
|
||||||
|
|
||||||
def get_alias(self, r):
|
def get_alias(self, r):
|
||||||
try:
|
try:
|
||||||
to_address = self.wallet.get_alias(r)
|
target, signing_address, auth_name = self.wallet.read_alias(r)
|
||||||
except BaseException, e:
|
except BaseException, e:
|
||||||
to_address = None
|
# raise exception if verify fails (verify the chain)
|
||||||
msg = "Warning: the key corresponding to %s does not match its previously known value.\nDo you wish to accept the new key?"%r
|
self.show_message("Alias error: " + e.message)
|
||||||
dialog = gtk.MessageDialog( self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, msg)
|
return
|
||||||
dialog.show()
|
|
||||||
result = dialog.run()
|
|
||||||
dialog.destroy()
|
|
||||||
if result != gtk.RESPONSE_CANCEL:
|
|
||||||
print e.message
|
|
||||||
to_address = e.message
|
|
||||||
self.wallet.aliases[r] = to_address
|
|
||||||
|
|
||||||
return to_address
|
if auth_name is None:
|
||||||
|
a = self.wallet.aliases.get(r)
|
||||||
|
if not a:
|
||||||
|
if self.question( "Warning: the alias is self-signed. Do you want to trust address %s ?"%to_address ):
|
||||||
|
self.wallet.aliases[r] = signing_address
|
||||||
|
else:
|
||||||
|
target = None
|
||||||
|
else:
|
||||||
|
if signing_address != a:
|
||||||
|
if self.question( "Warning: the signing key of %s does not match its previously known value! It is possible that someone is trying to do something nasty!!!\nDo you wish to accept the new key?"%r ):
|
||||||
|
self.wallet.aliases[r] = signing_address
|
||||||
|
else:
|
||||||
|
target = None
|
||||||
|
else:
|
||||||
|
if signing_address not in self.wallet.authorities.keys():
|
||||||
|
if self.question( "Warning: the alias '%s' was signed by %s [%s].\n\nDo you want to add this key to your list of trusted keys?"\
|
||||||
|
%(r,auth_name,signing_address)):
|
||||||
|
self.wallet.authorities[signing_address] = auth_name
|
||||||
|
else:
|
||||||
|
target = None
|
||||||
|
|
||||||
|
return target
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -248,6 +248,8 @@ class Wallet:
|
|||||||
self.history = {}
|
self.history = {}
|
||||||
self.labels = {} # labels for addresses and transactions
|
self.labels = {} # labels for addresses and transactions
|
||||||
self.aliases = {} # aliases for addresses
|
self.aliases = {} # aliases for addresses
|
||||||
|
self.authorities = {} # trusted addresses
|
||||||
|
|
||||||
self.receipts = {} # signed URIs
|
self.receipts = {} # signed URIs
|
||||||
self.receipt = None # next receipt
|
self.receipt = None # next receipt
|
||||||
self.addressbook = [] # outgoing addresses, for payments
|
self.addressbook = [] # outgoing addresses, for payments
|
||||||
@@ -383,7 +385,7 @@ class Wallet:
|
|||||||
order = G.order()
|
order = G.order()
|
||||||
# extract r,s from signature
|
# extract r,s from signature
|
||||||
sig = base64.b64decode(signature)
|
sig = base64.b64decode(signature)
|
||||||
if len(sig) != 65: raise BaseException("error")
|
if len(sig) != 65: raise BaseException("Wrong encoding")
|
||||||
r,s = util.sigdecode_string(sig[1:], order)
|
r,s = util.sigdecode_string(sig[1:], order)
|
||||||
recid = ord(sig[0]) - 27
|
recid = ord(sig[0]) - 27
|
||||||
# 1.1
|
# 1.1
|
||||||
@@ -407,7 +409,10 @@ class Wallet:
|
|||||||
# check that we get the original signing address
|
# check that we get the original signing address
|
||||||
addr = public_key_to_bc_address( '04'.decode('hex') + public_key.to_string() )
|
addr = public_key_to_bc_address( '04'.decode('hex') + public_key.to_string() )
|
||||||
# print addr
|
# print addr
|
||||||
assert address == addr
|
try:
|
||||||
|
assert address == addr
|
||||||
|
except:
|
||||||
|
raise BaseException("Bad signature")
|
||||||
|
|
||||||
|
|
||||||
def create_new_address2(self, for_change):
|
def create_new_address2(self, for_change):
|
||||||
@@ -489,6 +494,7 @@ class Wallet:
|
|||||||
'contacts':self.addressbook,
|
'contacts':self.addressbook,
|
||||||
'imported_keys':self.imported_keys,
|
'imported_keys':self.imported_keys,
|
||||||
'aliases':self.aliases,
|
'aliases':self.aliases,
|
||||||
|
'authorities':self.authorities,
|
||||||
'receipts':self.receipts,
|
'receipts':self.receipts,
|
||||||
}
|
}
|
||||||
f = open(self.path,"w")
|
f = open(self.path,"w")
|
||||||
@@ -521,6 +527,7 @@ class Wallet:
|
|||||||
self.addressbook = d.get('contacts')
|
self.addressbook = d.get('contacts')
|
||||||
self.imported_keys = d.get('imported_keys',{})
|
self.imported_keys = d.get('imported_keys',{})
|
||||||
self.aliases = d.get('aliases',{})
|
self.aliases = d.get('aliases',{})
|
||||||
|
self.authorities = d.get('authorities',{})
|
||||||
self.receipts = d.get('receipts',{})
|
self.receipts = d.get('receipts',{})
|
||||||
except:
|
except:
|
||||||
raise BaseException(upgrade_msg)
|
raise BaseException(upgrade_msg)
|
||||||
@@ -724,34 +731,47 @@ class Wallet:
|
|||||||
self.receipt = None
|
self.receipt = None
|
||||||
return True, out
|
return True, out
|
||||||
|
|
||||||
def get_alias(self, x):
|
|
||||||
|
def read_alias(self, alias):
|
||||||
# this might not be the right place for this function.
|
# this might not be the right place for this function.
|
||||||
import urllib
|
import urllib
|
||||||
if self.is_valid(x):
|
if self.is_valid(alias):
|
||||||
return x
|
return alias
|
||||||
else:
|
else:
|
||||||
m1 = re.match('([\w\-\.]+)@((\w[\w\-]+\.)+[\w\-]+)', x)
|
m1 = re.match('([\w\-\.]+)@((\w[\w\-]+\.)+[\w\-]+)', alias)
|
||||||
m2 = re.match('((\w[\w\-]+\.)+[\w\-]+)', x)
|
m2 = re.match('((\w[\w\-]+\.)+[\w\-]+)', alias)
|
||||||
if m1:
|
if m1:
|
||||||
url = 'http://' + m1.group(2) + '/bitcoin.id/' + m1.group(1)
|
url = 'http://' + m1.group(2) + '/bitcoin.id/' + m1.group(1)
|
||||||
elif m2:
|
elif m2:
|
||||||
url = 'http://' + x + '/bitcoin.id'
|
url = 'http://' + alias + '/bitcoin.id'
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
try:
|
try:
|
||||||
print url
|
lines = urllib.urlopen(url).readlines()
|
||||||
xx = urllib.urlopen(url).read().strip()
|
|
||||||
except:
|
except:
|
||||||
return ''
|
return ''
|
||||||
if not self.is_valid(xx):
|
|
||||||
return ''
|
|
||||||
self.labels[xx] = x
|
|
||||||
|
|
||||||
s = self.aliases.get(x)
|
# line 0
|
||||||
if s:
|
line = lines[0].strip().split(':')
|
||||||
if s != xx:
|
if len(line) == 1:
|
||||||
raise BaseException( xx )
|
auth_name = None
|
||||||
|
target = signing_addr = line[0]
|
||||||
else:
|
else:
|
||||||
self.aliases[x] = xx
|
target, auth_name, signing_addr, signature = line
|
||||||
|
msg = "alias:%s:%s:%s"%(alias,target,auth_name)
|
||||||
return xx
|
print msg, signature
|
||||||
|
self.verify_message(signing_addr, signature, msg)
|
||||||
|
|
||||||
|
# other lines are signed updates
|
||||||
|
for line in lines[1:]:
|
||||||
|
line = line.strip()
|
||||||
|
if not line: continue
|
||||||
|
line = line.split(':')
|
||||||
|
previous = target
|
||||||
|
print repr(line)
|
||||||
|
target, signature = line
|
||||||
|
self.verify_message(previous, signature, "alias:%s:%s"%(alias,target))
|
||||||
|
|
||||||
|
assert self.is_valid(target)
|
||||||
|
|
||||||
|
return target, signing_addr, auth_name
|
||||||
|
|||||||
Reference in New Issue
Block a user