Blame lang/python/src/core.py

Packit d7e8d0
# Copyright (C) 2016-2017 g10 Code GmbH
Packit d7e8d0
# Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
Packit d7e8d0
# Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
Packit d7e8d0
#
Packit d7e8d0
#    This library is free software; you can redistribute it and/or
Packit d7e8d0
#    modify it under the terms of the GNU Lesser General Public
Packit d7e8d0
#    License as published by the Free Software Foundation; either
Packit d7e8d0
#    version 2.1 of the License, or (at your option) any later version.
Packit d7e8d0
#
Packit d7e8d0
#    This library is distributed in the hope that it will be useful,
Packit d7e8d0
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d7e8d0
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit d7e8d0
#    Lesser General Public License for more details.
Packit d7e8d0
#
Packit d7e8d0
#    You should have received a copy of the GNU Lesser General Public
Packit d7e8d0
#    License along with this library; if not, write to the Free Software
Packit d7e8d0
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
Packit d7e8d0
Packit d7e8d0
"""Core functionality
Packit d7e8d0
Packit d7e8d0
Core functionality of GPGME wrapped in a object-oriented fashion.
Packit d7e8d0
Provides the 'Context' class for performing cryptographic operations,
Packit d7e8d0
and the 'Data' class describing buffers of data.
Packit d7e8d0
Packit d7e8d0
"""
Packit d7e8d0
Packit d7e8d0
from __future__ import absolute_import, print_function, unicode_literals
Packit d7e8d0
del absolute_import, print_function, unicode_literals
Packit d7e8d0
Packit d7e8d0
import re
Packit d7e8d0
import os
Packit d7e8d0
import warnings
Packit d7e8d0
import weakref
Packit d7e8d0
from . import gpgme
Packit d7e8d0
from .errors import errorcheck, GPGMEError
Packit d7e8d0
from . import constants
Packit d7e8d0
from . import errors
Packit d7e8d0
from . import util
Packit d7e8d0
Packit d7e8d0
class GpgmeWrapper(object):
Packit d7e8d0
    """Base wrapper class
Packit d7e8d0
Packit d7e8d0
    Not to be instantiated directly.
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
Packit d7e8d0
    def __init__(self, wrapped):
Packit d7e8d0
        self._callback_excinfo = None
Packit d7e8d0
        self.wrapped = wrapped
Packit d7e8d0
Packit d7e8d0
    def __repr__(self):
Packit d7e8d0
        return '<{}/{!r}>'.format(super(GpgmeWrapper, self).__repr__(),
Packit d7e8d0
                                  self.wrapped)
Packit d7e8d0
Packit d7e8d0
    def __str__(self):
Packit d7e8d0
        acc = ['{}.{}'.format(__name__, self.__class__.__name__)]
Packit d7e8d0
        flags = [f for f in self._boolean_properties if getattr(self, f)]
Packit d7e8d0
        if flags:
Packit d7e8d0
            acc.append('({})'.format(' '.join(flags)))
Packit d7e8d0
Packit d7e8d0
        return '<{}>'.format(' '.join(acc))
Packit d7e8d0
Packit d7e8d0
    def __hash__(self):
Packit d7e8d0
        return hash(repr(self.wrapped))
Packit d7e8d0
Packit d7e8d0
    def __eq__(self, other):
Packit d7e8d0
        if other == None:
Packit d7e8d0
            return False
Packit d7e8d0
        else:
Packit d7e8d0
            return repr(self.wrapped) == repr(other.wrapped)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def _ctype(self):
Packit d7e8d0
        """The name of the c type wrapped by this class
Packit d7e8d0
Packit d7e8d0
        Must be set by child classes.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        raise NotImplementedError()
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def _cprefix(self):
Packit d7e8d0
        """The common prefix of c functions wrapped by this class
Packit d7e8d0
Packit d7e8d0
        Must be set by child classes.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        raise NotImplementedError()
Packit d7e8d0
Packit d7e8d0
    def _errorcheck(self, name):
Packit d7e8d0
        """Must be implemented by child classes.
Packit d7e8d0
Packit d7e8d0
        This function must return a trueish value for all c functions
Packit d7e8d0
        returning gpgme_error_t."""
Packit d7e8d0
        raise NotImplementedError()
Packit d7e8d0
Packit d7e8d0
    """The set of all boolean properties"""
Packit d7e8d0
    _boolean_properties = set()
Packit d7e8d0
Packit d7e8d0
    def __wrap_boolean_property(self, key, do_set=False, value=None):
Packit d7e8d0
        get_func = getattr(gpgme,
Packit d7e8d0
                           "{}get_{}".format(self._cprefix, key))
Packit d7e8d0
        set_func = getattr(gpgme,
Packit d7e8d0
                           "{}set_{}".format(self._cprefix, key))
Packit d7e8d0
        def get(slf):
Packit d7e8d0
            return bool(get_func(slf.wrapped))
Packit d7e8d0
        def set_(slf, value):
Packit d7e8d0
            set_func(slf.wrapped, bool(value))
Packit d7e8d0
Packit d7e8d0
        p = property(get, set_, doc="{} flag".format(key))
Packit d7e8d0
        setattr(self.__class__, key, p)
Packit d7e8d0
Packit d7e8d0
        if do_set:
Packit d7e8d0
            set_(self, bool(value))
Packit d7e8d0
        else:
Packit d7e8d0
            return get(self)
Packit d7e8d0
Packit d7e8d0
    _munge_docstring = re.compile(r'gpgme_([^(]*)\(([^,]*), (.*\) -> .*)')
Packit d7e8d0
    def __getattr__(self, key):
Packit d7e8d0
        """On-the-fly generation of wrapper methods and properties"""
Packit d7e8d0
        if key[0] == '_' or self._cprefix == None:
Packit d7e8d0
            return None
Packit d7e8d0
Packit d7e8d0
        if key in self._boolean_properties:
Packit d7e8d0
            return self.__wrap_boolean_property(key)
Packit d7e8d0
Packit d7e8d0
        name = self._cprefix + key
Packit d7e8d0
        func = getattr(gpgme, name)
Packit d7e8d0
Packit d7e8d0
        if self._errorcheck(name):
Packit d7e8d0
            def _funcwrap(slf, *args):
Packit d7e8d0
                result = func(slf.wrapped, *args)
Packit d7e8d0
                if slf._callback_excinfo:
Packit d7e8d0
                    gpgme.gpg_raise_callback_exception(slf)
Packit d7e8d0
                return errorcheck(result, name)
Packit d7e8d0
        else:
Packit d7e8d0
            def _funcwrap(slf, *args):
Packit d7e8d0
                result = func(slf.wrapped, *args)
Packit d7e8d0
                if slf._callback_excinfo:
Packit d7e8d0
                    gpgme.gpg_raise_callback_exception(slf)
Packit d7e8d0
                return result
Packit d7e8d0
Packit d7e8d0
        doc = self._munge_docstring.sub(r'\2.\1(\3', getattr(func, "__doc__"))
Packit d7e8d0
        _funcwrap.__doc__ = doc
Packit d7e8d0
Packit d7e8d0
        # Monkey-patch the class.
Packit d7e8d0
        setattr(self.__class__, key, _funcwrap)
Packit d7e8d0
Packit d7e8d0
        # Bind the method to 'self'.
Packit d7e8d0
        def wrapper(*args):
Packit d7e8d0
            return _funcwrap(self, *args)
Packit d7e8d0
        wrapper.__doc__ = doc
Packit d7e8d0
Packit d7e8d0
        return wrapper
Packit d7e8d0
Packit d7e8d0
    def __setattr__(self, key, value):
Packit d7e8d0
        """On-the-fly generation of properties"""
Packit d7e8d0
        if key in self._boolean_properties:
Packit d7e8d0
            self.__wrap_boolean_property(key, True, value)
Packit d7e8d0
        else:
Packit d7e8d0
            super(GpgmeWrapper, self).__setattr__(key, value)
Packit d7e8d0
Packit d7e8d0
class Context(GpgmeWrapper):
Packit d7e8d0
    """Context for cryptographic operations
Packit d7e8d0
Packit d7e8d0
    All cryptographic operations in GPGME are performed within a
Packit d7e8d0
    context, which contains the internal state of the operation as
Packit d7e8d0
    well as configuration parameters.  By using several contexts you
Packit d7e8d0
    can run several cryptographic operations in parallel, with
Packit d7e8d0
    different configuration.
Packit d7e8d0
Packit d7e8d0
    Access to a context must be synchronized.
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
Packit d7e8d0
    def __init__(self, armor=False, textmode=False, offline=False,
Packit d7e8d0
                 signers=[], pinentry_mode=constants.PINENTRY_MODE_DEFAULT,
Packit d7e8d0
                 protocol=constants.PROTOCOL_OpenPGP,
Packit d7e8d0
                 wrapped=None, home_dir=None):
