diff options
Diffstat (limited to 'util.py')
-rw-r--r-- | util.py | 92 |
1 files changed, 86 insertions, 6 deletions
@@ -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() |