summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2017-10-24 11:53:10 +0200
committerRuben Pollan <meskio@sindominio.net>2017-10-26 18:37:05 +0200
commit5243c7eb4c58a4419da2103af8c1e4004f01053b (patch)
treeb12fcb016fc95ed9a07a5a2501329db8ec2a623d /src
parentd16b25da0962156601615587a612b57b918b0dc6 (diff)
[feat] add fetch key by fingerprint to keymanager
- Resolves: #9023
Diffstat (limited to 'src')
-rw-r--r--src/leap/bitmask/cli/keys.py21
-rw-r--r--src/leap/bitmask/core/dispatcher.py10
-rw-r--r--src/leap/bitmask/core/mail_services.py9
-rw-r--r--src/leap/bitmask/keymanager/__init__.py37
4 files changed, 77 insertions, 0 deletions
diff --git a/src/leap/bitmask/cli/keys.py b/src/leap/bitmask/cli/keys.py
index 82de386..ab73bff 100644
--- a/src/leap/bitmask/cli/keys.py
+++ b/src/leap/bitmask/cli/keys.py
@@ -41,6 +41,7 @@ SUBCOMMANDS:
list List all known keys
export Export a given key
+ fetch Fetch key by fingerprint
insert Insert a key to the key storage
delete Delete a key from the key storage
'''.format(name=command.appname)
@@ -97,6 +98,26 @@ SUBCOMMANDS:
return self._send(self._print_key)
+ def fetch(self, raw_args):
+ parser = argparse.ArgumentParser(
+ description='Bitmask fetch key by fingerprint',
+ prog='%s %s %s' % tuple(sys.argv[:3]))
+ parser.add_argument('-u', '--userid', default='',
+ help='Select the userid of the keyring')
+ parser.add_argument('address', nargs=1,
+ help='email address to pin to the key')
+ parser.add_argument('fingerprint', nargs=1,
+ help='fingerprint to fetch of the key')
+ subargs = parser.parse_args(raw_args)
+
+ userid = subargs.userid
+ if not userid:
+ userid = self.cfg.get('bonafide', 'active', default='')
+ self.data += ['fetch', userid, subargs.address[0],
+ subargs.fingerprint[0]]
+
+ return self._send(self._print_key)
+
def insert(self, raw_args):
parser = argparse.ArgumentParser(
description='Bitmask import key',
diff --git a/src/leap/bitmask/core/dispatcher.py b/src/leap/bitmask/core/dispatcher.py
index 91168d8..f2b3e8c 100644
--- a/src/leap/bitmask/core/dispatcher.py
+++ b/src/leap/bitmask/core/dispatcher.py
@@ -363,6 +363,16 @@ class KeysCmd(SubCommand):
return service.do_export(uid, address, private, fetch_remote)
@register_method('dict')
+ def do_FETCH(self, service, *parts, **kw):
+ if len(parts) < 5:
+ raise ValueError("An email address is needed")
+ uid = parts[2]
+ address = parts[3]
+ fingerprint = parts[4]
+
+ return service.do_fetch(uid, address, fingerprint)
+
+ @register_method('dict')
def do_INSERT(self, service, *parts, **kw):
if len(parts) < 6:
raise ValueError("An email address is needed")
diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py
index 31c2736..23105c7 100644
--- a/src/leap/bitmask/core/mail_services.py
+++ b/src/leap/bitmask/core/mail_services.py
@@ -422,6 +422,15 @@ class KeymanagerService(HookableService):
d.addCallback(lambda key: dict(key))
return d
+ def do_fetch(self, userid, address, fingerprint):
+ km = self._container.get_instance(userid)
+ if km is None:
+ return defer.fail(ValueError("User " + userid + " has no active "
+ "keymanager"))
+ d = km.fetch_key_fingerprint(address, fingerprint)
+ d.addCallback(lambda key: dict(key))
+ return d
+
def do_insert(self, userid, address, rawkey, validation='Fingerprint'):
km = self._container.get_instance(userid)
if km is None:
diff --git a/src/leap/bitmask/keymanager/__init__.py b/src/leap/bitmask/keymanager/__init__.py
index 45b7e58..e3ff3b8 100644
--- a/src/leap/bitmask/keymanager/__init__.py
+++ b/src/leap/bitmask/keymanager/__init__.py
@@ -261,6 +261,43 @@ class KeyManager(object):
d.addCallbacks(key_found, key_not_found)
return d
+ @defer.inlineCallbacks
+ def fetch_key_fingerprint(self, address, fingerprint):
+ """
+ Fetch a key from the key servers by fingerprint.
+
+ It will replace any key assigned to the address in the keyring and have
+ validation level Fingerprint.
+
+ :param address: The address bound to the key.
+ :type address: str
+ :param fingerprint: The fingerprint of the key to fetch.
+ :type fingerprint: str
+
+ :return: A Deferred which fires with an EncryptionKey fetched,
+ or which fails with KeyNotFound if no key was found in the
+ keyserver for this fingerprint.
+ :rtype: Deferred
+ """
+ key_data = yield self._nicknym.fetch_key_with_fingerprint(fingerprint)
+ key, _ = self._openpgp.parse_key(key_data, address)
+ key.validation = ValidationLevels.Fingerprint
+
+ if key.fingerprint != fingerprint:
+ raise keymanager_errors.KeyNotFound("Got wrong fingerprint")
+
+ try:
+ old_key = yield self._openpgp.get_key(address)
+ if old_key.fingerprint == key.fingerprint:
+ key.last_audited_at = old_key.last_audited_at
+ key.encr_used = old_key.encr_used
+ key.sign_used = old_key.sign_used
+ except keymanager_errors.KeyNotFound:
+ pass
+
+ yield self._openpgp.put_key(key)
+ defer.returnValue(key)
+
def get_all_keys(self, private=False):
"""
Return all keys stored in local database.