Packit d7e8d0
        """Construct a context object
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        armor		-- enable ASCII armoring (default False)
Packit d7e8d0
        textmode	-- enable canonical text mode (default False)
Packit d7e8d0
        offline		-- do not contact external key sources (default False)
Packit d7e8d0
        signers		-- list of keys used for signing (default [])
Packit d7e8d0
        pinentry_mode	-- pinentry mode (default PINENTRY_MODE_DEFAULT)
Packit d7e8d0
        protocol	-- protocol to use (default PROTOCOL_OpenPGP)
Packit d7e8d0
        home_dir        -- state directory (default is the engine default)
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if wrapped:
Packit d7e8d0
            self.own = False
Packit d7e8d0
        else:
Packit d7e8d0
            tmp = gpgme.new_gpgme_ctx_t_p()
Packit d7e8d0
            errorcheck(gpgme.gpgme_new(tmp))
Packit d7e8d0
            wrapped = gpgme.gpgme_ctx_t_p_value(tmp)
Packit d7e8d0
            gpgme.delete_gpgme_ctx_t_p(tmp)
Packit d7e8d0
            self.own = True
Packit d7e8d0
        super(Context, self).__init__(wrapped)
Packit d7e8d0
        self.armor = armor
Packit d7e8d0
        self.textmode = textmode
Packit d7e8d0
        self.offline = offline
Packit d7e8d0
        self.signers = signers
Packit d7e8d0
        self.pinentry_mode = pinentry_mode
Packit d7e8d0
        self.protocol = protocol
Packit d7e8d0
        self.home_dir = home_dir
Packit d7e8d0
Packit d7e8d0
    def __read__(self, sink, data):
Packit d7e8d0
        """Read helper
Packit d7e8d0
Packit d7e8d0
        Helper function to retrieve the results of an operation, or
Packit d7e8d0
        None if SINK is given.
Packit d7e8d0
        """
Packit d7e8d0
        if sink or data == None:
Packit d7e8d0
            return None
Packit d7e8d0
        data.seek(0, os.SEEK_SET)
Packit d7e8d0
        return data.read()
Packit d7e8d0
Packit d7e8d0
    def __repr__(self):
Packit d7e8d0
        return (
Packit d7e8d0
            "Context(armor={0.armor}, "
Packit d7e8d0
            "textmode={0.textmode}, offline={0.offline}, "
Packit d7e8d0
            "signers={0.signers}, pinentry_mode={0.pinentry_mode}, "
Packit d7e8d0
            "protocol={0.protocol}, home_dir={0.home_dir}"
Packit d7e8d0
            ")").format(self)
Packit d7e8d0
Packit d7e8d0
    def encrypt(self, plaintext, recipients=[], sign=True, sink=None,
Packit d7e8d0
                passphrase=None, always_trust=False, add_encrypt_to=False,
Packit d7e8d0
                prepare=False, expect_sign=False, compress=True):
Packit d7e8d0
        """Encrypt data
Packit d7e8d0
Packit d7e8d0
        Encrypt the given plaintext for the given recipients.  If the
Packit d7e8d0
        list of recipients is empty, the data is encrypted
Packit d7e8d0
        symmetrically with a passphrase.
Packit d7e8d0
Packit d7e8d0
        The passphrase can be given as parameter, using a callback
Packit d7e8d0
        registered at the context, or out-of-band via pinentry.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        recipients	-- list of keys to encrypt to
Packit d7e8d0
        sign		-- sign plaintext (default True)
Packit d7e8d0
        sink		-- write result to sink instead of returning it
Packit d7e8d0
        passphrase	-- for symmetric encryption
Packit d7e8d0
        always_trust	-- always trust the keys (default False)
Packit d7e8d0
        add_encrypt_to	-- encrypt to configured additional keys (default False)
Packit d7e8d0
        prepare		-- (ui) prepare for encryption (default False)
Packit d7e8d0
        expect_sign	-- (ui) prepare for signing (default False)
Packit d7e8d0
        compress	-- compress plaintext (default True)
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
        ciphertext	-- the encrypted data (or None if sink is given)
Packit d7e8d0
        result		-- additional information about the encryption
Packit d7e8d0
        sign_result	-- additional information about the signature(s)
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        InvalidRecipients -- if encryption using a particular key failed
Packit d7e8d0
        InvalidSigners	-- if signing using a particular key failed
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        ciphertext = sink if sink else Data()
Packit d7e8d0
        flags = 0
Packit d7e8d0
        flags |= always_trust * constants.ENCRYPT_ALWAYS_TRUST
Packit d7e8d0
        flags |= (not add_encrypt_to) * constants.ENCRYPT_NO_ENCRYPT_TO
Packit d7e8d0
        flags |= prepare * constants.ENCRYPT_PREPARE
Packit d7e8d0
        flags |= expect_sign * constants.ENCRYPT_EXPECT_SIGN
Packit d7e8d0
        flags |= (not compress) * constants.ENCRYPT_NO_COMPRESS
Packit d7e8d0
Packit d7e8d0
        if passphrase != None:
Packit d7e8d0
            old_pinentry_mode = self.pinentry_mode
Packit d7e8d0
            old_passphrase_cb = getattr(self, '_passphrase_cb', None)
Packit d7e8d0
            self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
Packit d7e8d0
            def passphrase_cb(hint, desc, prev_bad, hook=None):
Packit d7e8d0
                return passphrase
Packit d7e8d0
            self.set_passphrase_cb(passphrase_cb)
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            if sign:
Packit d7e8d0
                self.op_encrypt_sign(recipients, flags, plaintext, ciphertext)
Packit d7e8d0
            else:
Packit d7e8d0
                self.op_encrypt(recipients, flags, plaintext, ciphertext)
Packit d7e8d0
        except errors.GPGMEError as e:
Packit d7e8d0
            result = self.op_encrypt_result()
Packit d7e8d0
            sig_result = self.op_sign_result() if sign else None
Packit d7e8d0
            results = (self.__read__(sink, ciphertext),
Packit d7e8d0
                       result, sig_result)
Packit d7e8d0
            if e.getcode() == errors.UNUSABLE_PUBKEY:
Packit d7e8d0
                if result.invalid_recipients:
Packit d7e8d0
                    raise errors.InvalidRecipients(result.invalid_recipients,
Packit d7e8d0
                                                   error=e.error,
Packit d7e8d0
                                                   results=results)
Packit d7e8d0
            if e.getcode() == errors.UNUSABLE_SECKEY:
Packit d7e8d0
                sig_result = self.op_sign_result()
Packit d7e8d0
                if sig_result.invalid_signers:
Packit d7e8d0
                    raise errors.InvalidSigners(sig_result.invalid_signers,
Packit d7e8d0
                                                error=e.error,
Packit d7e8d0
                                                results=results)
Packit d7e8d0
            # Otherwise, just raise the error, but attach the results
Packit d7e8d0
            # first.
Packit d7e8d0
            e.results = results
Packit d7e8d0
            raise e
Packit d7e8d0
        finally:
Packit d7e8d0
            if passphrase != None:
Packit d7e8d0
                self.pinentry_mode = old_pinentry_mode
Packit d7e8d0
                if old_passphrase_cb:
Packit d7e8d0
                    self.set_passphrase_cb(*old_passphrase_cb[1:])
Packit d7e8d0
Packit d7e8d0
        result = self.op_encrypt_result()
Packit d7e8d0
        assert not result.invalid_recipients
Packit d7e8d0
        sig_result = self.op_sign_result() if sign else None
Packit d7e8d0
        assert not sig_result or not sig_result.invalid_signers
Packit d7e8d0
Packit d7e8d0
        return self.__read__(sink, ciphertext), result, sig_result
Packit d7e8d0
Packit d7e8d0
    def decrypt(self, ciphertext, sink=None, passphrase=None, verify=True):
Packit d7e8d0
        """Decrypt data
Packit d7e8d0
Packit d7e8d0
        Decrypt the given ciphertext and verify any signatures.  If
Packit d7e8d0
        VERIFY is an iterable of keys, the ciphertext must be signed
Packit d7e8d0
        by all those keys, otherwise an error is raised.
Packit d7e8d0
Packit d7e8d0
        If the ciphertext is symmetrically encrypted using a
Packit d7e8d0
        passphrase, that passphrase can be given as parameter, using a
Packit d7e8d0
        callback registered at the context, or out-of-band via
Packit d7e8d0
        pinentry.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        sink		-- write result to sink instead of returning it
Packit d7e8d0
        passphrase	-- for symmetric decryption
Packit d7e8d0
        verify		-- check signatures (default True)
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
        plaintext	-- the decrypted data (or None if sink is given)
Packit d7e8d0
        result		-- additional information about the decryption
Packit d7e8d0
        verify_result	-- additional information about the signature(s)
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        UnsupportedAlgorithm -- if an unsupported algorithm was used
Packit d7e8d0
        BadSignatures	-- if a bad signature is encountered
Packit d7e8d0
        MissingSignatures -- if expected signatures are missing or bad
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        plaintext = sink if sink else Data()
Packit d7e8d0
Packit d7e8d0
        if passphrase != None:
Packit d7e8d0
            old_pinentry_mode = self.pinentry_mode
Packit d7e8d0
            old_passphrase_cb = getattr(self, '_passphrase_cb', None)
Packit d7e8d0
            self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
Packit d7e8d0
            def passphrase_cb(hint, desc, prev_bad, hook=None):
Packit d7e8d0
                return passphrase
Packit d7e8d0
            self.set_passphrase_cb(passphrase_cb)
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            if verify:
Packit d7e8d0
                self.op_decrypt_verify(ciphertext, plaintext)
Packit d7e8d0
            else:
Packit d7e8d0
                self.op_decrypt(ciphertext, plaintext)
Packit d7e8d0
        except errors.GPGMEError as e:
Packit d7e8d0
            result = self.op_decrypt_result()
Packit d7e8d0
            verify_result = self.op_verify_result() if verify else None
Packit d7e8d0
            # Just raise the error, but attach the results first.
Packit d7e8d0
            e.results = (self.__read__(sink, plaintext),
Packit d7e8d0
                         result, verify_result)
Packit d7e8d0
            raise e
Packit d7e8d0
        finally:
Packit d7e8d0
            if passphrase != None:
Packit d7e8d0
                self.pinentry_mode = old_pinentry_mode
Packit d7e8d0
                if old_passphrase_cb:
Packit d7e8d0
                    self.set_passphrase_cb(*old_passphrase_cb[1:])
Packit d7e8d0
Packit d7e8d0
        result = self.op_decrypt_result()
Packit d7e8d0
        verify_result = self.op_verify_result() if verify else None
Packit d7e8d0
        results = (self.__read__(sink, plaintext), result, verify_result)
Packit d7e8d0
        if result.unsupported_algorithm:
Packit d7e8d0
            raise errors.UnsupportedAlgorithm(result.unsupported_algorithm,
Packit d7e8d0
                                              results=results)
Packit d7e8d0
Packit d7e8d0
        if verify:
Packit d7e8d0
            if any(s.status != errors.NO_ERROR
Packit d7e8d0
                   for s in verify_result.signatures):
Packit d7e8d0
                raise errors.BadSignatures(verify_result, results=results)
Packit d7e8d0
Packit d7e8d0
        if verify and verify != True:
Packit d7e8d0
            missing = list()
Packit d7e8d0
            for key in verify:
Packit d7e8d0
                ok = False
Packit d7e8d0
                for subkey in key.subkeys:
Packit d7e8d0
                    for sig in verify_result.signatures:
Packit d7e8d0
                        if sig.summary & constants.SIGSUM_VALID == 0:
Packit d7e8d0
                            continue
Packit d7e8d0
                        if subkey.can_sign and subkey.fpr == sig.fpr:
Packit d7e8d0
                            ok = True
Packit d7e8d0
                            break
Packit d7e8d0
                    if ok:
Packit d7e8d0
                        break
Packit d7e8d0
                if not ok:
Packit d7e8d0
                    missing.append(key)
Packit d7e8d0
            if missing:
Packit d7e8d0
                raise errors.MissingSignatures(verify_result, missing,
Packit d7e8d0
                                               results=results)
Packit d7e8d0
Packit d7e8d0
        return results
Packit d7e8d0
Packit d7e8d0
    def sign(self, data, sink=None, mode=constants.SIG_MODE_NORMAL):
Packit d7e8d0
        """Sign data
