Browse Source

expand the pubkey to include the uuid from the identity...

this is needd to be able to lookup the pubkey...

In testing this, we verified the identity obj, and it
exposed the issue that the ASN1DictCoder doesn't actually
make canonical output (dict keys were not sorted), so fix
this locally...
main
John-Mark Gurney 5 years ago
parent
commit
4ab4553af1
1 changed files with 69 additions and 3 deletions
  1. +69
    -3
      ui/cli.py

+ 69
- 3
ui/cli.py View File

@@ -194,7 +194,18 @@ def _trytodict(o):
except Exception: # pragma: no cover
raise TypeError('unable to find __to_dict__ on %s: %s' % (type(o), `o`))

_asn1coder = pasn1.ASN1DictCoder(coerce=_trytodict)
class CononicalCoder(pasn1.ASN1DictCoder):
def enc_dict(self, obj, **kwargs):
class FakeIter:
def iteritems(self):
itms = obj.items()
itms.sort()

return iter(itms)

return pasn1.ASN1DictCoder.enc_dict(self, FakeIter(), **kwargs)

_asn1coder = CononicalCoder(coerce=_trytodict)

class Persona(object):
'''The object that represents a persona, or identity. It will
@@ -216,6 +227,23 @@ class Persona(object):

self._created_by_ref = self._identity.uuid

def __repr__(self): # pragma: no cover
r = '<Persona: has key: %s, has pubkey: %s, identity: %s>' % \
(self._key is not None, self._pubkey is not None,
`self._identity`)

return r

@classmethod
def from_pubkey(cls, pubkeystr):
pubstr = base58.b58decode_check(pubkeystr)

uuid, pubkey = _asn1coder.loads(pubstr)

ident = Identity(uuid=uuid, pubkey=pubkey)

return cls(ident)

def get_identity(self):
'''Return the Identity object for this Persona.'''

@@ -225,7 +253,10 @@ class Persona(object):
'''Get a printable version of the public key. This is used
for importing into different programs, or for shared.'''

return base58.b58encode_check(self._identity.pubkey)
idobj = self._identity
pubstr = _asn1coder.dumps([ idobj.uuid, idobj.pubkey ])

return base58.b58encode_check(pubstr)

def new_version(self, *args):
'''Update the Persona's Identity object.'''
@@ -300,6 +331,8 @@ class Persona(object):
def verify(self, obj):
sigbytes = self._makesigbytes(obj)

pubkey = self._pubkey.public_bytes(Encoding.Raw,
PublicFormat.Raw)
self._pubkey.verify(obj['sig'], sigbytes)

return True
@@ -551,6 +584,28 @@ def main():
if __name__ == '__main__': # pragma: no cover
main()

class _TestCononicalCoder(unittest.TestCase):
def test_con(self):
obja = { 'foo': 23984732, 'a': 5, 'b': 6, 'something': '2398472398723498273dfasdfjlaksdfj' }
objaitems = obja.items()
objaitems.sort()
objb = dict(objaitems)

self.assertEqual(obja, objb)

# This is to make sure that item order changed
self.assertNotEqual(obja.items(), objb.items())

astr = pasn1.dumps(obja)
bstr = pasn1.dumps(objb)

self.assertNotEqual(astr, bstr)

astr = _asn1coder.dumps(obja)
bstr = _asn1coder.dumps(objb)

self.assertEqual(astr, bstr)

class _TestCases(unittest.TestCase):
def setUp(self):
d = os.path.realpath(tempfile.mkdtemp())
@@ -724,11 +779,22 @@ class _TestCases(unittest.TestCase):
self.assertIsInstance(idobj['pubkey'], str)

# that get_pubkey returns the correct thing
self.assertEqual(persona.get_pubkey(), base58.b58encode_check(idobj['pubkey']))
pubstr = _asn1coder.dumps([ idobj['uuid'], idobj['pubkey'] ])
self.assertEqual(persona.get_pubkey(),
base58.b58encode_check(pubstr))

# and that there is a signature
self.assertIsInstance(idobj['sig'], str)

# and that it can verify itself
persona.verify(idobj)

# and that a new persona can be created from the pubkey
pkpersona = Persona.from_pubkey(persona.get_pubkey())

# and that it can verify the old identity
self.assertTrue(pkpersona.verify(idobj))

# that a second time, it raises an exception
self.assertRaises(RuntimeError, persona.generate_key)



Loading…
Cancel
Save