summaryrefslogtreecommitdiff
path: root/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'util.py')
-rw-r--r--util.py92
1 files changed, 86 insertions, 6 deletions
diff --git a/util.py b/util.py
index 09bca6b4..2103c056 100644
--- a/util.py
+++ b/util.py
@@ -5,7 +5,40 @@ Utilities for Soledad.
import os
import gnupg
import re
-from gnupg import logger
+from gnupg import (
+ logger,
+ _is_sequence,
+ _make_binary_stream,
+)
+
+
+class ListPackets():
+ """
+ Handle status messages for --list-packets.
+ """
+
+ def __init__(self, gpg):
+ self.gpg = gpg
+ self.nodata = None
+ self.key = None
+ self.need_passphrase = None
+ self.need_passphrase_sym = None
+ self.userid_hint = None
+
+ def handle_status(self, key, value):
+ # TODO: write tests for handle_status
+ if key == 'NODATA':
+ self.nodata = True
+ if key == 'ENC_TO':
+ # This will only capture keys in our keyring. In the future we
+ # may want to include multiple unknown keys in this list.
+ self.key, _, _ = value.split()
+ if key == 'NEED_PASSPHRASE':
+ self.need_passphrase = True
+ if key == 'NEED_PASSPHRASE_SYM':
+ self.need_passphrase_sym = True
+ if key == 'USERID_HINT':
+ self.userid_hint = value.strip().split()
class GPGWrapper(gnupg.GPG):
@@ -17,11 +50,17 @@ class GPGWrapper(gnupg.GPG):
GNUPG_HOME = os.environ['HOME'] + "/.config/leap/gnupg"
GNUPG_BINARY = "/usr/bin/gpg" # this has to be changed based on OS
- def __init__(self, gpghome=GNUPG_HOME, gpgbinary=GNUPG_BINARY):
- super(GPGWrapper, self).__init__(gnupghome=gpghome,
- gpgbinary=gpgbinary)
+ def __init__(self, gpgbinary=GNUPG_BINARY, gnupghome=GNUPG_HOME,
+ verbose=False, use_agent=False, keyring=None, options=None):
+ super(GPGWrapper, self).__init__(gnupghome=gnupghome,
+ gpgbinary=gpgbinary,
+ verbose=verbose,
+ use_agent=use_agent,
+ keyring=keyring,
+ options=options)
+ self.result_map['list-packets'] = ListPackets
- def find_key(self, email):
+ def find_key_by_email(self, email):
"""
Find user's key based on their email.
"""
@@ -29,7 +68,16 @@ class GPGWrapper(gnupg.GPG):
for uid in key['uids']:
if re.search(email, uid):
return key
- raise LookupError("GnuPG public key for %s not found!" % email)
+ raise LookupError("GnuPG public key for email %s not found!" % email)
+
+ def find_key_by_subkey(self, subkey):
+ for key in self.list_keys():
+ for sub in key['subkeys']:
+ #print sub[0]
+ if sub[0] == subkey:
+ return key
+ raise LookupError(
+ "GnuPG public key for subkey %s not found!" % subkey)
def encrypt(self, data, recipient, sign=None, always_trust=True,
passphrase=None, symmetric=False):
@@ -96,3 +144,35 @@ class GPGWrapper(gnupg.GPG):
self._handle_io(args, file, result, passphrase=passphrase, binary=True)
logger.debug('encrypt result: %r', result.data)
return result
+
+ def list_packets(self, raw_data):
+ args = ["--list-packets"]
+ result = self.result_map['list-packets'](self)
+ self._handle_io(
+ args,
+ _make_binary_stream(raw_data, self.encoding),
+ result,
+ )
+ return result
+
+ def encrypted_to(self, raw_data):
+ """
+ Return the key to which raw_data is encrypted to.
+ """
+ # TODO: make this support multiple keys.
+ result = self.list_packets(raw_data)
+ if not result.encrypted_sym:
+ raise LookupError(
+ "Content is not encrypted to a GnuPG key!")
+ return self.find_key_by_subkey(result.key)
+
+ def is_encrypted_sym(self, raw_data):
+ result = self.list_packets(raw_data)
+ return bool(result.need_passphrase_sym)
+
+ def is_encrypted_asym(self, raw_data):
+ result = self.list_packets(raw_data)
+ return bool(result.need_passphrase)
+
+ def is_encrypted(self, raw_data):
+ self.is_encrypted_asym() or self.is_encrypted_sym()