Packit d7e8d0
Packit d7e8d0
        Sign the given data with either the configured default local
Packit d7e8d0
        key, or the 'signers' keys of this context.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        mode		-- signature mode (default: normal, see below)
Packit d7e8d0
        sink		-- write result to sink instead of returning it
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
        either
Packit d7e8d0
          signed_data	-- encoded data and signature (normal mode)
Packit d7e8d0
          signature	-- only the signature data (detached mode)
Packit d7e8d0
          cleartext	-- data and signature as text (cleartext mode)
Packit d7e8d0
            (or None if sink is given)
Packit d7e8d0
        result		-- additional information about the signature(s)
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        InvalidSigners	-- if signing using a particular key failed
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        signeddata = sink if sink else Data()
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            self.op_sign(data, signeddata, mode)
Packit d7e8d0
        except errors.GPGMEError as e:
Packit d7e8d0
            results = (self.__read__(sink, signeddata),
Packit d7e8d0
                       self.op_sign_result())
Packit d7e8d0
            if e.getcode() == errors.UNUSABLE_SECKEY:
Packit d7e8d0
                if results[1].invalid_signers:
Packit d7e8d0
                    raise errors.InvalidSigners(results[1].invalid_signers,
Packit d7e8d0
                                                error=e.error,
Packit d7e8d0
                                                results=results)
Packit d7e8d0
            e.results = results
Packit d7e8d0
            raise e
Packit d7e8d0
Packit d7e8d0
        result = self.op_sign_result()
Packit d7e8d0
        assert not result.invalid_signers
Packit d7e8d0
Packit d7e8d0
        return self.__read__(sink, signeddata), result
Packit d7e8d0
Packit d7e8d0
    def verify(self, signed_data, signature=None, sink=None, verify=[]):
Packit d7e8d0
        """Verify signatures
Packit d7e8d0
Packit d7e8d0
        Verify signatures over data.  If VERIFY is an iterable of
Packit d7e8d0
        keys, the ciphertext must be signed by all those keys,
Packit d7e8d0
        otherwise an error is raised.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        signature	-- detached signature data
Packit d7e8d0
        sink		-- write result to sink instead of returning it
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
        data		-- the plain data
Packit d7e8d0
            (or None if sink is given, or we verified a detached signature)
Packit d7e8d0
        result		-- additional information about the signature(s)
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        BadSignatures	-- if a bad signature is encountered
Packit d7e8d0
        MissingSignatures -- if expected signatures are missing or bad
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if signature:
Packit d7e8d0
            # Detached signature, we don't return the plain text.
Packit d7e8d0
            data = None
Packit d7e8d0
        else:
Packit d7e8d0
            data = sink if sink else Data()
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            if signature:
Packit d7e8d0
                self.op_verify(signature, signed_data, None)
Packit d7e8d0
            else:
Packit d7e8d0
                self.op_verify(signed_data, None, data)
Packit d7e8d0
        except errors.GPGMEError as e:
Packit d7e8d0
            # Just raise the error, but attach the results first.
Packit d7e8d0
            e.results = (self.__read__(sink, data),
Packit d7e8d0
                         self.op_verify_result())
Packit d7e8d0
            raise e
Packit d7e8d0
Packit d7e8d0
        results = (self.__read__(sink, data), self.op_verify_result())
Packit d7e8d0
        if any(s.status != errors.NO_ERROR for s in results[1].signatures):
Packit d7e8d0
            raise errors.BadSignatures(results[1], results=results)
Packit d7e8d0
Packit d7e8d0
        missing = list()
Packit d7e8d0
        for key in verify:
Packit d7e8d0
            ok = False
Packit d7e8d0
            for subkey in key.subkeys:
Packit d7e8d0
                for sig in results[1].signatures:
Packit d7e8d0
                    if sig.summary & constants.SIGSUM_VALID == 0:
Packit d7e8d0
                        continue
Packit d7e8d0
                    if subkey.can_sign and subkey.fpr == sig.fpr:
Packit d7e8d0
                        ok = True
Packit d7e8d0
                        break
Packit d7e8d0
                if ok:
Packit d7e8d0
                    break
Packit d7e8d0
            if not ok:
Packit d7e8d0
                missing.append(key)
Packit d7e8d0
        if missing:
Packit d7e8d0
            raise errors.MissingSignatures(results[1], missing,
Packit d7e8d0
                                           results=results)
Packit d7e8d0
Packit d7e8d0
        return results
Packit d7e8d0
Packit d7e8d0
    def keylist(self, pattern=None, secret=False,
Packit d7e8d0
                mode=constants.keylist.mode.LOCAL,
Packit d7e8d0
                source=None):
Packit d7e8d0
        """List keys
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        pattern	-- return keys matching pattern (default: all keys)
Packit d7e8d0
        secret	-- return only secret keys (default: False)
Packit d7e8d0
        mode    -- keylist mode (default: list local keys)
Packit d7e8d0
        source  -- read keys from source instead from the keyring
Packit d7e8d0
                       (all other options are ignored in this case)
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
                -- an iterator returning key objects
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
        """
Packit d7e8d0
        if not source:
Packit d7e8d0
            self.set_keylist_mode(mode)
Packit d7e8d0
            self.op_keylist_start(pattern, secret)
Packit d7e8d0
        else:
Packit d7e8d0
            # Automatic wrapping of SOURCE is not possible here,
Packit d7e8d0
            # because the object must not be deallocated until the
Packit d7e8d0
            # iteration over the results ends.
Packit d7e8d0
            if not isinstance(source, Data):
Packit d7e8d0
                source = Data(file=source)
Packit d7e8d0
            self.op_keylist_from_data_start(source, 0)
Packit d7e8d0
Packit d7e8d0
        key = self.op_keylist_next()
Packit d7e8d0
        while key:
Packit d7e8d0
            yield key
Packit d7e8d0
            key = self.op_keylist_next()
Packit d7e8d0
        self.op_keylist_end()
Packit d7e8d0
Packit d7e8d0
    def create_key(self, userid, algorithm=None, expires_in=0, expires=True,
Packit d7e8d0
                   sign=False, encrypt=False, certify=False, authenticate=False,
Packit d7e8d0
                   passphrase=None, force=False):
Packit d7e8d0
        """Create a primary key
Packit d7e8d0
Packit d7e8d0
        Create a primary key for the user id USERID.
Packit d7e8d0
Packit d7e8d0
        ALGORITHM may be used to specify the public key encryption
Packit d7e8d0
        algorithm for the new key.  By default, a reasonable default
Packit d7e8d0
        is chosen.  You may use "future-default" to select an
Packit d7e8d0
        algorithm that will be the default in a future implementation
Packit d7e8d0
        of the engine.  ALGORITHM may be a string like "rsa", or
Packit d7e8d0
        "rsa2048" to explicitly request an algorithm and a key size.
Packit d7e8d0
Packit d7e8d0
        EXPIRES_IN specifies the expiration time of the key in number
Packit d7e8d0
        of seconds since the keys creation.  By default, a reasonable
Packit d7e8d0
        expiration time is chosen.  If you want to create a key that
Packit d7e8d0
        does not expire, use the keyword argument EXPIRES.
Packit d7e8d0
Packit d7e8d0
        SIGN, ENCRYPT, CERTIFY, and AUTHENTICATE can be used to
Packit d7e8d0
        request the capabilities of the new key.  If you don't request
Packit d7e8d0
        any, a reasonable set of capabilities is selected, and in case
Packit d7e8d0
        of OpenPGP, a subkey with a reasonable set of capabilities is
Packit d7e8d0
        created.
Packit d7e8d0
Packit d7e8d0
        If PASSPHRASE is None (the default), then the key will not be
Packit d7e8d0
        protected with a passphrase.  If PASSPHRASE is a string, it
Packit d7e8d0
        will be used to protect the key.  If PASSPHRASE is True, the
Packit d7e8d0
        passphrase must be supplied using a passphrase callback or
Packit d7e8d0
        out-of-band with a pinentry.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        algorithm    -- public key algorithm, see above (default: reasonable)
Packit d7e8d0
        expires_in   -- expiration time in seconds (default: reasonable)
Packit d7e8d0
        expires      -- whether or not the key should expire (default: True)
Packit d7e8d0
        sign         -- request the signing capability (see above)
Packit d7e8d0
        encrypt      -- request the encryption capability (see above)
Packit d7e8d0
        certify      -- request the certification capability (see above)
Packit d7e8d0
        authenticate -- request the authentication capability (see above)
Packit d7e8d0
        passphrase   -- protect the key with a passphrase (default: no passphrase)
Packit d7e8d0
        force        -- force key creation even if a key with the same userid exists
Packit d7e8d0
                                                          (default: False)
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
                     -- an object describing the result of the key creation
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError   -- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if util.is_a_string(passphrase):
Packit d7e8d0
            old_pinentry_mode = self.pinentry_mode
Packit d7e8d0
            old_passphrase_cb = getattr(self, '_passphrase_cb', None)
Packit d7e8d0
            self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
Packit d7e8d0
            def passphrase_cb(hint, desc, prev_bad, hook=None):
Packit d7e8d0
                return passphrase
Packit d7e8d0
            self.set_passphrase_cb(passphrase_cb)
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            self.op_createkey(userid, algorithm,
Packit d7e8d0
                              0, # reserved
Packit d7e8d0
                              expires_in,
Packit d7e8d0
                              None, # extrakey
Packit d7e8d0
                              ((constants.create.SIGN if sign else 0)
Packit d7e8d0
                               | (constants.create.ENCR if encrypt else 0)
Packit d7e8d0
                               | (constants.create.CERT if certify else 0)
Packit d7e8d0
                               | (constants.create.AUTH if authenticate else 0)
Packit d7e8d0
                               | (constants.create.NOPASSWD if passphrase == None else 0)
Packit d7e8d0
                               | (0 if expires else constants.create.NOEXPIRE)
Packit d7e8d0
                               | (constants.create.FORCE if force else 0)))
Packit d7e8d0
        finally:
Packit d7e8d0
            if util.is_a_string(passphrase):
Packit d7e8d0
                self.pinentry_mode = old_pinentry_mode
Packit d7e8d0
                if old_passphrase_cb:
Packit d7e8d0
                    self.set_passphrase_cb(*old_passphrase_cb[1:])
Packit d7e8d0
Packit d7e8d0
        return self.op_genkey_result()
Packit d7e8d0
Packit d7e8d0
    def create_subkey(self, key, algorithm=None, expires_in=0, expires=True,
Packit d7e8d0
                      sign=False, encrypt=False, authenticate=False, passphrase=None):
Packit d7e8d0
        """Create a subkey
Packit d7e8d0
Packit d7e8d0
        Create a subkey for the given KEY.  As subkeys are a concept
Packit d7e8d0
        of OpenPGP, calling this is only valid for the OpenPGP
Packit d7e8d0
        protocol.
Packit d7e8d0
Packit d7e8d0
        ALGORITHM may be used to specify the public key encryption
Packit d7e8d0
        algorithm for the new subkey.  By default, a reasonable
Packit d7e8d0
        default is chosen.  You may use "future-default" to select an
Packit d7e8d0
        algorithm that will be the default in a future implementation
Packit d7e8d0
        of the engine.  ALGORITHM may be a string like "rsa", or
Packit d7e8d0
        "rsa2048" to explicitly request an algorithm and a key size.
Packit d7e8d0
Packit d7e8d0
        EXPIRES_IN specifies the expiration time of the subkey in
Packit d7e8d0
        number of seconds since the subkeys creation.  By default, a
Packit d7e8d0
        reasonable expiration time is chosen.  If you want to create a
Packit d7e8d0
        subkey that does not expire, use the keyword argument EXPIRES.
Packit d7e8d0
Packit d7e8d0
        SIGN, ENCRYPT, and AUTHENTICATE can be used to request the
Packit d7e8d0
        capabilities of the new subkey.  If you don't request any, an
Packit d7e8d0
        encryption subkey is generated.
Packit d7e8d0
Packit d7e8d0
        If PASSPHRASE is None (the default), then the subkey will not
Packit d7e8d0
        be protected with a passphrase.  If PASSPHRASE is a string, it
Packit d7e8d0
        will be used to protect the subkey.  If PASSPHRASE is True,
Packit d7e8d0
        the passphrase must be supplied using a passphrase callback or
Packit d7e8d0
        out-of-band with a pinentry.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        algorithm    -- public key algorithm, see above (default: reasonable)
Packit d7e8d0
        expires_in   -- expiration time in seconds (default: reasonable)
Packit d7e8d0
        expires      -- whether or not the subkey should expire (default: True)
Packit d7e8d0
        sign         -- request the signing capability (see above)
Packit d7e8d0
        encrypt      -- request the encryption capability (see above)
Packit d7e8d0
        authenticate -- request the authentication capability (see above)
Packit d7e8d0
        passphrase   -- protect the subkey with a passphrase (default: no passphrase)
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
                     -- an object describing the result of the subkey creation
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError   -- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if util.is_a_string(passphrase):
Packit d7e8d0
            old_pinentry_mode = self.pinentry_mode
Packit d7e8d0
            old_passphrase_cb = getattr(self, '_passphrase_cb', None)
Packit d7e8d0
            self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
Packit d7e8d0
            def passphrase_cb(hint, desc, prev_bad, hook=None):
Packit d7e8d0
                return passphrase
Packit d7e8d0
            self.set_passphrase_cb(passphrase_cb)
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            self.op_createsubkey(key, algorithm,
Packit d7e8d0
                                 0, # reserved
Packit d7e8d0
                                 expires_in,
Packit d7e8d0
                                 ((constants.create.SIGN if sign else 0)
Packit d7e8d0
                                  | (constants.create.ENCR if encrypt else 0)
Packit d7e8d0
                                  | (constants.create.AUTH if authenticate else 0)
Packit d7e8d0
                                  | (constants.create.NOPASSWD
Packit d7e8d0
                                     if passphrase == None else 0)
Packit d7e8d0
                                  | (0 if expires else constants.create.NOEXPIRE)))
Packit d7e8d0
        finally:
Packit d7e8d0
            if util.is_a_string(passphrase):
Packit d7e8d0
                self.pinentry_mode = old_pinentry_mode
Packit d7e8d0
                if old_passphrase_cb:
Packit d7e8d0
                    self.set_passphrase_cb(*old_passphrase_cb[1:])
Packit d7e8d0
Packit d7e8d0
        return self.op_genkey_result()
Packit d7e8d0
Packit d7e8d0
    def key_add_uid(self, key, uid):
Packit d7e8d0
        """Add a UID
Packit d7e8d0
Packit d7e8d0
        Add the uid UID to the given KEY.  Calling this function is
Packit d7e8d0
        only valid for the OpenPGP protocol.
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError   -- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        self.op_adduid(key, uid, 0)
Packit d7e8d0
Packit d7e8d0
    def key_revoke_uid(self, key, uid):
Packit d7e8d0
        """Revoke a UID
Packit d7e8d0
Packit d7e8d0
        Revoke the uid UID from the given KEY.  Calling this function
Packit d7e8d0
        is only valid for the OpenPGP protocol.
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError   -- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        self.op_revuid(key, uid, 0)
Packit d7e8d0
Packit d7e8d0
    def key_sign(self, key, uids=None, expires_in=False, local=False):
Packit d7e8d0
        """Sign a key
Packit d7e8d0
Packit d7e8d0
        Sign a key with the current set of signing keys.  Calling this
Packit d7e8d0
        function is only valid for the OpenPGP protocol.
Packit d7e8d0
Packit d7e8d0
        If UIDS is None (the default), then all UIDs are signed.  If
Packit d7e8d0
        it is a string, then only the matching UID is signed.  If it
Packit d7e8d0
        is a list of strings, then all matching UIDs are signed.  Note
Packit d7e8d0
        that a case-sensitive exact string comparison is done.
Packit d7e8d0
Packit d7e8d0
        EXPIRES_IN specifies the expiration time of the signature in
Packit d7e8d0
        seconds.  If EXPIRES_IN is False, the signature does not
Packit d7e8d0
        expire.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        uids         -- user ids to sign, see above (default: sign all)
Packit d7e8d0
        expires_in   -- validity period of the signature in seconds
Packit d7e8d0
                                               (default: do not expire)
Packit d7e8d0
        local        -- create a local, non-exportable signature
Packit d7e8d0
                                               (default: False)
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError   -- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        flags = 0
Packit d7e8d0
        if uids == None or util.is_a_string(uids):
Packit d7e8d0
            pass#through unchanged
Packit d7e8d0
        else:
Packit d7e8d0
            flags |= constants.keysign.LFSEP
Packit d7e8d0
            uids = "\n".join(uids)
Packit d7e8d0
Packit d7e8d0
        if not expires_in:
Packit d7e8d0
            flags |= constants.keysign.NOEXPIRE
Packit d7e8d0
Packit d7e8d0
        if local:
Packit d7e8d0
            flags |= constants.keysign.LOCAL
Packit d7e8d0
Packit d7e8d0
        self.op_keysign(key, uids, expires_in, flags)
Packit d7e8d0
Packit d7e8d0
    def key_tofu_policy(self, key, policy):
Packit d7e8d0
        """Set a keys' TOFU policy
Packit d7e8d0
Packit d7e8d0
        Set the TOFU policy associated with KEY to POLICY.  Calling
Packit d7e8d0
        this function is only valid for the OpenPGP protocol.
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError   -- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        self.op_tofu_policy(key, policy)
Packit d7e8d0
Packit d7e8d0
    def assuan_transact(self, command,
Packit d7e8d0
                        data_cb=None, inquire_cb=None, status_cb=None):
Packit d7e8d0
        """Issue a raw assuan command
Packit d7e8d0
Packit d7e8d0
        This function can be used to issue a raw assuan command to the
Packit d7e8d0
        engine.
Packit d7e8d0
Packit d7e8d0
        If command is a string or bytes, it will be used as-is.  If it
Packit d7e8d0
        is an iterable of strings, it will be properly escaped and
Packit d7e8d0
        joined into an well-formed assuan command.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        data_cb		-- a callback receiving data lines
Packit d7e8d0
        inquire_cb	-- a callback providing more information
Packit d7e8d0
        status_cb	-- a callback receiving status lines
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
        result		-- the result of command as GPGMEError
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
Packit d7e8d0
        if util.is_a_string(command) or isinstance(command, bytes):
Packit d7e8d0
            cmd = command
Packit d7e8d0
        else:
Packit d7e8d0
            cmd = " ".join(util.percent_escape(f) for f in command)
Packit d7e8d0
Packit d7e8d0
        errptr = gpgme.new_gpgme_error_t_p()
Packit d7e8d0
Packit d7e8d0
        err = gpgme.gpgme_op_assuan_transact_ext(
Packit d7e8d0
            self.wrapped,
Packit d7e8d0
            cmd,
Packit d7e8d0
            (weakref.ref(self), data_cb) if data_cb else None,
Packit d7e8d0
            (weakref.ref(self), inquire_cb) if inquire_cb else None,
Packit d7e8d0
            (weakref.ref(self), status_cb) if status_cb else None,
Packit d7e8d0
            errptr)
Packit d7e8d0
Packit d7e8d0
        if self._callback_excinfo:
Packit d7e8d0
            gpgme.gpg_raise_callback_exception(self)
Packit d7e8d0
Packit d7e8d0
        errorcheck(err)
Packit d7e8d0
Packit d7e8d0
        status = gpgme.gpgme_error_t_p_value(errptr)
Packit d7e8d0
        gpgme.delete_gpgme_error_t_p(errptr)
Packit d7e8d0
Packit d7e8d0
        return GPGMEError(status) if status != 0 else None
Packit d7e8d0
Packit d7e8d0
    def interact(self, key, func, sink=None, flags=0, fnc_value=None):
Packit d7e8d0
        """Interact with the engine
Packit d7e8d0
Packit d7e8d0
        This method can be used to edit keys and cards interactively.
Packit d7e8d0
        KEY is the key to edit, FUNC is called repeatedly with two
Packit d7e8d0
        unicode arguments, 'keyword' and 'args'.  See the GPGME manual
Packit d7e8d0
        for details.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        sink		-- if given, additional output is written here
Packit d7e8d0
        flags		-- use constants.INTERACT_CARD to edit a card
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if key == None:
Packit d7e8d0
            raise ValueError("First argument cannot be None")
Packit d7e8d0
Packit d7e8d0
        if sink == None:
Packit d7e8d0
            sink = Data()
Packit d7e8d0
Packit d7e8d0
        if fnc_value:
Packit d7e8d0
            opaquedata = (weakref.ref(self), func, fnc_value)
Packit d7e8d0
        else:
Packit d7e8d0
            opaquedata = (weakref.ref(self), func)
Packit d7e8d0
Packit d7e8d0
        result = gpgme.gpgme_op_interact(self.wrapped, key, flags,
Packit d7e8d0
                                         opaquedata, sink)
Packit d7e8d0
        if self._callback_excinfo:
Packit d7e8d0
            gpgme.gpg_raise_callback_exception(self)
Packit d7e8d0
        errorcheck(result)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def signers(self):
Packit d7e8d0
        """Keys used for signing"""
Packit d7e8d0
        return [self.signers_enum(i) for i in range(self.signers_count())]
Packit d7e8d0
    @signers.setter
Packit d7e8d0
    def signers(self, signers):
Packit d7e8d0
        old = self.signers
Packit d7e8d0
        self.signers_clear()
Packit d7e8d0
        try:
Packit d7e8d0
            for key in signers:
Packit d7e8d0
                self.signers_add(key)
Packit d7e8d0
        except:
Packit d7e8d0
            self.signers = old
Packit d7e8d0
            raise
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def pinentry_mode(self):
Packit d7e8d0
        """Pinentry mode"""
Packit d7e8d0
        return self.get_pinentry_mode()
Packit d7e8d0
    @pinentry_mode.setter
Packit d7e8d0
    def pinentry_mode(self, value):
Packit d7e8d0
        self.set_pinentry_mode(value)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def protocol(self):
Packit d7e8d0
        """Protocol to use"""
Packit d7e8d0
        return self.get_protocol()
Packit d7e8d0
    @protocol.setter
Packit d7e8d0
    def protocol(self, value):
Packit d7e8d0
        errorcheck(gpgme.gpgme_engine_check_version(value))
Packit d7e8d0
        self.set_protocol(value)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def home_dir(self):
Packit d7e8d0
        """Engine's home directory"""
Packit d7e8d0
        return self.engine_info.home_dir
Packit d7e8d0
    @home_dir.setter
Packit d7e8d0
    def home_dir(self, value):
Packit d7e8d0
        self.set_engine_info(self.protocol, home_dir=value)
Packit d7e8d0
Packit d7e8d0
    _ctype = 'gpgme_ctx_t'
Packit d7e8d0
    _cprefix = 'gpgme_'
Packit d7e8d0
Packit d7e8d0
    def _errorcheck(self, name):
Packit d7e8d0
        """This function should list all functions returning gpgme_error_t"""
Packit d7e8d0
        # The list of functions is created using:
Packit d7e8d0
        #
Packit d7e8d0
        # $ grep '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \
Packit d7e8d0
        #   | grep -v _op_ | awk "/\(gpgme_ctx/ { printf (\"'%s',\\n\", \$2) } "
Packit d7e8d0
        return ((name.startswith('gpgme_op_')
Packit d7e8d0
                 and not name.endswith('_result'))
Packit d7e8d0
                or name in {
Packit d7e8d0
                    'gpgme_new',
Packit d7e8d0
                    'gpgme_set_ctx_flag',
Packit d7e8d0
                    'gpgme_set_protocol',
Packit d7e8d0
                    'gpgme_set_sub_protocol',
Packit d7e8d0
                    'gpgme_set_keylist_mode',
Packit d7e8d0
                    'gpgme_set_pinentry_mode',
Packit d7e8d0
                    'gpgme_set_locale',
Packit d7e8d0
                    'gpgme_ctx_set_engine_info',
Packit d7e8d0
                    'gpgme_signers_add',
Packit d7e8d0
                    'gpgme_sig_notation_add',
Packit d7e8d0
                    'gpgme_set_sender',
Packit d7e8d0
                    'gpgme_cancel',
Packit d7e8d0
                    'gpgme_cancel_async',
Packit d7e8d0
                    'gpgme_get_key',
Packit d7e8d0
                })
Packit d7e8d0
Packit d7e8d0
    _boolean_properties = {'armor', 'textmode', 'offline'}
Packit d7e8d0
Packit d7e8d0
    def __del__(self):
Packit d7e8d0
        if not gpgme:
Packit d7e8d0
            # At interpreter shutdown, gpgme is set to NONE.
Packit d7e8d0
            return
Packit d7e8d0
Packit d7e8d0
        self._free_passcb()
Packit d7e8d0
        self._free_progresscb()
Packit d7e8d0
        self._free_statuscb()
Packit d7e8d0
        if self.own and self.wrapped and gpgme.gpgme_release:
Packit d7e8d0
            gpgme.gpgme_release(self.wrapped)
Packit d7e8d0
            self.wrapped = None
Packit d7e8d0
Packit d7e8d0
    # Implement the context manager protocol.
Packit d7e8d0
    def __enter__(self):
Packit d7e8d0
        return self
Packit d7e8d0
    def __exit__(self, type, value, tb):
Packit d7e8d0
        self.__del__()
Packit d7e8d0
Packit d7e8d0
    def op_keylist_all(self, *args, **kwargs):
Packit d7e8d0
        self.op_keylist_start(*args, **kwargs)
Packit d7e8d0
        key = self.op_keylist_next()
Packit d7e8d0
        while key:
Packit d7e8d0
            yield key
Packit d7e8d0
            key = self.op_keylist_next()
Packit d7e8d0
        self.op_keylist_end()
Packit d7e8d0
Packit d7e8d0
    def op_keylist_next(self):
Packit d7e8d0
        """Returns the next key in the list created
Packit d7e8d0
        by a call to op_keylist_start().  The object returned
Packit d7e8d0
        is of type Key."""
Packit d7e8d0
        ptr = gpgme.new_gpgme_key_t_p()
Packit d7e8d0
        try:
Packit d7e8d0
            errorcheck(gpgme.gpgme_op_keylist_next(self.wrapped, ptr))
Packit d7e8d0
            key = gpgme.gpgme_key_t_p_value(ptr)
Packit d7e8d0
        except errors.GPGMEError as excp:
Packit d7e8d0
            key = None
Packit d7e8d0
            if excp.getcode() != errors.EOF:
Packit d7e8d0
                raise excp
Packit d7e8d0
        gpgme.delete_gpgme_key_t_p(ptr)
Packit d7e8d0
        if key:
Packit d7e8d0
            key.__del__ = lambda self: gpgme.gpgme_key_unref(self)
Packit d7e8d0
            return key
Packit d7e8d0
Packit d7e8d0
    def get_key(self, fpr, secret=False):
Packit d7e8d0
        """Get a key given a fingerprint
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        secret		-- to request a secret key
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
                        -- the matching key
Packit d7e8d0
Packit d7e8d0
        Raises:
Packit d7e8d0
        KeyError	-- if the key was not found
Packit d7e8d0
        GPGMEError	-- as signaled by the underlying library
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        ptr = gpgme.new_gpgme_key_t_p()
Packit d7e8d0
Packit d7e8d0
        try:
Packit d7e8d0
            errorcheck(gpgme.gpgme_get_key(self.wrapped, fpr, ptr, secret))
Packit d7e8d0
        except errors.GPGMEError as e:
Packit d7e8d0
            if e.getcode() == errors.EOF:
Packit d7e8d0
                raise errors.KeyNotFound(fpr)
Packit d7e8d0
            raise e
Packit d7e8d0
Packit d7e8d0
        key = gpgme.gpgme_key_t_p_value(ptr)
Packit d7e8d0
        gpgme.delete_gpgme_key_t_p(ptr)
Packit d7e8d0
        assert key
Packit d7e8d0
        key.__del__ = lambda self: gpgme.gpgme_key_unref(self)
Packit d7e8d0
        return key
Packit d7e8d0
Packit d7e8d0
    def op_trustlist_all(self, *args, **kwargs):
Packit d7e8d0
        self.op_trustlist_start(*args, **kwargs)
Packit d7e8d0
        trust = self.op_trustlist_next()
Packit d7e8d0
        while trust:
Packit d7e8d0
            yield trust
Packit d7e8d0
            trust = self.op_trustlist_next()
Packit d7e8d0
        self.op_trustlist_end()
Packit d7e8d0
Packit d7e8d0
    def op_trustlist_next(self):
Packit d7e8d0
        """Returns the next trust item in the list created
Packit d7e8d0
        by a call to op_trustlist_start().  The object returned
Packit d7e8d0
        is of type TrustItem."""
Packit d7e8d0
        ptr = gpgme.new_gpgme_trust_item_t_p()
Packit d7e8d0
        try:
Packit d7e8d0
            errorcheck(gpgme.gpgme_op_trustlist_next(self.wrapped, ptr))
Packit d7e8d0
            trust = gpgme.gpgme_trust_item_t_p_value(ptr)
Packit d7e8d0
        except errors.GPGMEError as excp:
Packit d7e8d0
            trust = None
Packit d7e8d0
            if excp.getcode() != errors.EOF:
Packit d7e8d0
                raise
Packit d7e8d0
        gpgme.delete_gpgme_trust_item_t_p(ptr)
Packit d7e8d0
        return trust
Packit d7e8d0
Packit d7e8d0
    def set_passphrase_cb(self, func, hook=None):
Packit d7e8d0
        """Sets the passphrase callback to the function specified by func.
Packit d7e8d0
Packit d7e8d0
        When the system needs a passphrase, it will call func with three args:
Packit d7e8d0
        hint, a string describing the key it needs the passphrase for;
Packit d7e8d0
        desc, a string describing the passphrase it needs;
Packit d7e8d0
        prev_bad, a boolean equal True if this is a call made after
Packit d7e8d0
        unsuccessful previous attempt.
Packit d7e8d0
Packit d7e8d0
        If hook has a value other than None it will be passed into the func
Packit d7e8d0
        as a forth argument.
Packit d7e8d0
Packit d7e8d0
        Please see the GPGME manual for more information.
Packit d7e8d0
        """
Packit d7e8d0
        if func == None:
Packit d7e8d0
            hookdata = None
Packit d7e8d0
        else:
Packit d7e8d0
            if hook == None:
Packit d7e8d0
                hookdata = (weakref.ref(self), func)
Packit d7e8d0
            else:
Packit d7e8d0
                hookdata = (weakref.ref(self), func, hook)
Packit d7e8d0
        gpgme.gpg_set_passphrase_cb(self, hookdata)
Packit d7e8d0
Packit d7e8d0
    def _free_passcb(self):
Packit d7e8d0
        if gpgme.gpg_set_passphrase_cb:
Packit d7e8d0
            self.set_passphrase_cb(None)
Packit d7e8d0
Packit d7e8d0
    def set_progress_cb(self, func, hook=None):
Packit d7e8d0
        """Sets the progress meter callback to the function specified by FUNC.
Packit d7e8d0
        If FUNC is None, the callback will be cleared.
Packit d7e8d0
Packit d7e8d0
        This function will be called to provide an interactive update
Packit d7e8d0
        of the system's progress.  The function will be called with
Packit d7e8d0
        three arguments, type, total, and current.  If HOOK is not
Packit d7e8d0
        None, it will be supplied as fourth argument.
Packit d7e8d0
Packit d7e8d0
        Please see the GPGME manual for more information.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if func == None:
Packit d7e8d0
            hookdata = None
Packit d7e8d0
        else:
Packit d7e8d0
            if hook == None:
Packit d7e8d0
                hookdata = (weakref.ref(self), func)
Packit d7e8d0
            else:
Packit d7e8d0
                hookdata = (weakref.ref(self), func, hook)
Packit d7e8d0
        gpgme.gpg_set_progress_cb(self, hookdata)
Packit d7e8d0
Packit d7e8d0
    def _free_progresscb(self):
Packit d7e8d0
        if gpgme.gpg_set_progress_cb:
Packit d7e8d0
            self.set_progress_cb(None)
Packit d7e8d0
Packit d7e8d0
    def set_status_cb(self, func, hook=None):
Packit d7e8d0
        """Sets the status callback to the function specified by FUNC.  If
Packit d7e8d0
        FUNC is None, the callback will be cleared.
Packit d7e8d0
Packit d7e8d0
        The function will be called with two arguments, keyword and
Packit d7e8d0
        args.  If HOOK is not None, it will be supplied as third
Packit d7e8d0
        argument.
Packit d7e8d0
Packit d7e8d0
        Please see the GPGME manual for more information.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        if func == None:
Packit d7e8d0
            hookdata = None
Packit d7e8d0
        else:
Packit d7e8d0
            if hook == None:
Packit d7e8d0
                hookdata = (weakref.ref(self), func)
Packit d7e8d0
            else:
Packit d7e8d0
                hookdata = (weakref.ref(self), func, hook)
Packit d7e8d0
        gpgme.gpg_set_status_cb(self, hookdata)
Packit d7e8d0
Packit d7e8d0
    def _free_statuscb(self):
Packit d7e8d0
        if gpgme.gpg_set_status_cb:
Packit d7e8d0
            self.set_status_cb(None)
Packit d7e8d0
Packit d7e8d0
    @property
Packit d7e8d0
    def engine_info(self):
Packit d7e8d0
        """Configuration of the engine currently in use"""
Packit d7e8d0
        p = self.protocol
Packit d7e8d0
        infos = [i for i in self.get_engine_info() if i.protocol == p]
Packit d7e8d0
        assert len(infos) == 1
Packit d7e8d0
        return infos[0]
Packit d7e8d0
Packit d7e8d0
    def get_engine_info(self):
Packit d7e8d0
        """Get engine configuration
Packit d7e8d0
Packit d7e8d0
        Returns information about all configured and installed
Packit d7e8d0
        engines.
Packit d7e8d0
Packit d7e8d0
        Returns:
Packit d7e8d0
        infos		-- a list of engine infos
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        return gpgme.gpgme_ctx_get_engine_info(self.wrapped)
Packit d7e8d0
Packit d7e8d0
    def set_engine_info(self, proto, file_name=None, home_dir=None):
Packit d7e8d0
        """Change engine configuration
Packit d7e8d0
Packit d7e8d0
        Changes the configuration of the crypto engine implementing
Packit d7e8d0
        the protocol 'proto' for the context.
Packit d7e8d0
Packit d7e8d0
        Keyword arguments:
Packit d7e8d0
        file_name	-- engine program file name (unchanged if None)
Packit d7e8d0
        home_dir	-- configuration directory (unchanged if None)
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        self.ctx_set_engine_info(proto, file_name, home_dir)
Packit d7e8d0
Packit d7e8d0
    def wait(self, hang):
Packit d7e8d0
        """Wait for asynchronous call to finish. Wait forever if hang is True.
Packit d7e8d0
        Raises an exception on errors.
Packit d7e8d0
Packit d7e8d0
        Please read the GPGME manual for more information.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        ptr = gpgme.new_gpgme_error_t_p()
Packit d7e8d0
        gpgme.gpgme_wait(self.wrapped, ptr, hang)
Packit d7e8d0
        status = gpgme.gpgme_error_t_p_value(ptr)
Packit d7e8d0
        gpgme.delete_gpgme_error_t_p(ptr)
Packit d7e8d0
        errorcheck(status)
Packit d7e8d0
Packit d7e8d0
    def op_edit(self, key, func, fnc_value, out):
Packit d7e8d0
        """Start key editing using supplied callback function
Packit d7e8d0
Packit d7e8d0
        Note: This interface is deprecated and will be removed with
Packit d7e8d0
        GPGME 1.8.  Please use .interact instead.  Furthermore, we
Packit d7e8d0
        implement this using gpgme_op_interact, so callbacks will get
Packit d7e8d0
        called with string keywords instead of numeric status
Packit d7e8d0
        messages.  Code that is using constants.STATUS_X or
Packit d7e8d0
        constants.status.X will continue to work, whereas code using
Packit d7e8d0
        magic numbers will break as a result.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        warnings.warn("Call to deprecated method op_edit.",
Packit d7e8d0
                      category=DeprecationWarning)
Packit d7e8d0
        return self.interact(key, func, sink=out, fnc_value=fnc_value)
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
class Data(GpgmeWrapper):
Packit d7e8d0
    """Data buffer
Packit d7e8d0
Packit d7e8d0
    A lot of data has to be exchanged between the user and the crypto
Packit d7e8d0
    engine, like plaintext messages, ciphertext, signatures and
Packit d7e8d0
    information about the keys.  The technical details about
Packit d7e8d0
    exchanging the data information are completely abstracted by
Packit d7e8d0
    GPGME.  The user provides and receives the data via `gpgme_data_t'
Packit d7e8d0
    objects, regardless of the communication protocol between GPGME
Packit d7e8d0
    and the crypto engine in use.
Packit d7e8d0
Packit d7e8d0
    This Data class is the implementation of the GpgmeData objects.
Packit d7e8d0
Packit d7e8d0
    Please see the information about __init__ for instantiation.
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
Packit d7e8d0
    _ctype = 'gpgme_data_t'
Packit d7e8d0
    _cprefix = 'gpgme_data_'
Packit d7e8d0
Packit d7e8d0
    def _errorcheck(self, name):
Packit d7e8d0
        """This function should list all functions returning gpgme_error_t"""
Packit d7e8d0
        # This list is compiled using
Packit d7e8d0
        #
Packit d7e8d0
        # $ grep -v '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \
Packit d7e8d0
        #   | awk "/\(gpgme_data_t/ { printf (\"'%s',\\n\", \$2) } " | sed "s/'\\*/'/"
Packit d7e8d0
        return name not in {
Packit d7e8d0
            'gpgme_data_read',
Packit d7e8d0
            'gpgme_data_write',
Packit d7e8d0
            'gpgme_data_seek',
Packit d7e8d0
            'gpgme_data_release',
Packit d7e8d0
            'gpgme_data_release_and_get_mem',
Packit d7e8d0
            'gpgme_data_get_encoding',
Packit d7e8d0
            'gpgme_data_get_file_name',
Packit d7e8d0
            'gpgme_data_identify',
Packit d7e8d0
        }
Packit d7e8d0
Packit d7e8d0
    def __init__(self, string=None, file=None, offset=None,
Packit d7e8d0
                 length=None, cbs=None, copy=True):
Packit d7e8d0
        """Initialize a new gpgme_data_t object.
Packit d7e8d0
Packit d7e8d0
        If no args are specified, make it an empty object.
Packit d7e8d0
Packit d7e8d0
        If string alone is specified, initialize it with the data
Packit d7e8d0
        contained there.
Packit d7e8d0
Packit d7e8d0
        If file, offset, and length are all specified, file must
Packit d7e8d0
        be either a filename or a file-like object, and the object
Packit d7e8d0
        will be initialized by reading the specified chunk from the file.
Packit d7e8d0
Packit d7e8d0
        If cbs is specified, it MUST be a tuple of the form:
Packit d7e8d0
Packit d7e8d0
        (read_cb, write_cb, seek_cb, release_cb[, hook])
Packit d7e8d0
Packit d7e8d0
        where the first four items are functions implementing reading,
Packit d7e8d0
        writing, seeking the data, and releasing any resources once
Packit d7e8d0
        the data object is deallocated.  The functions must match the
Packit d7e8d0
        following prototypes:
Packit d7e8d0
Packit d7e8d0
            def read(amount, hook=None):
Packit d7e8d0
                return 
Packit d7e8d0
Packit d7e8d0
            def write(data, hook=None):
Packit d7e8d0
                return <the number of bytes written>
Packit d7e8d0
Packit d7e8d0
            def seek(offset, whence, hook=None):
Packit d7e8d0
                return <the new file position>
Packit d7e8d0
Packit d7e8d0
            def release(hook=None):
Packit d7e8d0
                <return value and exceptions are ignored>
Packit d7e8d0
Packit d7e8d0
        The functions may be bound methods.  In that case, you can
Packit d7e8d0
        simply use the 'self' reference instead of using a hook.
Packit d7e8d0
Packit d7e8d0
        If file is specified without any other arguments, then
Packit d7e8d0
        it must be a filename, and the object will be initialized from
Packit d7e8d0
        that file.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        super(Data, self).__init__(None)
Packit d7e8d0
        self.data_cbs = None
Packit d7e8d0
Packit d7e8d0
        if cbs != None:
Packit d7e8d0
            self.new_from_cbs(*cbs)
Packit d7e8d0
        elif string != None:
Packit d7e8d0
            self.new_from_mem(string, copy)
Packit d7e8d0
        elif file != None and offset != None and length != None:
Packit d7e8d0
            self.new_from_filepart(file, offset, length)
Packit d7e8d0
        elif file != None:
Packit d7e8d0
            if util.is_a_string(file):
Packit d7e8d0
                self.new_from_file(file, copy)
Packit d7e8d0
            else:
Packit d7e8d0
                self.new_from_fd(file)
Packit d7e8d0
        else:
Packit d7e8d0
            self.new()
Packit d7e8d0
Packit d7e8d0
    def __del__(self):
Packit d7e8d0
        if not gpgme:
Packit d7e8d0
            # At interpreter shutdown, gpgme is set to NONE.
Packit d7e8d0
            return
Packit d7e8d0
Packit d7e8d0
        if self.wrapped != None and gpgme.gpgme_data_release:
Packit d7e8d0
            gpgme.gpgme_data_release(self.wrapped)
Packit d7e8d0
            if self._callback_excinfo:
Packit d7e8d0
                gpgme.gpg_raise_callback_exception(self)
Packit d7e8d0
            self.wrapped = None
Packit d7e8d0
        self._free_datacbs()
Packit d7e8d0
Packit d7e8d0
    # Implement the context manager protocol.
Packit d7e8d0
    def __enter__(self):
Packit d7e8d0
        return self
Packit d7e8d0
    def __exit__(self, type, value, tb):
Packit d7e8d0
        self.__del__()
Packit d7e8d0
Packit d7e8d0
    def _free_datacbs(self):
Packit d7e8d0
        self._data_cbs = None
Packit d7e8d0
Packit d7e8d0
    def new(self):
Packit d7e8d0
        tmp = gpgme.new_gpgme_data_t_p()
Packit d7e8d0
        errorcheck(gpgme.gpgme_data_new(tmp))
Packit d7e8d0
        self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
Packit d7e8d0
        gpgme.delete_gpgme_data_t_p(tmp)
Packit d7e8d0
Packit d7e8d0
    def new_from_mem(self, string, copy=True):
Packit d7e8d0
        tmp = gpgme.new_gpgme_data_t_p()
Packit d7e8d0
        errorcheck(gpgme.gpgme_data_new_from_mem(tmp,string,len(string),copy))
Packit d7e8d0
        self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
Packit d7e8d0
        gpgme.delete_gpgme_data_t_p(tmp)
Packit d7e8d0
Packit d7e8d0
    def new_from_file(self, filename, copy=True):
Packit d7e8d0
        tmp = gpgme.new_gpgme_data_t_p()
Packit d7e8d0
        try:
Packit d7e8d0
            errorcheck(gpgme.gpgme_data_new_from_file(tmp, filename, copy))
Packit d7e8d0
        except errors.GPGMEError as e:
Packit d7e8d0
            if e.getcode() == errors.INV_VALUE and not copy:
Packit d7e8d0
                raise ValueError("delayed reads are not yet supported")
Packit d7e8d0
            else:
Packit d7e8d0
                raise e
Packit d7e8d0
        self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
Packit d7e8d0
        gpgme.delete_gpgme_data_t_p(tmp)
Packit d7e8d0
Packit d7e8d0
    def new_from_cbs(self, read_cb, write_cb, seek_cb, release_cb, hook=None):
Packit d7e8d0
        tmp = gpgme.new_gpgme_data_t_p()
Packit d7e8d0
        if hook != None:
Packit d7e8d0
            hookdata = (weakref.ref(self),
Packit d7e8d0
                        read_cb, write_cb, seek_cb, release_cb, hook)
Packit d7e8d0
        else:
Packit d7e8d0
            hookdata = (weakref.ref(self),
Packit d7e8d0
                        read_cb, write_cb, seek_cb, release_cb)
Packit d7e8d0
        gpgme.gpg_data_new_from_cbs(self, hookdata, tmp)
Packit d7e8d0
        self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
Packit d7e8d0
        gpgme.delete_gpgme_data_t_p(tmp)
Packit d7e8d0
Packit d7e8d0
    def new_from_filepart(self, file, offset, length):
Packit d7e8d0
        """This wraps the GPGME gpgme_data_new_from_filepart() function.
Packit d7e8d0
        The argument "file" may be:
Packit d7e8d0
Packit d7e8d0
        * a string specifying a file name, or
Packit d7e8d0
        * a file-like object supporting the fileno() and the mode attribute.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
Packit d7e8d0
        tmp = gpgme.new_gpgme_data_t_p()
Packit d7e8d0
        filename = None
Packit d7e8d0
        fp = None
Packit d7e8d0
Packit d7e8d0
        if util.is_a_string(file):
Packit d7e8d0
            filename = file
Packit d7e8d0
        else:
Packit d7e8d0
            fp = gpgme.fdopen(file.fileno(), file.mode)
Packit d7e8d0
            if fp == None:
Packit d7e8d0
                raise ValueError("Failed to open file from %s arg %s" % \
Packit d7e8d0
                      (str(type(file)), str(file)))
Packit d7e8d0
Packit d7e8d0
        errorcheck(gpgme.gpgme_data_new_from_filepart(tmp, filename, fp,
Packit d7e8d0
                                                      offset, length))
Packit d7e8d0
        self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
Packit d7e8d0
        gpgme.delete_gpgme_data_t_p(tmp)
Packit d7e8d0
Packit d7e8d0
    def new_from_fd(self, file):
Packit d7e8d0
        """This wraps the GPGME gpgme_data_new_from_fd() function.  The
Packit d7e8d0
        argument "file" must be a file-like object, supporting the
Packit d7e8d0
        fileno() method.
Packit d7e8d0
Packit d7e8d0
        """
Packit d7e8d0
        tmp = gpgme.new_gpgme_data_t_p()
Packit d7e8d0
        errorcheck(gpgme.gpgme_data_new_from_fd(tmp, file.fileno()))
Packit d7e8d0
        self.wrapped = gpgme.gpgme_data_t_p_value(tmp)
Packit d7e8d0
        gpgme.delete_gpgme_data_t_p(tmp)
Packit d7e8d0
Packit d7e8d0
    def new_from_stream(self, file):
Packit d7e8d0
        """This wrap around gpgme_data_new_from_stream is an alias for
Packit d7e8d0
        new_from_fd() method since in python there's not difference
Packit d7e8d0
        between file stream and file descriptor"""
Packit d7e8d0
        self.new_from_fd(file)
Packit d7e8d0
Packit d7e8d0
    def write(self, buffer):
Packit d7e8d0
        """Write buffer given as string or bytes.
Packit d7e8d0
Packit d7e8d0
        If a string is given, it is implicitly encoded using UTF-8."""
Packit d7e8d0
        written = gpgme.gpgme_data_write(self.wrapped, buffer)
Packit d7e8d0
        if written < 0:
Packit d7e8d0
            if self._callback_excinfo:
Packit d7e8d0
                gpgme.gpg_raise_callback_exception(self)
Packit d7e8d0
            else:
Packit d7e8d0
                raise GPGMEError.fromSyserror()
Packit d7e8d0
        return written
Packit d7e8d0
Packit d7e8d0
    def read(self, size = -1):
Packit d7e8d0
        """Read at most size bytes, returned as bytes.
Packit d7e8d0
Packit d7e8d0
        If the size argument is negative or omitted, read until EOF is reached.
Packit d7e8d0
Packit d7e8d0
        Returns the data read, or the empty string if there was no data
Packit d7e8d0
        to read before EOF was reached."""
Packit d7e8d0
Packit d7e8d0
        if size == 0:
Packit d7e8d0
            return ''
Packit d7e8d0
Packit d7e8d0
        if size > 0:
Packit d7e8d0
            try:
Packit d7e8d0
                result = gpgme.gpgme_data_read(self.wrapped, size)
Packit d7e8d0
            except:
Packit d7e8d0
                if self._callback_excinfo:
Packit d7e8d0
                    gpgme.gpg_raise_callback_exception(self)
Packit d7e8d0
                else:
Packit d7e8d0
                    raise
Packit d7e8d0
            return result
Packit d7e8d0
        else:
Packit d7e8d0
            chunks = []
Packit d7e8d0
            while True:
Packit d7e8d0
                try:
Packit d7e8d0
                    result = gpgme.gpgme_data_read(self.wrapped, 4096)
Packit d7e8d0
                except:
Packit d7e8d0
                    if self._callback_excinfo:
Packit d7e8d0
                        gpgme.gpg_raise_callback_exception(self)
Packit d7e8d0
                    else:
Packit d7e8d0
                        raise
Packit d7e8d0
                if len(result) == 0:
Packit d7e8d0
                    break
Packit d7e8d0
                chunks.append(result)
Packit d7e8d0
            return b''.join(chunks)
Packit d7e8d0
Packit d7e8d0
def pubkey_algo_string(subkey):
Packit d7e8d0
    """Return short algorithm string
Packit d7e8d0
Packit d7e8d0
    Return a public key algorithm string (e.g. "rsa2048") for a given
Packit d7e8d0
    SUBKEY.
Packit d7e8d0
Packit d7e8d0
    Returns:
Packit d7e8d0
    algo      - a string
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
    return gpgme.gpgme_pubkey_algo_string(subkey)
Packit d7e8d0
Packit d7e8d0
def pubkey_algo_name(algo):
Packit d7e8d0
    """Return name of public key algorithm
Packit d7e8d0
Packit d7e8d0
    Return the name of the public key algorithm for a given numeric
Packit d7e8d0
    algorithm id ALGO (cf. RFC4880).
Packit d7e8d0
Packit d7e8d0
    Returns:
Packit d7e8d0
    algo      - a string
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
    return gpgme.gpgme_pubkey_algo_name(algo)
Packit d7e8d0
Packit d7e8d0
def hash_algo_name(algo):
Packit d7e8d0
    """Return name of hash algorithm
Packit d7e8d0
Packit d7e8d0
    Return the name of the hash algorithm for a given numeric
Packit d7e8d0
    algorithm id ALGO (cf. RFC4880).
Packit d7e8d0
Packit d7e8d0
    Returns:
Packit d7e8d0
    algo      - a string
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
    return gpgme.gpgme_hash_algo_name(algo)
Packit d7e8d0
Packit d7e8d0
def get_protocol_name(proto):
Packit d7e8d0
    """Get protocol description
Packit d7e8d0
Packit d7e8d0
    Get the string describing protocol PROTO.
Packit d7e8d0
Packit d7e8d0
    Returns:
Packit d7e8d0
    proto     - a string
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
    return gpgme.gpgme_get_protocol_name(proto)
Packit d7e8d0
Packit d7e8d0
def addrspec_from_uid(uid):
Packit d7e8d0
    """Return the address spec
Packit d7e8d0
Packit d7e8d0
    Return the addr-spec (cf. RFC2822 section 4.3) from a user id UID.
Packit d7e8d0
Packit d7e8d0
    Returns:
Packit d7e8d0
    addr_spec - a string
Packit d7e8d0
Packit d7e8d0
    """
Packit d7e8d0
    return gpgme.gpgme_addrspec_from_uid(uid)
Packit d7e8d0
Packit d7e8d0
def check_version(version=None):
Packit d7e8d0
    return gpgme.gpgme_check_version(version)
Packit d7e8d0
Packit d7e8d0
# check_version also makes sure that several subsystems are properly
Packit d7e8d0
# initialized, and it must be run at least once before invoking any
Packit d7e8d0
# other function.  We do it here so that the user does not have to do
Packit d7e8d0
# it unless she really wants to check for a certain version.
Packit d7e8d0
check_version()
Packit d7e8d0
Packit d7e8d0
def engine_check_version (proto):
Packit d7e8d0
    try:
Packit d7e8d0
        errorcheck(gpgme.gpgme_engine_check_version(proto))
Packit d7e8d0
        return True
Packit d7e8d0
    except errors.GPGMEError:
Packit d7e8d0
        return False
Packit d7e8d0
Packit d7e8d0
def get_engine_info():
Packit d7e8d0
    ptr = gpgme.new_gpgme_engine_info_t_p()
Packit d7e8d0
    try:
Packit d7e8d0
        errorcheck(gpgme.gpgme_get_engine_info(ptr))
Packit d7e8d0
        info = gpgme.gpgme_engine_info_t_p_value(ptr)
Packit d7e8d0
    except errors.GPGMEError:
Packit d7e8d0
        info = None
Packit d7e8d0
    gpgme.delete_gpgme_engine_info_t_p(ptr)
Packit d7e8d0
    return info
Packit d7e8d0
Packit d7e8d0
def set_engine_info(proto, file_name, home_dir=None):
Packit d7e8d0
    """Changes the default configuration of the crypto engine implementing
Packit d7e8d0
    the protocol 'proto'. 'file_name' is the file name of
Packit d7e8d0
    the executable program implementing this protocol. 'home_dir' is the
Packit d7e8d0
    directory name of the configuration directory (engine's default is
Packit d7e8d0
    used if omitted)."""
Packit d7e8d0
    errorcheck(gpgme.gpgme_set_engine_info(proto, file_name, home_dir))
Packit d7e8d0
Packit d7e8d0
def set_locale(category, value):
Packit d7e8d0
    """Sets the default locale used by contexts"""
Packit d7e8d0
    errorcheck(gpgme.gpgme_set_locale(None, category, value))
Packit d7e8d0
Packit d7e8d0
def wait(hang):
Packit d7e8d0
    """Wait for asynchronous call on any Context  to finish.
Packit d7e8d0
    Wait forever if hang is True.
Packit d7e8d0
Packit d7e8d0
    For finished anynch calls it returns a tuple (status, context):
Packit d7e8d0
        status  - status return by asnynchronous call.
Packit d7e8d0
        context - context which caused this call to return.
Packit d7e8d0
Packit d7e8d0
    Please read the GPGME manual of more information."""
Packit d7e8d0
    ptr = gpgme.new_gpgme_error_t_p()
Packit d7e8d0
    context = gpgme.gpgme_wait(None, ptr, hang)
Packit d7e8d0
    status = gpgme.gpgme_error_t_p_value(ptr)
Packit d7e8d0
    gpgme.delete_gpgme_error_t_p(ptr)
Packit d7e8d0
    if context == None:
Packit d7e8d0
        errorcheck(status)
Packit d7e8d0
    else:
Packit d7e8d0
        context = Context(context)
Packit d7e8d0
    return (status, context)